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