1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: appenv.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #if STLPORT_VERSION>=321
40 #include <hintids.hxx>
42 #include <sfx2/request.hxx>
43 #include <svx/svxids.hrc>
45 #include <svtools/svmedit.hxx>
46 #ifndef _APP_HXX //autogen
47 #include <vcl/svapp.hxx>
49 #ifndef _WRKWIN_HXX //autogen
50 #include <vcl/wrkwin.hxx>
52 #include <sfx2/app.hxx>
53 #include <sfx2/docfac.hxx>
54 #include <sfx2/printer.hxx>
55 #ifndef _MSGBOX_HXX //autogen
56 #include <vcl/msgbox.hxx>
58 #include <sfx2/dispatch.hxx>
59 #include <svx/boxitem.hxx>
60 #include <svx/lrspitem.hxx>
61 #include <svx/ulspitem.hxx>
62 #include <svx/pbinitem.hxx>
63 #include <svx/paperinf.hxx>
64 #include <svx/brkitem.hxx>
65 #include <fmthdft.hxx>
68 #include <swmodule.hxx>
79 #ifndef IDOCUMENTDEVICEACCESS_HXX_INCLUDED
80 #include <IDocumentDeviceAccess.hxx>
88 #include <pagedesc.hxx>
89 #include <poolfmt.hxx>
91 #include <SwStyleNameMapper.hxx>
92 #include <crsskip.hxx>
98 #include <globals.hrc>
104 #include <poolfmt.hrc>
106 #include "swabstdlg.hxx"
107 #include "envelp.hrc"
108 #include "envimg.hxx"
110 #define ENV_NEWDOC RET_OK
111 #define ENV_INSERT RET_USER
112 #define ENV_CANCEL SHRT_MAX
115 // --------------------------------------------------------------------------
118 // Funktion wird fuer Etiketten und Briefumschlaege benutzt!
119 // im applab.cxx und appenv.cxx
120 String
InsertLabEnvText( SwWrtShell
& rSh
, SwFldMgr
& rFldMgr
, const String
& rText
)
124 aText
.EraseAllChars( '\r' );
127 USHORT nTokenPos
= 0;
128 while( STRING_NOTFOUND
!= nTokenPos
)
130 String aLine
= aText
.GetToken( 0, '\n', nTokenPos
);
131 while ( aLine
.Len() )
136 USHORT nPos
= aLine
.Search( '<' );
139 sTmpText
= aLine
.Copy( 0, nPos
);
140 aLine
.Erase( 0, nPos
);
141 // sTmpText = aLine.Cut( 0, nPos );
145 nPos
= aLine
.Search( '>' );
146 if ( nPos
== STRING_NOTFOUND
)
150 // sTmpText = aLine.Cut();
154 sTmpText
= aLine
.Copy( 0, nPos
+ 1);
155 aLine
.Erase( 0, nPos
+ 1);
156 // sTmpText = aLine.Cut( 0, nPos + 1 );
158 // Datenbankfelder muesen mind. 3 Punkte beinhalten!
159 String
sDBName( sTmpText
.Copy( 1, sTmpText
.Len() - 2));
160 USHORT nCnt
= sDBName
.GetTokenCount('.');
163 ::ReplacePoint(sDBName
, TRUE
);
164 SwInsertFld_Data
aData(TYP_DBFLD
, 0, sDBName
, aEmptyStr
, 0, &rSh
);
165 rFldMgr
.InsertFld( aData
);
172 rSh
.Insert( sTmpText
);
174 rSh
.InsertLineBreak();
176 rSh
.DelLeft(); // Letzten Linebreak wieder l???schen
181 // ----------------------------------------------------------------------------
184 void lcl_CopyCollAttr(SwWrtShell
* pOldSh
, SwWrtShell
* pNewSh
, USHORT nCollId
)
186 USHORT nCollCnt
= pOldSh
->GetTxtFmtCollCount();
188 for( USHORT nCnt
= 0; nCnt
< nCollCnt
; ++nCnt
)
189 if(nCollId
== (pColl
= &pOldSh
->GetTxtFmtColl(nCnt
))->GetPoolFmtId())
190 pNewSh
->GetTxtCollFromPool(nCollId
)->SetFmtAttr(pColl
->GetAttrSet());
193 // ----------------------------------------------------------------------------
196 void SwModule::InsertEnv( SfxRequest
& rReq
)
198 static USHORT nTitleNo
= 0;
200 SwDocShell
*pMyDocSh
;
201 SfxViewFrame
*pFrame
;
206 //aktuelle Shell besorgen
207 pMyDocSh
= (SwDocShell
*) SfxObjectShell::Current();
208 pOldSh
= pMyDocSh
? pMyDocSh
->GetWrtShell() : 0;
210 // Neues Dokument erzeugen (kein Show!)
211 SfxObjectShellRef
xDocSh( new SwDocShell( SFX_CREATE_MODE_STANDARD
) );
212 xDocSh
->DoInitNew( 0 );
213 pFrame
= SfxViewFrame::CreateViewFrame( *xDocSh
, 0, TRUE
);
214 pNewView
= (SwView
*) pFrame
->GetViewShell();
215 pNewView
->AttrChangedNotify( &pNewView
->GetWrtShell() );//Damit SelectShell gerufen wird.
216 pSh
= pNewView
->GetWrtShellPtr();
218 String
aTmp( SW_RES(STR_ENV_TITLE
) );
219 aTmp
+= String::CreateFromInt32( ++nTitleNo
);
220 xDocSh
->SetTitle( aTmp
);
222 // Ggf. alte Collections "Absender" und "Empfaenger" in neues
226 ::lcl_CopyCollAttr(pOldSh
, pSh
, RES_POOLCOLL_JAKETADRESS
);
227 ::lcl_CopyCollAttr(pOldSh
, pSh
, RES_POOLCOLL_SENDADRESS
);
230 // SwEnvItem aus Config lesen
231 SwEnvCfgItem aEnvCfg
;
233 //Haben wir schon einen Briefumschlag.
234 BOOL bEnvChange
= FALSE
;
236 SfxItemSet
aSet(GetPool(), FN_ENVELOP
, FN_ENVELOP
, 0);
237 aSet
.Put(aEnvCfg
.GetItem());
239 SfxPrinter
* pTempPrinter
= pSh
->getIDocumentDeviceAccess()->getPrinter( true );
242 const SwPageDesc
& rCurPageDesc
= pOldSh
->GetPageDesc(pOldSh
->GetCurPageDesc());
244 SwStyleNameMapper::FillUIName( RES_POOLPAGE_JAKET
, sJacket
);
245 bEnvChange
= rCurPageDesc
.GetName() == sJacket
;
247 IDocumentDeviceAccess
* pIDDA_old
= pOldSh
->getIDocumentDeviceAccess();
248 if( pIDDA_old
->getPrinter( false ) )
250 IDocumentDeviceAccess
* pIDDA
= pSh
->getIDocumentDeviceAccess();
251 pIDDA
->setJobsetup( *pIDDA_old
->getJobsetup() );
252 //#69563# if it isn't the same printer then the pointer has been invalidated!
253 pTempPrinter
= pIDDA
->getPrinter( true );
255 pTempPrinter
->SetPaperBin(rCurPageDesc
.GetMaster().GetPaperBin().GetValue());
259 Window
*pParent
= pOldSh
? pOldSh
->GetWin() : 0;
260 SfxAbstractTabDialog
* pDlg
=NULL
;
261 short nMode
= ENV_INSERT
;
263 SFX_REQUEST_ARG( rReq
, pItem
, SwEnvItem
, FN_ENVELOP
, sal_False
);
266 SwAbstractDialogFactory
* pFact
= SwAbstractDialogFactory::Create();
267 DBG_ASSERT(pFact
, "SwAbstractDialogFactory fail!");
269 pDlg
= pFact
->CreateSwEnvDlg( pParent
, aSet
, pOldSh
, pTempPrinter
, !bEnvChange
, DLG_ENV
);
270 DBG_ASSERT(pDlg
, "Dialogdiet fail!");
271 nMode
= pDlg
->Execute();
275 SFX_REQUEST_ARG( rReq
, pBoolItem
, SfxBoolItem
, FN_PARAM_1
, sal_False
);
276 if ( pBoolItem
&& pBoolItem
->GetValue() )
280 if (nMode
== ENV_NEWDOC
|| nMode
== ENV_INSERT
)
282 SwWait
aWait( (SwDocShell
&)*xDocSh
, TRUE
);
284 // Dialog auslesen, Item in Config speichern
285 const SwEnvItem
& rItem
= pItem
? *pItem
: (const SwEnvItem
&) pDlg
->GetOutputItemSet()->Get(FN_ENVELOP
);
286 aEnvCfg
.GetItem() = rItem
;
289 //Wenn wir Drucken uebernehmen wir den eingestellten Jobsetup aus
290 //dem Dialog. Die Informationen muessen hier vor dem evtl. zerstoeren
291 //der neuen Shell gesetzt werden, weil deren Drucker an den Dialog
293 if ( nMode
!= ENV_NEWDOC
)
295 ASSERT(pOldSh
, "Kein Dokument - war 'Einfuegen' nicht disabled???");
296 SvxPaperBinItem
aItem( RES_PAPER_BIN
);
297 aItem
.SetValue((BYTE
)pSh
->getIDocumentDeviceAccess()->getPrinter(true)->GetPaperBin());
298 pOldSh
->GetPageDescFromPool(RES_POOLPAGE_JAKET
)->GetMaster().SetFmtAttr(aItem
);
301 SwWrtShell
*pTmp
= nMode
== ENV_INSERT
? pOldSh
: pSh
;
302 const SwPageDesc
* pFollow
= 0;
303 SwTxtFmtColl
*pSend
= pTmp
->GetTxtCollFromPool( RES_POOLCOLL_SENDADRESS
),
304 *pAddr
= pTmp
->GetTxtCollFromPool( RES_POOLCOLL_JAKETADRESS
);
305 const String
&rSendMark
= pSend
->GetName();
306 const String
&rAddrMark
= pAddr
->GetName();
308 if (nMode
== ENV_INSERT
)
311 SetView(&pOldSh
->GetView()); // Pointer auf oberste View restaurieren
313 //Neues Dok wieder loeschen
316 //#i4251# selected text or objects in the document should
317 //not be deleted on inserting envelopes
319 // Los geht's (Einfuegen)
320 pSh
->StartUndo(UNDO_UI_INSERT_ENVELOPE
, NULL
);
321 pSh
->StartAllAction();
322 pSh
->SttEndDoc(TRUE
);
326 // Folgevorlage: Seite 2
327 pFollow
= pSh
->GetPageDesc(pSh
->GetCurPageDesc()).GetFollow();
329 // Text der ersten Seite loeschen
330 if ( !pSh
->SttNxtPg(TRUE
) )
333 // Rahmen der ersten Seite loeschen
334 if( pSh
->GotoFly( rSendMark
) )
336 pSh
->EnterSelFrmMode();
339 if ( pSh
->GotoFly( rAddrMark
) )
341 pSh
->EnterSelFrmMode();
344 pSh
->SttEndDoc(TRUE
);
347 // Folgevorlage: Seite 1
348 pFollow
= &pSh
->GetPageDesc(pSh
->GetCurPageDesc());
350 // Seitenumbruch einfuegen
351 if ( pSh
->IsCrsrInTbl() )
354 pSh
->Right( CRSR_SKIP_CHARS
, FALSE
, 1, FALSE
);
355 SfxItemSet
aBreakSet( pSh
->GetAttrPool(), RES_BREAK
, RES_BREAK
, 0 );
356 aBreakSet
.Put( SvxFmtBreakItem(SVX_BREAK_PAGE_BEFORE
, RES_BREAK
) );
357 pSh
->SetTblAttr( aBreakSet
);
360 pSh
->InsertPageBreak(0, FALSE
);
361 pSh
->SttEndDoc(TRUE
);
365 pFollow
= &pSh
->GetPageDesc(pSh
->GetCurPageDesc());
366 // Los geht's (Drucken)
367 pSh
->StartAllAction();
370 // Neue Collections "Absender" und "Empfaenger" wieder in neues
374 ::lcl_CopyCollAttr(pOldSh
, pSh
, RES_POOLCOLL_JAKETADRESS
);
375 ::lcl_CopyCollAttr(pOldSh
, pSh
, RES_POOLCOLL_SENDADRESS
);
380 pSh
->SetNewDoc(); // Performanceprobleme vermeiden
382 // Flys dieser Seite merken
383 SvPtrarr
aFlyArr(0, 5);
384 if( ENV_NEWDOC
!= nMode
&& !bEnvChange
)
385 pSh
->GetPageObjs( aFlyArr
);
387 // Page-Desc ermitteln
388 SwPageDesc
* pDesc
= pSh
->GetPageDescFromPool(RES_POOLPAGE_JAKET
);
389 SwFrmFmt
& rFmt
= pDesc
->GetMaster();
391 Printer
*pPrt
= pSh
->getIDocumentDeviceAccess()->getPrinter( true );
393 // Raender (setzen sich zusammen aus Shift-Offset und
395 Size aPaperSize
= pPrt
->PixelToLogic( pPrt
->GetPaperSizePixel(),
397 if ( !aPaperSize
.Width() && !aPaperSize
.Height() )
398 aPaperSize
= SvxPaperInfo::GetPaperSize(PAPER_A4
);
399 if ( aPaperSize
.Width() > aPaperSize
.Height() )
402 long lLeft
= rItem
.lShiftRight
,
403 lUpper
= rItem
.lShiftDown
;
405 USHORT nPageW
= (USHORT
) Max(rItem
.lWidth
, rItem
.lHeight
),
406 nPageH
= (USHORT
) Min(rItem
.lWidth
, rItem
.lHeight
);
408 switch (rItem
.eAlign
)
410 case ENV_HOR_LEFT
: break;
411 case ENV_HOR_CNTR
: lLeft
+= Max(0L, long(aPaperSize
.Width() - nPageW
)) / 2;
413 case ENV_HOR_RGHT
: lLeft
+= Max(0L, long(aPaperSize
.Width() - nPageW
));
415 case ENV_VER_LEFT
: lUpper
+= Max(0L, long(aPaperSize
.Width() - nPageH
));
417 case ENV_VER_CNTR
: lUpper
+= Max(0L, long(aPaperSize
.Width() - nPageH
)) / 2;
419 case ENV_VER_RGHT
: break;
421 SvxLRSpaceItem
aLRMargin( RES_LR_SPACE
);
422 SvxULSpaceItem
aULMargin( RES_UL_SPACE
);
423 aLRMargin
.SetLeft ((USHORT
) lLeft
);
424 aULMargin
.SetUpper((USHORT
) lUpper
);
425 aLRMargin
.SetRight(0);
426 aULMargin
.SetLower(0);
427 rFmt
.SetFmtAttr(aLRMargin
);
428 rFmt
.SetFmtAttr(aULMargin
);
431 rFmt
.SetFmtAttr(SwFmtHeader(BOOL(FALSE
)));
432 pDesc
->ChgHeaderShare(FALSE
);
433 rFmt
.SetFmtAttr(SwFmtFooter(BOOL(FALSE
)));
434 pDesc
->ChgFooterShare(FALSE
);
437 pDesc
->SetUseOn(nsUseOnPage::PD_ALL
);
439 // Einstellen der Seitengroesse
440 rFmt
.SetFmtAttr(SwFmtFrmSize(ATT_FIX_SIZE
,
441 nPageW
+ lLeft
, nPageH
+ lUpper
));
443 // Einstellen der Numerierungsart der Seite
445 aType
.SetNumberingType(SVX_NUM_NUMBER_NONE
);
446 pDesc
->SetNumType(aType
);
450 pDesc
->SetFollow(pFollow
);
453 pDesc
->SetLandscape( rItem
.eAlign
>= ENV_VER_LEFT
&&
454 rItem
.eAlign
<= ENV_VER_RGHT
);
456 // Page-Desc anwenden
459 pSh
->FindPageDescByName( pDesc
->GetName(),
464 pSh
->ChgPageDesc( nPos
, *pDesc
);
465 pSh
->ChgCurPageDesc(*pDesc
);
468 SwFlyFrmAttrMgr
aMgr(FALSE
, pSh
, FRMMGR_TYPE_ENVELP
);
470 aMgr
.SetHeightSizeType(ATT_VAR_SIZE
);
472 //Defaults ueberschreiben!
473 aMgr
.GetAttrSet().Put( SvxBoxItem(RES_BOX
) );
474 aMgr
.SetULSpace( 0L, 0L );
475 aMgr
.SetLRSpace( 0L, 0L );
480 pSh
->SttEndDoc(TRUE
);
481 aMgr
.InsertFlyFrm(FLY_PAGE
,
482 Point(rItem
.lSendFromLeft
+ lLeft
, rItem
.lSendFromTop
+ lUpper
),
483 Size (rItem
.lAddrFromLeft
- rItem
.lSendFromLeft
, 0));
485 pSh
->EnterSelFrmMode();
486 pSh
->SetFlyName( rSendMark
);
488 pSh
->LeaveSelFrmMode();
489 pSh
->SetTxtFmtColl( pSend
);
490 InsertLabEnvText( *pSh
, aFldMgr
, rItem
.aSendText
);
491 aMgr
.UpdateAttrMgr();
495 pSh
->SttEndDoc(TRUE
);
497 aMgr
.InsertFlyFrm(FLY_PAGE
,
498 Point(rItem
.lAddrFromLeft
+ lLeft
, rItem
.lAddrFromTop
+ lUpper
),
499 Size (nPageW
- rItem
.lAddrFromLeft
- 566, 0));
500 pSh
->EnterSelFrmMode();
501 pSh
->SetFlyName( rAddrMark
);
503 pSh
->LeaveSelFrmMode();
504 pSh
->SetTxtFmtColl( pAddr
);
505 InsertLabEnvText(*pSh
, aFldMgr
, rItem
.aAddrText
);
507 // Flys auf die "alten" Seiten verschieben
509 pSh
->SetPageObjsNewPage(aFlyArr
, 1);
512 pSh
->SttEndDoc(TRUE
);
516 if (nMode
== ENV_NEWDOC
)
519 pSh
->EndUndo(UNDO_UI_INSERT_ENVELOPE
);
521 if (nMode
== ENV_NEWDOC
)
523 pFrame
->GetFrame()->Appear();
525 if ( rItem
.aAddrText
.indexOf('<') >= 0 )
527 static USHORT __READONLY_DATA aInva
[] =
534 pFrame
->GetBindings().Invalidate( aInva
);
536 // Datenbankbeamer oeffnen
537 ShowDBObj(*pNewView
, pSh
->GetDBData());
543 rReq
.AppendItem( rItem
);
544 if ( nMode
== ENV_NEWDOC
)
545 rReq
.AppendItem( SfxBoolItem( FN_PARAM_1
, TRUE
) );
557 // Pointer auf oberste View restaurieren
559 SetView(&pOldSh
->GetView());