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