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