Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include <cstdarg>
22 :
23 : #include <hintids.hxx>
24 :
25 : #include <comphelper/string.hxx>
26 : #include <sfx2/request.hxx>
27 : #include <svx/svxids.hrc>
28 :
29 : #include <svtools/svmedit.hxx>
30 : #include <vcl/svapp.hxx>
31 : #include <vcl/wrkwin.hxx>
32 : #include <sfx2/app.hxx>
33 : #include <sfx2/docfac.hxx>
34 : #include <sfx2/printer.hxx>
35 : #include <vcl/msgbox.hxx>
36 : #include <sfx2/dispatch.hxx>
37 : #include <editeng/boxitem.hxx>
38 : #include <editeng/lrspitem.hxx>
39 : #include <editeng/ulspitem.hxx>
40 : #include <editeng/pbinitem.hxx>
41 : #include <editeng/paperinf.hxx>
42 : #include <editeng/brkitem.hxx>
43 : #include <fmthdft.hxx>
44 : #include <swwait.hxx>
45 : #include <paratr.hxx>
46 : #include <swmodule.hxx>
47 : #include <wrtsh.hxx>
48 : #include <view.hxx>
49 : #include <docsh.hxx>
50 : #include <frmatr.hxx>
51 : #include <fldbas.hxx>
52 : #include <swundo.hxx>
53 : #include <IDocumentDeviceAccess.hxx>
54 : #include <dbmgr.hxx>
55 : #include <fmtcol.hxx>
56 : #include <frmmgr.hxx>
57 : #include <fldmgr.hxx>
58 : #include <pagedesc.hxx>
59 : #include <poolfmt.hxx>
60 : #include <expfld.hxx>
61 : #include <SwStyleNameMapper.hxx>
62 : #include <crsskip.hxx>
63 :
64 : #include <cmdid.h>
65 : #include <globals.hrc>
66 : #include <app.hrc>
67 : #include <poolfmt.hrc>
68 : #include "swabstdlg.hxx"
69 : #include "envelp.hrc"
70 : #include "envimg.hxx"
71 :
72 : #define ENV_NEWDOC RET_OK
73 : #define ENV_INSERT RET_USER
74 :
75 : // Function used for labels and envelopes in applab.cxx and appenv.cxx
76 0 : String InsertLabEnvText( SwWrtShell& rSh, SwFldMgr& rFldMgr, const String& rText )
77 : {
78 0 : String sRet;
79 0 : String aText(comphelper::string::remove(rText, '\r'));
80 :
81 0 : sal_uInt16 nTokenPos = 0;
82 0 : while( STRING_NOTFOUND != nTokenPos )
83 : {
84 0 : String aLine = aText.GetToken( 0, '\n', nTokenPos );
85 0 : while ( aLine.Len() )
86 : {
87 0 : String sTmpText;
88 0 : bool bField = false;
89 :
90 0 : sal_uInt16 nPos = aLine.Search( '<' );
91 0 : if ( nPos )
92 : {
93 0 : sTmpText = aLine.Copy( 0, nPos );
94 0 : aLine.Erase( 0, nPos );
95 : }
96 : else
97 : {
98 0 : nPos = aLine.Search( '>' );
99 0 : if ( nPos == STRING_NOTFOUND )
100 : {
101 0 : sTmpText = aLine;
102 0 : aLine.Erase();
103 : }
104 : else
105 : {
106 0 : sTmpText = aLine.Copy( 0, nPos + 1);
107 0 : aLine.Erase( 0, nPos + 1);
108 :
109 : // Database fields must contain at least 3 points!
110 0 : String sDBName( sTmpText.Copy( 1, sTmpText.Len() - 2));
111 0 : sal_uInt16 nCnt = comphelper::string::getTokenCount(sDBName, '.');
112 0 : if (nCnt >= 3)
113 : {
114 0 : ::ReplacePoint(sDBName, true);
115 0 : SwInsertFld_Data aData(TYP_DBFLD, 0, sDBName, aEmptyStr, 0, &rSh );
116 0 : rFldMgr.InsertFld( aData );
117 0 : sRet = sDBName;
118 0 : bField = true;
119 0 : }
120 : }
121 : }
122 0 : if ( !bField )
123 0 : rSh.Insert( sTmpText );
124 0 : }
125 0 : rSh.InsertLineBreak();
126 0 : }
127 0 : rSh.DelLeft(); // Again remove last linebreak
128 :
129 0 : return sRet;
130 : }
131 :
132 0 : static void lcl_CopyCollAttr(SwWrtShell* pOldSh, SwWrtShell* pNewSh, sal_uInt16 nCollId)
133 : {
134 0 : sal_uInt16 nCollCnt = pOldSh->GetTxtFmtCollCount();
135 : SwTxtFmtColl* pColl;
136 0 : for( sal_uInt16 nCnt = 0; nCnt < nCollCnt; ++nCnt )
137 0 : if(nCollId == (pColl = &pOldSh->GetTxtFmtColl(nCnt))->GetPoolFmtId())
138 0 : pNewSh->GetTxtCollFromPool(nCollId)->SetFmtAttr(pColl->GetAttrSet());
139 0 : }
140 :
141 0 : void SwModule::InsertEnv( SfxRequest& rReq )
142 : {
143 : static sal_uInt16 nTitleNo = 0;
144 :
145 : SwDocShell *pMyDocSh;
146 : SfxViewFrame *pFrame;
147 : SwView *pNewView;
148 : SwWrtShell *pOldSh,
149 : *pSh;
150 :
151 : // Get current shell
152 0 : pMyDocSh = (SwDocShell*) SfxObjectShell::Current();
153 0 : pOldSh = pMyDocSh ? pMyDocSh->GetWrtShell() : 0;
154 :
155 : // Create new document (don't show!)
156 0 : SfxObjectShellLock xDocSh( new SwDocShell( SFX_CREATE_MODE_STANDARD ) );
157 0 : xDocSh->DoInitNew( 0 );
158 0 : pFrame = SfxViewFrame::LoadHiddenDocument( *xDocSh, 0 );
159 0 : pNewView = (SwView*) pFrame->GetViewShell();
160 0 : pNewView->AttrChangedNotify( &pNewView->GetWrtShell() ); // so that SelectShell is being called
161 0 : pSh = pNewView->GetWrtShellPtr();
162 :
163 0 : String aTmp( SW_RES(STR_ENV_TITLE) );
164 0 : aTmp += String::CreateFromInt32( ++nTitleNo );
165 0 : xDocSh->SetTitle( aTmp );
166 :
167 : // if applicable, copy the old Collections "Sender" and "Reciever" to
168 : // a new document
169 0 : if ( pOldSh )
170 : {
171 0 : ::lcl_CopyCollAttr(pOldSh, pSh, RES_POOLCOLL_JAKETADRESS);
172 0 : ::lcl_CopyCollAttr(pOldSh, pSh, RES_POOLCOLL_SENDADRESS);
173 : }
174 :
175 : // Read SwEnvItem from config
176 0 : SwEnvCfgItem aEnvCfg;
177 :
178 : // Check if there's already an envelope.
179 0 : bool bEnvChange = false;
180 :
181 0 : SfxItemSet aSet(GetPool(), FN_ENVELOP, FN_ENVELOP, 0);
182 0 : aSet.Put(aEnvCfg.GetItem());
183 :
184 0 : SfxPrinter* pTempPrinter = pSh->getIDocumentDeviceAccess()->getPrinter( true );
185 0 : if(pOldSh )
186 : {
187 0 : const SwPageDesc& rCurPageDesc = pOldSh->GetPageDesc(pOldSh->GetCurPageDesc());
188 0 : String sJacket;
189 0 : SwStyleNameMapper::FillUIName( RES_POOLPAGE_JAKET, sJacket );
190 0 : bEnvChange = rCurPageDesc.GetName() == sJacket;
191 :
192 0 : IDocumentDeviceAccess* pIDDA_old = pOldSh->getIDocumentDeviceAccess();
193 0 : if( pIDDA_old->getPrinter( false ) )
194 : {
195 0 : IDocumentDeviceAccess* pIDDA = pSh->getIDocumentDeviceAccess();
196 0 : pIDDA->setJobsetup( *pIDDA_old->getJobsetup() );
197 : //#69563# if it isn't the same printer then the pointer has been invalidated!
198 0 : pTempPrinter = pIDDA->getPrinter( true );
199 : }
200 0 : pTempPrinter->SetPaperBin(rCurPageDesc.GetMaster().GetPaperBin().GetValue());
201 :
202 : }
203 :
204 0 : Window *pParent = pOldSh ? pOldSh->GetWin() : 0;
205 0 : SfxAbstractTabDialog * pDlg=NULL;
206 0 : short nMode = ENV_INSERT;
207 :
208 0 : SFX_REQUEST_ARG( rReq, pItem, SwEnvItem, FN_ENVELOP, sal_False );
209 0 : if ( !pItem )
210 : {
211 0 : SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
212 : OSL_ENSURE(pFact, "SwAbstractDialogFactory fail!");
213 :
214 0 : pDlg = pFact->CreateSwEnvDlg( pParent, aSet, pOldSh, pTempPrinter, !bEnvChange, DLG_ENV );
215 : OSL_ENSURE(pDlg, "Dialogdiet fail!");
216 0 : nMode = pDlg->Execute();
217 : }
218 : else
219 : {
220 0 : SFX_REQUEST_ARG( rReq, pBoolItem, SfxBoolItem, FN_PARAM_1, sal_False );
221 0 : if ( pBoolItem && pBoolItem->GetValue() )
222 0 : nMode = ENV_NEWDOC;
223 : }
224 :
225 0 : if (nMode == ENV_NEWDOC || nMode == ENV_INSERT)
226 : {
227 0 : SwWait aWait( (SwDocShell&)*xDocSh, sal_True );
228 :
229 : // Read dialog and save item to config
230 0 : const SwEnvItem& rItem = pItem ? *pItem : (const SwEnvItem&) pDlg->GetOutputItemSet()->Get(FN_ENVELOP);
231 0 : aEnvCfg.GetItem() = rItem;
232 0 : aEnvCfg.Commit();
233 :
234 : // When we print we take the Jobsetup that is set up in the dialog.
235 : // Information has to be set here, before a possible destruction of
236 : // the new shell because the shell's printer has been handed to the
237 : // dialog.
238 0 : if ( nMode != ENV_NEWDOC )
239 : {
240 : OSL_ENSURE(pOldSh, "No document - wasn't 'Insert' disabled???");
241 0 : SvxPaperBinItem aItem( RES_PAPER_BIN );
242 0 : aItem.SetValue((sal_uInt8)pSh->getIDocumentDeviceAccess()->getPrinter(true)->GetPaperBin());
243 0 : pOldSh->GetPageDescFromPool(RES_POOLPAGE_JAKET)->GetMaster().SetFmtAttr(aItem);
244 : }
245 :
246 0 : SwWrtShell *pTmp = nMode == ENV_INSERT ? pOldSh : pSh;
247 0 : const SwPageDesc* pFollow = 0;
248 0 : SwTxtFmtColl *pSend = pTmp->GetTxtCollFromPool( RES_POOLCOLL_SENDADRESS ),
249 0 : *pAddr = pTmp->GetTxtCollFromPool( RES_POOLCOLL_JAKETADRESS);
250 0 : const String &rSendMark = pSend->GetName();
251 0 : const String &rAddrMark = pAddr->GetName();
252 :
253 0 : if (nMode == ENV_INSERT)
254 : {
255 :
256 0 : SetView(&pOldSh->GetView()); // Set pointer to top view
257 :
258 : // Delete new document
259 0 : xDocSh->DoClose();
260 0 : pSh = pOldSh;
261 : //#i4251# selected text or objects in the document should
262 : //not be deleted on inserting envelopes
263 0 : pSh->EnterStdMode();
264 : // Here it goes (insert)
265 0 : pSh->StartUndo(UNDO_UI_INSERT_ENVELOPE, NULL);
266 0 : pSh->StartAllAction();
267 0 : pSh->SttEndDoc(sal_True);
268 :
269 0 : if (bEnvChange)
270 : {
271 : // followup template: page 2
272 0 : pFollow = pSh->GetPageDesc(pSh->GetCurPageDesc()).GetFollow();
273 :
274 : // Delete text from the first page
275 0 : if ( !pSh->SttNxtPg(sal_True) )
276 0 : pSh->EndPg(sal_True);
277 0 : pSh->DelRight();
278 : // Delete frame of the first page
279 0 : if( pSh->GotoFly( rSendMark ) )
280 : {
281 0 : pSh->EnterSelFrmMode();
282 0 : pSh->DelRight();
283 : }
284 0 : if ( pSh->GotoFly( rAddrMark ) )
285 : {
286 0 : pSh->EnterSelFrmMode();
287 0 : pSh->DelRight();
288 : }
289 0 : pSh->SttEndDoc(sal_True);
290 : }
291 : else
292 : // Followup template: page 1
293 0 : pFollow = &pSh->GetPageDesc(pSh->GetCurPageDesc());
294 :
295 : // Insert page break
296 0 : if ( pSh->IsCrsrInTbl() )
297 : {
298 0 : pSh->SplitNode();
299 0 : pSh->Right( CRSR_SKIP_CHARS, sal_False, 1, sal_False );
300 0 : SfxItemSet aBreakSet( pSh->GetAttrPool(), RES_BREAK, RES_BREAK, 0 );
301 0 : aBreakSet.Put( SvxFmtBreakItem(SVX_BREAK_PAGE_BEFORE, RES_BREAK) );
302 0 : pSh->SetTblAttr( aBreakSet );
303 : }
304 : else
305 0 : pSh->InsertPageBreak(0, sal_False);
306 0 : pSh->SttEndDoc(sal_True);
307 : }
308 : else
309 : {
310 0 : pFollow = &pSh->GetPageDesc(pSh->GetCurPageDesc());
311 : // Let's go (print)
312 0 : pSh->StartAllAction();
313 0 : pSh->DoUndo(sal_False);
314 :
315 : // Again, copy the new collections "Sender" and "Reciever" to
316 : // a new document
317 0 : if ( pOldSh )
318 : {
319 0 : ::lcl_CopyCollAttr(pOldSh, pSh, RES_POOLCOLL_JAKETADRESS);
320 0 : ::lcl_CopyCollAttr(pOldSh, pSh, RES_POOLCOLL_SENDADRESS);
321 : }
322 : }
323 :
324 0 : SET_CURR_SHELL(pSh);
325 0 : pSh->SetNewDoc(); // Avoid performance problems
326 :
327 : // Remember Flys of this site
328 0 : std::vector<SwFrmFmt*> aFlyArr;
329 0 : if( ENV_NEWDOC != nMode && !bEnvChange )
330 0 : pSh->GetPageObjs( aFlyArr );
331 :
332 : // Get page description
333 0 : SwPageDesc* pDesc = pSh->GetPageDescFromPool(RES_POOLPAGE_JAKET);
334 0 : SwFrmFmt& rFmt = pDesc->GetMaster();
335 :
336 0 : Printer *pPrt = pSh->getIDocumentDeviceAccess()->getPrinter( true );
337 :
338 : // Borders (are put together by Shift-Offset and alignment)
339 0 : Size aPaperSize = pPrt->PixelToLogic( pPrt->GetPaperSizePixel(),
340 0 : MAP_TWIP);
341 0 : if ( !aPaperSize.Width() && !aPaperSize.Height() )
342 0 : aPaperSize = SvxPaperInfo::GetPaperSize(PAPER_A4);
343 0 : if ( aPaperSize.Width() > aPaperSize.Height() )
344 0 : Swap( aPaperSize );
345 :
346 0 : long lLeft = rItem.lShiftRight,
347 0 : lUpper = rItem.lShiftDown;
348 :
349 0 : sal_uInt16 nPageW = (sal_uInt16) Max(rItem.lWidth, rItem.lHeight),
350 0 : nPageH = (sal_uInt16) Min(rItem.lWidth, rItem.lHeight);
351 :
352 0 : switch (rItem.eAlign)
353 : {
354 0 : case ENV_HOR_LEFT: break;
355 0 : case ENV_HOR_CNTR: lLeft += Max(0L, long(aPaperSize.Width() - nPageW)) / 2;
356 0 : break;
357 0 : case ENV_HOR_RGHT: lLeft += Max(0L, long(aPaperSize.Width() - nPageW));
358 0 : break;
359 0 : case ENV_VER_LEFT: lUpper += Max(0L, long(aPaperSize.Width() - nPageH));
360 0 : break;
361 0 : case ENV_VER_CNTR: lUpper += Max(0L, long(aPaperSize.Width() - nPageH)) / 2;
362 0 : break;
363 0 : case ENV_VER_RGHT: break;
364 : }
365 0 : SvxLRSpaceItem aLRMargin( RES_LR_SPACE );
366 0 : SvxULSpaceItem aULMargin( RES_UL_SPACE );
367 0 : aLRMargin.SetLeft ((sal_uInt16) lLeft );
368 0 : aULMargin.SetUpper((sal_uInt16) lUpper);
369 0 : aLRMargin.SetRight(0);
370 0 : aULMargin.SetLower(0);
371 0 : rFmt.SetFmtAttr(aLRMargin);
372 0 : rFmt.SetFmtAttr(aULMargin);
373 :
374 : // Header and footer
375 0 : rFmt.SetFmtAttr(SwFmtHeader(sal_False));
376 0 : pDesc->ChgHeaderShare(sal_False);
377 0 : rFmt.SetFmtAttr(SwFmtFooter(sal_False));
378 0 : pDesc->ChgFooterShare(sal_False);
379 :
380 : // Page numbering
381 0 : pDesc->SetUseOn(nsUseOnPage::PD_ALL);
382 :
383 : // Page size
384 : rFmt.SetFmtAttr(SwFmtFrmSize(ATT_FIX_SIZE,
385 0 : nPageW + lLeft, nPageH + lUpper));
386 :
387 : // Set type of page numbering
388 0 : SvxNumberType aType;
389 0 : aType.SetNumberingType(SVX_NUM_NUMBER_NONE);
390 0 : pDesc->SetNumType(aType);
391 :
392 : // Followup template
393 0 : if (pFollow)
394 0 : pDesc->SetFollow(pFollow);
395 :
396 : // Landscape
397 : pDesc->SetLandscape( rItem.eAlign >= ENV_VER_LEFT &&
398 0 : rItem.eAlign <= ENV_VER_RGHT);
399 :
400 : // Apply page description
401 :
402 : sal_uInt16 nPos;
403 0 : pSh->FindPageDescByName( pDesc->GetName(),
404 : sal_False,
405 0 : &nPos );
406 :
407 :
408 0 : pSh->ChgPageDesc( nPos, *pDesc);
409 0 : pSh->ChgCurPageDesc(*pDesc);
410 :
411 : // Insert Frame
412 0 : SwFlyFrmAttrMgr aMgr(sal_False, pSh, FRMMGR_TYPE_ENVELP);
413 0 : SwFldMgr aFldMgr;
414 0 : aMgr.SetHeightSizeType(ATT_VAR_SIZE);
415 :
416 : // Overwrite defaults!
417 0 : aMgr.GetAttrSet().Put( SvxBoxItem(RES_BOX) );
418 0 : aMgr.SetULSpace( 0L, 0L );
419 0 : aMgr.SetLRSpace( 0L, 0L );
420 :
421 : // Sender
422 0 : if (rItem.bSend)
423 : {
424 0 : pSh->SttEndDoc(sal_True);
425 : aMgr.InsertFlyFrm(FLY_AT_PAGE,
426 : Point(rItem.lSendFromLeft + lLeft, rItem.lSendFromTop + lUpper),
427 0 : Size (rItem.lAddrFromLeft - rItem.lSendFromLeft, 0));
428 :
429 0 : pSh->EnterSelFrmMode();
430 0 : pSh->SetFlyName( rSendMark );
431 0 : pSh->UnSelectFrm();
432 0 : pSh->LeaveSelFrmMode();
433 0 : pSh->SetTxtFmtColl( pSend );
434 0 : InsertLabEnvText( *pSh, aFldMgr, rItem.aSendText );
435 0 : aMgr.UpdateAttrMgr();
436 : }
437 :
438 : // Addressee
439 0 : pSh->SttEndDoc(sal_True);
440 :
441 : aMgr.InsertFlyFrm(FLY_AT_PAGE,
442 : Point(rItem.lAddrFromLeft + lLeft, rItem.lAddrFromTop + lUpper),
443 0 : Size (nPageW - rItem.lAddrFromLeft - 566, 0));
444 0 : pSh->EnterSelFrmMode();
445 0 : pSh->SetFlyName( rAddrMark );
446 0 : pSh->UnSelectFrm();
447 0 : pSh->LeaveSelFrmMode();
448 0 : pSh->SetTxtFmtColl( pAddr );
449 0 : InsertLabEnvText(*pSh, aFldMgr, rItem.aAddrText);
450 :
451 : // Move Flys to the "old" pages
452 0 : if (!aFlyArr.empty())
453 0 : pSh->SetPageObjsNewPage(aFlyArr, 1);
454 :
455 : // Finished
456 0 : pSh->SttEndDoc(sal_True);
457 :
458 0 : pSh->EndAllAction();
459 :
460 0 : if (nMode == ENV_NEWDOC)
461 0 : pSh->DoUndo(sal_True);
462 : else
463 0 : pSh->EndUndo(UNDO_UI_INSERT_ENVELOPE);
464 :
465 0 : if (nMode == ENV_NEWDOC)
466 : {
467 0 : pFrame->GetFrame().Appear();
468 :
469 0 : if ( rItem.aAddrText.indexOf('<') >= 0 )
470 : {
471 : static sal_uInt16 const aInva[] =
472 : {
473 : SID_SBA_BRW_UPDATE,
474 : SID_SBA_BRW_INSERT,
475 : SID_SBA_BRW_MERGE,
476 : 0
477 : };
478 0 : pFrame->GetBindings().Invalidate( aInva );
479 :
480 : // Open database beamer
481 0 : ShowDBObj(*pNewView, pSh->GetDBData());
482 : }
483 : }
484 :
485 0 : if ( !pItem )
486 : {
487 0 : rReq.AppendItem( rItem );
488 0 : if ( nMode == ENV_NEWDOC )
489 0 : rReq.AppendItem( SfxBoolItem( FN_PARAM_1, sal_True ) );
490 : }
491 :
492 0 : rReq.Done();
493 : }
494 : else // Abort
495 : {
496 0 : rReq.Ignore();
497 :
498 0 : xDocSh->DoClose();
499 0 : --nTitleNo;
500 :
501 : // Set pointer to top view
502 0 : if (pOldSh)
503 0 : SetView(&pOldSh->GetView());
504 : }
505 0 : delete pDlg;
506 30 : }
507 :
508 :
509 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|