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