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 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sw.hxx" 26 27 #include <cstdarg> 28 29 #include <hintids.hxx> 30 31 #include <vcl/svapp.hxx> 32 #include <vcl/wrkwin.hxx> 33 #include <vcl/msgbox.hxx> 34 #include <sfx2/app.hxx> 35 #include <sfx2/dispatch.hxx> 36 #include <sfx2/printer.hxx> 37 #include <sfx2/request.hxx> 38 #include <sfx2/linkmgr.hxx> 39 #include <editeng/pbinitem.hxx> 40 #include <editeng/ulspitem.hxx> 41 #include <editeng/lrspitem.hxx> 42 #include <editeng/boxitem.hxx> 43 #include <editeng/paperinf.hxx> 44 #include <editeng/protitem.hxx> 45 #include <com/sun/star/frame/XStorable.hpp> 46 #include <com/sun/star/frame/XModel.hpp> 47 #include <fmthdft.hxx> 48 #include <fmtanchr.hxx> 49 #include <fmtfsize.hxx> 50 #include <fmtornt.hxx> 51 #include <swwait.hxx> 52 #include <gloshdl.hxx> 53 #include <mdiexp.hxx> 54 #include <frmatr.hxx> 55 #include <paratr.hxx> 56 #include <swmodule.hxx> 57 #include <view.hxx> 58 #include <docsh.hxx> 59 #include <fldbas.hxx> 60 #include <swundo.hxx> 61 #include <wrtsh.hxx> 62 #include <cmdid.h> 63 #include <dbmgr.hxx> 64 #include <fmtcol.hxx> 65 #include <expfld.hxx> 66 #include <fldmgr.hxx> 67 #include <label.hxx> 68 #include <labimg.hxx> 69 #include <section.hxx> 70 #include <pagedesc.hxx> 71 #include <poolfmt.hxx> 72 73 #ifndef _APP_HRC 74 #include <app.hrc> 75 #endif 76 #ifndef _POOLFMT_HRC 77 #include <poolfmt.hrc> 78 #endif 79 #include "swabstdlg.hxx" 80 #include "envelp.hrc" 81 #include <misc.hrc> 82 83 #include <IDocumentDeviceAccess.hxx> 84 85 using namespace ::com::sun::star; 86 using ::rtl::OUString; 87 88 // steht im appenv.cxx 89 extern String InsertLabEnvText( SwWrtShell& , SwFldMgr& , const String& ); 90 91 const char __FAR_DATA MASTER_LABEL[] = "MasterLabel"; 92 93 // -------------------------------------------------------------------------- 94 95 const SwFrmFmt *lcl_InsertBCText( SwWrtShell& rSh, const SwLabItem& rItem, 96 SwFrmFmt &rFmt, 97 sal_uInt16 nCol, sal_uInt16 nRow, sal_Bool bPage) 98 { 99 SfxItemSet aSet(rSh.GetAttrPool(), RES_ANCHOR, RES_ANCHOR, 100 RES_VERT_ORIENT, RES_VERT_ORIENT, RES_HORI_ORIENT, RES_HORI_ORIENT, 101 RES_LR_SPACE, RES_LR_SPACE, 0 ); 102 sal_uInt16 nPhyPageNum, nVirtPageNum; 103 rSh.GetPageNum( nPhyPageNum, nVirtPageNum ); 104 105 aSet.Put(SwFmtAnchor(bPage ? FLY_AS_CHAR : FLY_AT_PAGE, nPhyPageNum)); 106 if (!bPage) 107 { 108 aSet.Put(SwFmtHoriOrient(rItem.lLeft + nCol * rItem.lHDist, 109 text::HoriOrientation::NONE, text::RelOrientation::PAGE_FRAME )); 110 aSet.Put(SwFmtVertOrient(rItem.lUpper + nRow * rItem.lVDist, 111 text::VertOrientation::NONE, text::RelOrientation::PAGE_FRAME )); 112 } 113 if ( nCol == rItem.nCols -1 ) 114 { 115 aSet.Put( SvxLRSpaceItem( 0, 0, 0, 0, RES_LR_SPACE ) ); 116 } 117 const SwFrmFmt *pFmt = rSh.NewFlyFrm(aSet, sal_True, &rFmt ); // Fly einfuegen 118 ASSERT( pFmt, "Fly not inserted" ); 119 120 rSh.UnSelectFrm(); //Rahmen wurde automatisch selektiert 121 122 rSh.SetTxtFmtColl( rSh.GetTxtCollFromPool( RES_POOLCOLL_STANDARD ) ); 123 124 // 125 if(!rItem.bSynchron || !(nCol|nRow)) 126 { 127 SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); 128 DBG_ASSERT(pFact, "Dialogdiet fail!"); 129 ::GlossarySetActGroup fnSetActGroup = pFact->SetGlossaryActGroupFunc( DLG_RENAME_GLOS ); 130 if ( fnSetActGroup ) 131 (*fnSetActGroup)( rItem.sGlossaryGroup ); 132 SwGlossaryHdl* pGlosHdl = rSh.GetView().GetGlosHdl(); 133 pGlosHdl->SetCurGroup(rItem.sGlossaryGroup, sal_True); 134 pGlosHdl->InsertGlossary( rItem.sGlossaryBlockName ); 135 } 136 137 return pFmt; 138 } 139 140 const SwFrmFmt *lcl_InsertLabText( SwWrtShell& rSh, const SwLabItem& rItem, 141 SwFrmFmt &rFmt, SwFldMgr& rFldMgr, 142 sal_uInt16 nCol, sal_uInt16 nRow, sal_Bool bLast, sal_Bool bPage) 143 { 144 SfxItemSet aSet(rSh.GetAttrPool(), RES_ANCHOR, RES_ANCHOR, 145 RES_VERT_ORIENT, RES_VERT_ORIENT, RES_HORI_ORIENT, RES_HORI_ORIENT, 146 RES_LR_SPACE, RES_LR_SPACE, 0 ); 147 sal_uInt16 nPhyPageNum, nVirtPageNum; 148 rSh.GetPageNum( nPhyPageNum, nVirtPageNum ); 149 150 aSet.Put(SwFmtAnchor(bPage ? FLY_AS_CHAR : FLY_AT_PAGE, nPhyPageNum)); 151 if (!bPage) 152 { 153 aSet.Put(SwFmtHoriOrient(rItem.lLeft + nCol * rItem.lHDist, 154 text::HoriOrientation::NONE, text::RelOrientation::PAGE_FRAME )); 155 aSet.Put(SwFmtVertOrient(rItem.lUpper + nRow * rItem.lVDist, 156 text::VertOrientation::NONE, text::RelOrientation::PAGE_FRAME )); 157 } 158 if ( nCol == rItem.nCols -1 ) 159 { 160 aSet.Put( SvxLRSpaceItem( 0, 0, 0, 0, RES_LR_SPACE ) ); 161 } 162 const SwFrmFmt *pFmt = rSh.NewFlyFrm(aSet, sal_True, &rFmt ); // Fly einfuegen 163 ASSERT( pFmt, "Fly not inserted" ); 164 165 rSh.UnSelectFrm(); //Rahmen wurde automatisch selektiert 166 167 rSh.SetTxtFmtColl( rSh.GetTxtCollFromPool( RES_POOLCOLL_STANDARD ) ); 168 169 // Ggf. "Naechster Datensatz" 170 String sDBName; 171 if( (!rItem.bSynchron || !(nCol|nRow)) && (sDBName = InsertLabEnvText( rSh, rFldMgr, rItem.aWriting )).Len() && !bLast ) 172 { 173 sDBName.SetToken( 3, DB_DELIM, String::CreateFromAscii("True")); 174 SwInsertFld_Data aData(TYP_DBNEXTSETFLD, 0, sDBName, aEmptyStr, 0, &rSh ); 175 rFldMgr.InsertFld( aData ); 176 } 177 178 return pFmt; 179 } 180 181 // ---------------------------------------------------------------------------- 182 183 184 void SwModule::InsertLab(SfxRequest& rReq, sal_Bool bLabel) 185 { 186 static sal_uInt16 nLabelTitleNo = 0; 187 static sal_uInt16 nBCTitleNo = 0; 188 189 // DB-Manager anlegen 190 SwNewDBMgr* pNewDBMgr = new SwNewDBMgr; 191 192 // SwLabItem aus Config lesen 193 SwLabCfgItem aLabCfg(bLabel); 194 195 // Dialog hochfahren 196 SfxItemSet aSet( GetPool(), FN_LABEL, FN_LABEL, 0 ); 197 aSet.Put( aLabCfg.GetItem() ); 198 199 SwAbstractDialogFactory* pDialogFactory = SwAbstractDialogFactory::Create(); 200 DBG_ASSERT(pDialogFactory, "SwAbstractDialogFactory fail!"); 201 202 AbstarctSwLabDlg* pDlg = pDialogFactory->CreateSwLabDlg( 0, aSet, pNewDBMgr, bLabel, DLG_LAB ); 203 DBG_ASSERT(pDlg, "Dialogdiet fail!"); 204 205 if ( RET_OK == pDlg->Execute() ) 206 { 207 // Dialog auslesen, Item in Config speichern 208 const SwLabItem& rItem = (const SwLabItem&) pDlg-> 209 GetOutputItemSet()->Get(FN_LABEL); 210 aLabCfg.GetItem() = rItem; 211 aLabCfg.Commit(); 212 213 // Neues Dokument erzeugen. 214 SfxObjectShellLock xDocSh( new SwDocShell( SFX_CREATE_MODE_STANDARD)); 215 xDocSh->DoInitNew( 0 ); 216 217 // Drucker 218 Printer *pPrt = pDlg->GetPrt(); 219 if (pPrt) 220 { 221 SwDocShell *pDocSh = (SwDocShell*)(&*xDocSh); 222 pDocSh->getIDocumentDeviceAccess()->setJobsetup(pPrt->GetJobSetup()); 223 } 224 225 SfxViewFrame* pViewFrame = SfxViewFrame::DisplayNewDocument( *xDocSh, rReq ); 226 227 SwView *pNewView = (SwView*) pViewFrame->GetViewShell(); 228 pNewView->AttrChangedNotify( &pNewView->GetWrtShell() );//Damit SelectShell gerufen wird. 229 230 // Dokumenttitel setzen 231 String aTmp; 232 if(bLabel) 233 { 234 aTmp = String(SW_RES( STR_LAB_TITLE)); 235 aTmp += String::CreateFromInt32(++nLabelTitleNo ); 236 } 237 else 238 { 239 aTmp = pDlg->GetBusinessCardStr(); 240 aTmp += String::CreateFromInt32( ++nBCTitleNo ); 241 } 242 xDocSh->SetTitle( aTmp ); 243 244 pViewFrame->GetFrame().Appear(); 245 246 // Shell ermitteln 247 SwWrtShell *pSh = pNewView->GetWrtShellPtr(); 248 ASSERT( pSh, "missing WrtShell" ); 249 250 { // block for locks the dispatcher!! 251 252 SwWait aWait( (SwDocShell&)*xDocSh, true ); 253 254 SET_CURR_SHELL(pSh); 255 pSh->SetLabelDoc(rItem.bSynchron); 256 pSh->DoUndo( sal_False ); 257 pSh->StartAllAction(); 258 259 pSh->SetNewDoc(); // Performanceprobleme vermeiden 260 261 SwPageDesc aDesc = pSh->GetPageDesc( 0 ); 262 SwFrmFmt& rFmt = aDesc.GetMaster(); 263 264 // Raender 265 SvxLRSpaceItem aLRMargin( RES_LR_SPACE ); 266 SvxULSpaceItem aULMargin( RES_UL_SPACE ); 267 aLRMargin.SetLeft ((sal_uInt16) rItem.lLeft ); 268 aULMargin.SetUpper((sal_uInt16) rItem.lUpper); 269 aLRMargin.SetRight(MINLAY/2); 270 aULMargin.SetLower(MINLAY/2); 271 rFmt.SetFmtAttr(aLRMargin); 272 rFmt.SetFmtAttr(aULMargin); 273 274 // Kopf- und Fusszeilen 275 rFmt.SetFmtAttr(SwFmtHeader(sal_Bool(sal_False))); 276 aDesc.ChgHeaderShare(sal_False); 277 rFmt.SetFmtAttr(SwFmtFooter(sal_Bool(sal_False))); 278 aDesc.ChgFooterShare(sal_False); 279 280 281 aDesc.SetUseOn(nsUseOnPage::PD_ALL); // Seitennumerierung 282 283 // Einstellen der Seitengroesse 284 rFmt.SetFmtAttr(SwFmtFrmSize(ATT_FIX_SIZE, 285 rItem.lPaperWidth == 0 ? rItem.lLeft + rItem.nCols * rItem.lHDist + MINLAY : rItem.lPaperWidth, 286 rItem.bCont || rItem.lPaperHeight == 0 ? rItem.lUpper + rItem.nRows * rItem.lVDist + MINLAY : rItem.lPaperHeight)); 287 288 // Numerierungsart 289 SvxNumberType aType; 290 aType.SetNumberingType(SVX_NUM_NUMBER_NONE); 291 aDesc.SetNumType( aType ); 292 293 // Folgevorlage 294 const SwPageDesc &rFollow = pSh->GetPageDesc( pSh->GetCurPageDesc() ); 295 aDesc.SetFollow( &rFollow ); 296 297 pPrt = pSh->getIDocumentDeviceAccess()->getPrinter( true ); 298 SvxPaperBinItem aItem( RES_PAPER_BIN ); 299 aItem.SetValue((sal_Int8)pPrt->GetPaperBin()); 300 rFmt.SetFmtAttr(aItem); 301 302 //determine orientation by calculating the width and height of the resulting page 303 const int nResultWidth = rItem.lHDist * (rItem.nCols - 1) + rItem.lWidth + rItem.lLeft; 304 const int nResultHeight = rItem.lVDist * (rItem.nRows - 1) + rItem.lHeight + rItem.lUpper; 305 aDesc.SetLandscape(nResultWidth > nResultHeight); 306 307 pSh->ChgPageDesc( 0, aDesc ); 308 309 // Rahmen einfuegen 310 SwFldMgr* pFldMgr = new SwFldMgr; 311 pFldMgr->SetEvalExpFlds(sal_False); 312 313 //fix(24446): Damit der Text der Ettiketten nicht im unbedruckbaren 314 //Bereich landet stellen wir entsprechende Raender ein. Um das Handling 315 //so Optimal wie moeglich zu halten stellen wir zunaechst an der 316 //aktuellen Absatzvorlage keinen Rand als hartes Attribut ein (Damit die 317 //Formatierung wg. der Zeichengeb. Rahmen passt. Dann stellen wir die 318 //Standarabsatzvorlage anhand des unbedruckbaren Bereiches ein. 319 const long nMin = pPrt->GetPageOffset().X() - rItem.lLeft; 320 if ( nMin > 0 ) 321 { 322 SvxLRSpaceItem aLR( RES_LR_SPACE ); 323 pSh->SetAttrItem( aLR ); 324 SwFmt *pStandard = pSh->GetTxtCollFromPool( RES_POOLCOLL_STANDARD ); 325 aLR.SetLeft ( sal_uInt16(nMin) ); 326 aLR.SetRight( sal_uInt16(nMin) ); 327 pStandard->SetFmtAttr( aLR ); 328 } 329 330 // Rahmenvorlage vorbereiten 331 SwFrmFmt* pFmt = pSh->GetFrmFmtFromPool( RES_POOLFRM_LABEL ); 332 SwFmtFrmSize aFrmSize( ATT_FIX_SIZE, 333 rItem.lHDist - (rItem.lHDist-rItem.lWidth), 334 rItem.lVDist - (rItem.lVDist-rItem.lHeight)); 335 pFmt->SetFmtAttr(aFrmSize); 336 337 SvxLRSpaceItem aFrmLRSpace( 0, (sal_uInt16)(rItem.lHDist - rItem.lWidth), 338 0, 0, 339 RES_LR_SPACE); 340 pFmt->SetFmtAttr(aFrmLRSpace); 341 342 SvxULSpaceItem aFrmULSpace( 0, (sal_uInt16)(rItem.lVDist - rItem.lHeight), 343 RES_UL_SPACE); 344 pFmt->SetFmtAttr(aFrmULSpace); 345 346 const SwFrmFmt *pFirstFlyFmt = 0; 347 if ( rItem.bPage ) 348 { 349 SwFmtVertOrient aFrmVertOrient( pFmt->GetVertOrient() ); 350 aFrmVertOrient.SetVertOrient( text::VertOrientation::TOP ); 351 pFmt->SetFmtAttr(aFrmVertOrient); 352 353 for ( sal_uInt16 i = 0; i < rItem.nRows; ++i ) 354 { 355 for ( sal_uInt16 j = 0; j < rItem.nCols; ++j ) 356 { 357 pSh->Push(); 358 const SwFrmFmt *pTmp = 359 bLabel ? 360 lcl_InsertLabText( *pSh, rItem, *pFmt, *pFldMgr, j, i, 361 i == rItem.nRows - 1 && j == rItem.nCols - 1, 362 sal_True ) : 363 lcl_InsertBCText(*pSh, rItem, *pFmt, j, i, sal_True); 364 if (!(i|j)) 365 { 366 pFirstFlyFmt = pTmp; 367 368 if (rItem.bSynchron) 369 { 370 // if there is no content in the fly then 371 // dont leave the fly!!! 372 pSh->Push(); 373 pSh->SttDoc(); 374 sal_Bool bInFly = 0 != pSh->WizzardGetFly(); 375 pSh->Pop( bInFly ); 376 377 if( bInFly ) 378 pSh->EndDoc(sal_True); // select all content 379 // in the fly 380 else 381 pSh->SetMark(); // set only the mark 382 383 SwSectionData aSect(CONTENT_SECTION, 384 String::CreateFromAscii(MASTER_LABEL)); 385 pSh->InsertSection(aSect); 386 } 387 } 388 else if (rItem.bSynchron) 389 { 390 SwSectionData aSect(FILE_LINK_SECTION, 391 pSh->GetUniqueSectionName()); 392 String sLinkName(sfx2::cTokenSeperator); 393 sLinkName += sfx2::cTokenSeperator; 394 sLinkName += String::CreateFromAscii(MASTER_LABEL); 395 aSect.SetLinkFileName(sLinkName); 396 aSect.SetProtectFlag(true); 397 pSh->Insert(aDotStr); // Dummytext zum Zuweisen der Section 398 pSh->SttDoc(); 399 pSh->EndDoc(sal_True); // Alles im Rahmen selektieren 400 pSh->InsertSection(aSect); 401 } 402 pSh->Pop( sal_False ); 403 } 404 if ( i + 1 != rItem.nRows ) 405 pSh->SplitNode(); // Kleine Optimierung 406 } 407 } 408 else 409 { 410 pFirstFlyFmt = bLabel ? 411 lcl_InsertLabText( *pSh, rItem, *pFmt, *pFldMgr, 412 static_cast< sal_uInt16 >(rItem.nCol - 1), 413 static_cast< sal_uInt16 >(rItem.nRow - 1), sal_True, sal_False ) : 414 lcl_InsertBCText(*pSh, rItem, *pFmt, 415 static_cast< sal_uInt16 >(rItem.nCol - 1), 416 static_cast< sal_uInt16 >(rItem.nRow - 1), sal_False); 417 } 418 419 //fill the user fields 420 if(!bLabel) 421 { 422 uno::Reference< frame::XModel > xModel = pSh->GetView().GetDocShell()->GetBaseModel(); 423 DBG_ASSERT(pDialogFactory, "SwAbstractDialogFactory fail!"); 424 SwLabDlgMethod SwLabDlgUpdateFieldInformation = pDialogFactory->GetSwLabDlgStaticMethod (); 425 SwLabDlgUpdateFieldInformation(xModel, rItem); 426 } 427 428 pFldMgr->SetEvalExpFlds(sal_True); 429 pFldMgr->EvalExpFlds(pSh); 430 431 delete pFldMgr; 432 433 pSh->GotoFly(pFirstFlyFmt->GetName(), FLYCNTTYPE_ALL, sal_False); 434 435 pSh->EndAllAction(); 436 pSh->DoUndo( sal_True ); 437 } 438 439 if( rItem.aWriting.indexOf( '<' ) >= 0 ) 440 { 441 // Datenbankbrowser mit zuletzt verwendeter Datenbank oeffnen 442 ShowDBObj( *pNewView, pSh->GetDBData() ); 443 } 444 445 if( rItem.bSynchron ) 446 { 447 SfxDispatcher* pDisp = pViewFrame->GetDispatcher(); 448 ASSERT(pDisp, "Heute kein Dispatcher am Frame?"); 449 pDisp->Execute(FN_SYNC_LABELS, SFX_CALLMODE_ASYNCHRON); 450 } 451 rReq.SetReturnValue(SfxVoidItem(bLabel ? FN_LABEL : FN_BUSINESS_CARD)); 452 } 453 delete pDlg; 454 455 if( pNewDBMgr ) 456 delete pNewDBMgr; 457 } 458