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