blob: 88202cbf23a26416147a516e6904ab70c5d09a85 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sw.hxx"
#ifdef SW_DLLIMPLEMENTATION
#undef SW_DLLIMPLEMENTATION
#endif
#include <hintids.hxx>
#include <tools/pstm.hxx>
#define _SVSTDARR_LONGSSORT
#define _SVSTDARR_LONGS
#include <svl/svstdarr.hxx>
#include <editeng/paperinf.hxx>
#ifndef _SVX_TSTPITEM_HXX //autogen
#include <editeng/tstpitem.hxx>
#endif
#include <editeng/lrspitem.hxx>
#include <editeng/brshitem.hxx>
#ifndef _MSGBOX_HXX //autogen
#include <vcl/msgbox.hxx>
#endif
#ifndef _MENU_HXX //autogen
#include <vcl/menu.hxx>
#endif
#ifndef _CMDID_H
#include <cmdid.h>
#endif
#include <frmatr.hxx>
#include <swtypes.hxx>
#include <wrtsh.hxx>
#ifndef _VIEW_HXX
#include <view.hxx>
#endif
#ifndef _BASESH_HXX
#include <basesh.hxx>
#endif
#include <drpcps.hxx>
#include <envfmt.hxx>
#include <fmtcol.hxx>
#ifndef _PARDLG_HXX
#include "swuipardlg.hxx"
#endif
#include <pattern.hxx>
#include <poolfmt.hxx>
#include <uiborder.hxx>
#include <uitool.hxx>
#ifndef _ENVFMT_HRC
#include <envfmt.hrc>
#endif
#include "swabstdlg.hxx"
#include "chrdlg.hrc"
namespace swui
{
SwAbstractDialogFactory * GetFactory();
}
static PopupMenu *pMenu;
static long lUserW = 5669; // 10 cm
static long lUserH = 5669; // 10 cm
// --------------------------------------------------------------------------
SwEnvFmtPage::SwEnvFmtPage(Window* pParent, const SfxItemSet& rSet) :
SfxTabPage(pParent, SW_RES(TP_ENV_FMT), rSet),
aAddrFL (this, SW_RES( FL_ADDRESSEE )),
aAddrPosInfo (this, SW_RES( TXT_ADDR_POS )),
aAddrLeftText (this, SW_RES( TXT_ADDR_LEFT )),
aAddrLeftField (this, SW_RES( FLD_ADDR_LEFT )),
aAddrTopText (this, SW_RES( TXT_ADDR_TOP )),
aAddrTopField (this, SW_RES( FLD_ADDR_TOP )),
aAddrFormatInfo (this, SW_RES( TXT_ADDR_FORMAT )),
aAddrEditButton (this, SW_RES( BTN_ADDR_EDIT )),
aSendFL (this, SW_RES( FL_SENDER )),
aSendPosInfo (this, SW_RES( TXT_SEND_POS )),
aSendLeftText (this, SW_RES( TXT_SEND_LEFT )),
aSendLeftField (this, SW_RES( FLD_SEND_LEFT )),
aSendTopText (this, SW_RES( TXT_SEND_TOP )),
aSendTopField (this, SW_RES( FLD_SEND_TOP )),
aSendFormatInfo (this, SW_RES( TXT_SEND_FORMAT )),
aSendEditButton (this, SW_RES( BTN_SEND_EDIT )),
aSizeFL (this, SW_RES( FL_SIZE )),
aSizeFormatText (this, SW_RES( TXT_SIZE_FORMAT )),
aSizeFormatBox (this, SW_RES( BOX_SIZE_FORMAT )),
aSizeWidthText (this, SW_RES( TXT_SIZE_WIDTH )),
aSizeWidthField (this, SW_RES( FLD_SIZE_WIDTH )),
aSizeHeightText (this, SW_RES( TXT_SIZE_HEIGHT )),
aSizeHeightField (this, SW_RES( FLD_SIZE_HEIGHT )),
aPreview (this, SW_RES( WIN_PREVIEW ))
{
FreeResource();
SetExchangeSupport();
// Metriken
FieldUnit aMetric = ::GetDfltMetric(sal_False);
SetMetric(aAddrLeftField, aMetric);
SetMetric(aAddrTopField, aMetric);
SetMetric(aSendLeftField, aMetric);
SetMetric(aSendTopField, aMetric);
SetMetric(aSizeWidthField, aMetric);
SetMetric(aSizeHeightField, aMetric);
// Menues einhaengen
::pMenu = new PopupMenu(SW_RES(MNU_EDIT));
aAddrEditButton.SetPopupMenu(::pMenu);
aSendEditButton.SetPopupMenu(::pMenu);
// Handler installieren
Link aLk = LINK(this, SwEnvFmtPage, ModifyHdl);
aAddrLeftField .SetUpHdl( aLk );
aAddrTopField .SetUpHdl( aLk );
aSendLeftField .SetUpHdl( aLk );
aSendTopField .SetUpHdl( aLk );
aSizeWidthField .SetUpHdl( aLk );
aSizeHeightField.SetUpHdl( aLk );
aAddrLeftField .SetDownHdl( aLk );
aAddrTopField .SetDownHdl( aLk );
aSendLeftField .SetDownHdl( aLk );
aSendTopField .SetDownHdl( aLk );
aSizeWidthField .SetDownHdl( aLk );
aSizeHeightField.SetDownHdl( aLk );
aAddrLeftField .SetLoseFocusHdl( aLk );
aAddrTopField .SetLoseFocusHdl( aLk );
aSendLeftField .SetLoseFocusHdl( aLk );
aSendTopField .SetLoseFocusHdl( aLk );
aSizeWidthField .SetLoseFocusHdl( aLk );
aSizeHeightField.SetLoseFocusHdl( aLk );
aLk = LINK(this, SwEnvFmtPage, EditHdl );
aAddrEditButton.SetSelectHdl( aLk );
aSendEditButton.SetSelectHdl( aLk );
aPreview.SetBorderStyle( WINDOW_BORDER_MONO );
aSizeFormatBox .SetSelectHdl(LINK(this, SwEnvFmtPage, FormatHdl));
// aSizeFormatBox
for (sal_uInt16 i = PAPER_A3; i <= PAPER_KAI32BIG; i++)
{
if (i != PAPER_USER)
{
String aPaperName = SvxPaperInfo::GetName((Paper) i),
aEntryName;
sal_uInt16 nPos = 0;
sal_Bool bFound = sal_False;
while (nPos < aSizeFormatBox.GetEntryCount() && !bFound)
{
aEntryName = aSizeFormatBox.GetEntry(i);
if (aEntryName < aPaperName)
nPos++;
else
bFound = sal_True;
}
aSizeFormatBox.InsertEntry(aPaperName, nPos);
aIDs.Insert((sal_uInt16) i, nPos);
}
}
aSizeFormatBox.InsertEntry(SvxPaperInfo::GetName(PAPER_USER));
aIDs.Insert((sal_uInt16) PAPER_USER, aIDs.Count());
}
// --------------------------------------------------------------------------
__EXPORT SwEnvFmtPage::~SwEnvFmtPage()
{
aAddrEditButton.SetPopupMenu(0);
aSendEditButton.SetPopupMenu(0);
delete ::pMenu;
}
// --------------------------------------------------------------------------
IMPL_LINK_INLINE_START( SwEnvFmtPage, ModifyHdl, Edit *, pEdit )
{
long lWVal = static_cast< long >(GetFldVal(aSizeWidthField ));
long lHVal = static_cast< long >(GetFldVal(aSizeHeightField));
long lWidth = Max(lWVal, lHVal);
long lHeight = Min(lWVal, lHVal);
if (pEdit == &aSizeWidthField || pEdit == &aSizeHeightField)
{
Paper ePaper = SvxPaperInfo::GetSvxPaper(
Size(lHeight, lWidth), MAP_TWIP, sal_True);
for (sal_uInt16 i = 0; i < aIDs.Count(); i++)
if (aIDs[i] == (sal_uInt16)ePaper)
aSizeFormatBox.SelectEntryPos(i);
// Benutzergroesse merken
if (aIDs[aSizeFormatBox.GetSelectEntryPos()] == (sal_uInt16)PAPER_USER)
{
lUserW = lWidth ;
lUserH = lHeight;
}
aSizeFormatBox.GetSelectHdl().Call(&aSizeFormatBox);
}
else
{
FillItem(GetParent()->aEnvItem);
SetMinMax();
aPreview.Invalidate();
}
return 0;
}
IMPL_LINK_INLINE_END( SwEnvFmtPage, ModifyHdl, Edit *, pEdit )
// --------------------------------------------------------------------------
IMPL_LINK( SwEnvFmtPage, EditHdl, MenuButton *, pButton )
{
SwWrtShell* pSh = GetParent()->pSh;
ASSERT(pSh, "Shell fehlt");
// Collection-Ptr ermitteln
sal_Bool bSender = pButton != &aAddrEditButton;
SwTxtFmtColl* pColl = pSh->GetTxtCollFromPool( static_cast< sal_uInt16 >(
bSender ? RES_POOLCOLL_SENDADRESS : RES_POOLCOLL_JAKETADRESS));
ASSERT(pColl, "Text-Collection fehlt");
switch (pButton->GetCurItemId())
{
case MID_CHAR:
{
SfxItemSet *pCollSet = GetCollItemSet(pColl, bSender);
// Damit die Hintergrundfarbe nicht uebergebuegelt wird:
SfxAllItemSet aTmpSet(*pCollSet);
// Das CHRATR_BACKGROUND-Attribut wird fuer den Dialog in
// ein RES_BACKGROUND verwandelt und wieder zurueck ...
const SfxPoolItem *pTmpBrush;
if( SFX_ITEM_SET == aTmpSet.GetItemState( RES_CHRATR_BACKGROUND,
sal_True, &pTmpBrush ) )
{
SvxBrushItem aTmpBrush( *((SvxBrushItem*)pTmpBrush) );
aTmpBrush.SetWhich( RES_BACKGROUND );
aTmpSet.Put( aTmpBrush );
}
else
aTmpSet.ClearItem( RES_BACKGROUND );
SwAbstractDialogFactory* pFact = swui::GetFactory();
DBG_ASSERT(pFact, "SwAbstractDialogFactory fail!");
SfxAbstractTabDialog* pDlg = pFact->CreateSwCharDlg( GetParent(), pSh->GetView(), aTmpSet, DLG_CHAR ,&pColl->GetName() );
DBG_ASSERT(pDlg, "Dialogdiet fail!");
if (pDlg->Execute() == RET_OK)
{
SfxItemSet aOutputSet( *pDlg->GetOutputItemSet() );
if( SFX_ITEM_SET == aOutputSet.GetItemState( RES_BACKGROUND,
sal_False, &pTmpBrush ) )
{
SvxBrushItem aTmpBrush( *((SvxBrushItem*)pTmpBrush) );
aTmpBrush.SetWhich( RES_CHRATR_BACKGROUND );
pCollSet->Put( aTmpBrush );
}
aOutputSet.ClearItem( RES_BACKGROUND );
pCollSet->Put(aOutputSet);
}
delete pDlg;
}
break;
case MID_PARA:
{
SfxItemSet *pCollSet = GetCollItemSet(pColl, bSender);
// Damit die Tabulatoren nicht uebergebuegelt werden:
SfxAllItemSet aTmpSet(*pCollSet);
// Tabulatoren, DefaultTabs ins ItemSet Stecken
const SvxTabStopItem& rDefTabs = (const SvxTabStopItem&)
pSh->GetView().GetCurShell()->GetPool().GetDefaultItem(RES_PARATR_TABSTOP);
sal_uInt16 nDefDist = ::GetTabDist( rDefTabs );
SfxUInt16Item aDefDistItem( SID_ATTR_TABSTOP_DEFAULTS, nDefDist );
aTmpSet.Put( aDefDistItem );
// Aktueller Tab
SfxUInt16Item aTabPos( SID_ATTR_TABSTOP_POS, 0 );
aTmpSet.Put( aTabPos );
// linker Rand als Offset
const long nOff = ((SvxLRSpaceItem&)aTmpSet.Get( RES_LR_SPACE )).
GetTxtLeft();
SfxInt32Item aOff( SID_ATTR_TABSTOP_OFFSET, nOff );
aTmpSet.Put( aOff );
// BoxInfo setzen
::PrepareBoxInfo( aTmpSet, *pSh );
SwParaDlg *pDlg = new SwParaDlg(GetParent(), pSh->GetView(), aTmpSet, DLG_ENVELOP, &pColl->GetName());
if ( pDlg->Execute() == RET_OK )
{
// Defaults evtl umsetzen
const SfxPoolItem* pItem = 0;
SfxItemSet* pOutputSet = (SfxItemSet*)pDlg->GetOutputItemSet();
sal_uInt16 nNewDist;
if( SFX_ITEM_SET == pOutputSet->GetItemState( SID_ATTR_TABSTOP_DEFAULTS,
sal_False, &pItem ) &&
nDefDist != (nNewDist = ((SfxUInt16Item*)pItem)->GetValue()) )
{
SvxTabStopItem aDefTabs( 0, 0, SVX_TAB_ADJUST_DEFAULT, RES_PARATR_TABSTOP );
MakeDefTabs( nNewDist, aDefTabs );
pSh->SetDefault( aDefTabs );
pOutputSet->ClearItem( SID_ATTR_TABSTOP_DEFAULTS );
}
if( pOutputSet->Count() )
{
pCollSet->Put(*pOutputSet);
}
}
delete pDlg;
}
break;
}
return 0;
}
/*------------------------------------------------------------------------
Beschreibung: Ein temporaeres Itemset, das bei Abbruch verworfen wird
------------------------------------------------------------------------*/
SfxItemSet *SwEnvFmtPage::GetCollItemSet(SwTxtFmtColl* pColl, sal_Bool bSender)
{
SfxItemSet *&pAddrSet = bSender ? GetParent()->pSenderSet : GetParent()->pAddresseeSet;
if (!pAddrSet)
{
// Range ermitteln (Ranges beider Itemsets mergen)
const sal_uInt16 *pRanges = pColl->GetAttrSet().GetRanges();
static sal_uInt16 __READONLY_DATA aRanges[] =
{
RES_PARATR_BEGIN, RES_PARATR_ADJUST,
RES_PARATR_TABSTOP, RES_PARATR_END-1,
RES_LR_SPACE, RES_UL_SPACE,
RES_BACKGROUND, RES_SHADOW,
SID_ATTR_TABSTOP_POS, SID_ATTR_TABSTOP_POS,
SID_ATTR_TABSTOP_DEFAULTS, SID_ATTR_TABSTOP_DEFAULTS,
SID_ATTR_TABSTOP_OFFSET, SID_ATTR_TABSTOP_OFFSET,
SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER,
0, 0
};
// BruteForce-Merge, weil MergeRange in SvTools buggy ist:
sal_uInt16 i = 0;
SvLongsSort aMergedRanges( 0, 10 );
while (pRanges[i])
{
for (sal_uInt16 nPos = pRanges[i]; nPos <= pRanges[i+1]; nPos++)
aMergedRanges.Insert(nPos);
i += 2;
}
i = 0;
while (aRanges[i])
{
for (sal_uInt16 nPos = aRanges[i]; nPos <= aRanges[i+1]; nPos++)
aMergedRanges.Insert(nPos);
i += 2;
}
// Ranges kompaktieren
SvLongs aCompactedRanges( 0, 10 );
aCompactedRanges.Insert(aMergedRanges[0], aCompactedRanges.Count());
for (i = 0; i < aMergedRanges.Count(); i++)
{
while (i + 1 < aMergedRanges.Count() &&
aMergedRanges[i+1] - aMergedRanges[i] == 1)
{
i++;
}
long nEnd = aMergedRanges[i];
aCompactedRanges.Insert(nEnd, aCompactedRanges.Count());
if (i + 1 < aMergedRanges.Count())
{
long nStart = aMergedRanges[i+1];
aCompactedRanges.Insert(nStart, aCompactedRanges.Count());
}
}
// Neue Ranges erzeugen
sal_uInt16 *pNewRanges = new sal_uInt16[aCompactedRanges.Count() + 1];
for (i = 0; i < aCompactedRanges.Count(); i++)
pNewRanges[i] = (sal_uInt16)aCompactedRanges[i];
pNewRanges[i] = 0;
pAddrSet = new SfxItemSet(GetParent()->pSh->GetView().GetCurShell()->GetPool(),
pNewRanges);
pAddrSet->Put(pColl->GetAttrSet());
delete[] pNewRanges;
}
return pAddrSet;
}
// --------------------------------------------------------------------------
IMPL_LINK( SwEnvFmtPage, FormatHdl, ListBox *, EMPTYARG )
{
long lWidth;
long lHeight;
long lSendFromLeft;
long lSendFromTop;
long lAddrFromLeft;
long lAddrFromTop;
sal_uInt16 nPaper = aIDs[aSizeFormatBox.GetSelectEntryPos()];
if (nPaper != (sal_uInt16)PAPER_USER)
{
Size aSz = SvxPaperInfo::GetPaperSize((Paper)nPaper);
lWidth = Max(aSz.Width(), aSz.Height());
lHeight = Min(aSz.Width(), aSz.Height());
}
else
{
lWidth = lUserW;
lHeight = lUserH;
}
lSendFromLeft = 566; // 1cm
lSendFromTop = 566; // 1cm
lAddrFromLeft = lWidth / 2;
lAddrFromTop = lHeight / 2;
SetFldVal(aAddrLeftField, lAddrFromLeft);
SetFldVal(aAddrTopField , lAddrFromTop );
SetFldVal(aSendLeftField, lSendFromLeft);
SetFldVal(aSendTopField , lSendFromTop );
SetFldVal(aSizeWidthField , lWidth );
SetFldVal(aSizeHeightField, lHeight);
SetMinMax();
FillItem(GetParent()->aEnvItem);
aPreview.Invalidate();
return 0;
}
// --------------------------------------------------------------------------
void SwEnvFmtPage::SetMinMax()
{
long lWVal = static_cast< long >(GetFldVal(aSizeWidthField ));
long lHVal = static_cast< long >(GetFldVal(aSizeHeightField));
long lWidth = Max(lWVal, lHVal),
lHeight = Min(lWVal, lHVal);
// Min und Max
aAddrLeftField.SetMin((long) 100 * (GetFldVal(aSendLeftField) + 566), FUNIT_TWIP);
aAddrLeftField.SetMax((long) 100 * (lWidth - 2 * 566), FUNIT_TWIP);
aAddrTopField .SetMin((long) 100 * (GetFldVal(aSendTopField ) + 2 * 566), FUNIT_TWIP);
aAddrTopField .SetMax((long) 100 * (lHeight - 2 * 566), FUNIT_TWIP);
aSendLeftField.SetMin((long) 100 * (566), FUNIT_TWIP);
aSendLeftField.SetMax((long) 100 * (GetFldVal(aAddrLeftField) - 566), FUNIT_TWIP);
aSendTopField .SetMin((long) 100 * (566), FUNIT_TWIP);
aSendTopField .SetMax((long) 100 * (GetFldVal(aAddrTopField ) - 2 * 566), FUNIT_TWIP);
// First und Last
aAddrLeftField.SetFirst(aAddrLeftField.GetMin());
aAddrLeftField.SetLast (aAddrLeftField.GetMax());
aAddrTopField .SetFirst(aAddrTopField .GetMin());
aAddrTopField .SetLast (aAddrTopField .GetMax());
aSendLeftField.SetFirst(aSendLeftField.GetMin());
aSendLeftField.SetLast (aSendLeftField.GetMax());
aSendTopField .SetFirst(aSendTopField .GetMin());
aSendTopField .SetLast (aSendTopField .GetMax());
// Fields neu formatieren
aAddrLeftField .Reformat();
aAddrTopField .Reformat();
aSendLeftField .Reformat();
aSendTopField .Reformat();
aSizeWidthField .Reformat();
aSizeHeightField.Reformat();
}
// --------------------------------------------------------------------------
SfxTabPage* __EXPORT SwEnvFmtPage::Create(Window* pParent, const SfxItemSet& rSet)
{
return new SwEnvFmtPage(pParent, rSet);
}
// ----------------------------------------------------------------------------
void __EXPORT SwEnvFmtPage::ActivatePage(const SfxItemSet& rSet)
{
SfxItemSet aSet(rSet);
aSet.Put(GetParent()->aEnvItem);
Reset(aSet);
}
// ----------------------------------------------------------------------------
int __EXPORT SwEnvFmtPage::DeactivatePage(SfxItemSet* _pSet)
{
if( _pSet )
FillItemSet(*_pSet);
return SfxTabPage::LEAVE_PAGE;
}
// --------------------------------------------------------------------------
void SwEnvFmtPage::FillItem(SwEnvItem& rItem)
{
rItem.lAddrFromLeft = static_cast< sal_Int32 >(GetFldVal(aAddrLeftField));
rItem.lAddrFromTop = static_cast< sal_Int32 >(GetFldVal(aAddrTopField ));
rItem.lSendFromLeft = static_cast< sal_Int32 >(GetFldVal(aSendLeftField));
rItem.lSendFromTop = static_cast< sal_Int32 >(GetFldVal(aSendTopField ));
sal_uInt16 nPaper = aIDs[aSizeFormatBox.GetSelectEntryPos()];
if (nPaper == (sal_uInt16)PAPER_USER)
{
long lWVal = static_cast< long >(GetFldVal(aSizeWidthField ));
long lHVal = static_cast< long >(GetFldVal(aSizeHeightField));
rItem.lWidth = Max(lWVal, lHVal);
rItem.lHeight = Min(lWVal, lHVal);
}
else
{
long lWVal = SvxPaperInfo::GetPaperSize((Paper)nPaper).Width ();
long lHVal = SvxPaperInfo::GetPaperSize((Paper)nPaper).Height();
rItem.lWidth = Max(lWVal, lHVal);
rItem.lHeight = Min(lWVal, lHVal);
}
}
// --------------------------------------------------------------------------
sal_Bool __EXPORT SwEnvFmtPage::FillItemSet(SfxItemSet& rSet)
{
FillItem(GetParent()->aEnvItem);
rSet.Put(GetParent()->aEnvItem);
return sal_True;
}
// --------------------------------------------------------------------------
void __EXPORT SwEnvFmtPage::Reset(const SfxItemSet& rSet)
{
const SwEnvItem& rItem = (const SwEnvItem&) rSet.Get(FN_ENVELOP);
Paper ePaper = SvxPaperInfo::GetSvxPaper(
Size( Min(rItem.lWidth, rItem.lHeight),
Max(rItem.lWidth, rItem.lHeight)), MAP_TWIP, sal_True);
for (sal_uInt16 i = 0; i < (sal_uInt16) aIDs.Count(); i++)
if (aIDs[i] == (sal_uInt16)ePaper)
aSizeFormatBox.SelectEntryPos(i);
// Die MetricFields
SetFldVal(aAddrLeftField, rItem.lAddrFromLeft);
SetFldVal(aAddrTopField , rItem.lAddrFromTop );
SetFldVal(aSendLeftField, rItem.lSendFromLeft);
SetFldVal(aSendTopField , rItem.lSendFromTop );
SetFldVal(aSizeWidthField , Max(rItem.lWidth, rItem.lHeight));
SetFldVal(aSizeHeightField , Min(rItem.lWidth, rItem.lHeight));
SetMinMax();
DELETEZ(GetParent()->pSenderSet);
DELETEZ(GetParent()->pAddresseeSet);
}