Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include <cstdarg>
22 :
23 : #include <hintids.hxx>
24 :
25 : #include <vcl/svapp.hxx>
26 : #include <vcl/wrkwin.hxx>
27 : #include <vcl/msgbox.hxx>
28 : #include <sfx2/app.hxx>
29 : #include <sfx2/dispatch.hxx>
30 : #include <sfx2/printer.hxx>
31 : #include <sfx2/request.hxx>
32 : #include <sfx2/linkmgr.hxx>
33 : #include <editeng/pbinitem.hxx>
34 : #include <editeng/ulspitem.hxx>
35 : #include <editeng/lrspitem.hxx>
36 : #include <editeng/boxitem.hxx>
37 : #include <editeng/paperinf.hxx>
38 : #include <editeng/protitem.hxx>
39 : #include <com/sun/star/frame/XStorable.hpp>
40 : #include <com/sun/star/frame/XModel.hpp>
41 : #include <fmthdft.hxx>
42 : #include <fmtanchr.hxx>
43 : #include <fmtfsize.hxx>
44 : #include <fmtornt.hxx>
45 : #include <swwait.hxx>
46 : #include <gloshdl.hxx>
47 : #include <mdiexp.hxx>
48 : #include <frmatr.hxx>
49 : #include <paratr.hxx>
50 : #include <swmodule.hxx>
51 : #include <view.hxx>
52 : #include <docsh.hxx>
53 : #include <fldbas.hxx>
54 : #include <swundo.hxx>
55 : #include <wrtsh.hxx>
56 : #include <cmdid.h>
57 : #include <dbmgr.hxx>
58 : #include <fmtcol.hxx>
59 : #include <expfld.hxx>
60 : #include <fldmgr.hxx>
61 : #include <label.hxx>
62 : #include <labimg.hxx>
63 : #include <section.hxx>
64 : #include <pagedesc.hxx>
65 : #include <poolfmt.hxx>
66 :
67 : #include <app.hrc>
68 : #include <poolfmt.hrc>
69 : #include "swabstdlg.hxx"
70 : #include "envelp.hrc"
71 : #include <misc.hrc>
72 :
73 : #include <IDocumentDeviceAccess.hxx>
74 :
75 : using namespace ::com::sun::star;
76 :
77 : // is in appenv.cxx
78 : extern String InsertLabEnvText( SwWrtShell& , SwFldMgr& , const String& );
79 :
80 : const char MASTER_LABEL[] = "MasterLabel";
81 :
82 0 : static const SwFrmFmt *lcl_InsertBCText( SwWrtShell& rSh, const SwLabItem& rItem,
83 : SwFrmFmt &rFmt,
84 : sal_uInt16 nCol, sal_uInt16 nRow )
85 : {
86 0 : SfxItemSet aSet(rSh.GetAttrPool(), RES_ANCHOR, RES_ANCHOR,
87 0 : RES_VERT_ORIENT, RES_VERT_ORIENT, RES_HORI_ORIENT, RES_HORI_ORIENT, 0 );
88 : sal_uInt16 nPhyPageNum, nVirtPageNum;
89 0 : rSh.GetPageNum( nPhyPageNum, nVirtPageNum );
90 :
91 : //anchor frame to page
92 0 : aSet.Put( SwFmtAnchor( FLY_AT_PAGE, nPhyPageNum ) );
93 0 : aSet.Put( SwFmtHoriOrient( rItem.lLeft + nCol * rItem.lHDist,
94 0 : text::HoriOrientation::NONE, text::RelOrientation::PAGE_FRAME ) );
95 0 : aSet.Put( SwFmtVertOrient( rItem.lUpper + nRow * rItem.lVDist,
96 0 : text::VertOrientation::NONE, text::RelOrientation::PAGE_FRAME ) );
97 0 : const SwFrmFmt *pFmt = rSh.NewFlyFrm(aSet, sal_True, &rFmt ); // Insert Fly
98 : OSL_ENSURE( pFmt, "Fly not inserted" );
99 :
100 0 : rSh.UnSelectFrm(); //Frame was selected automatically
101 :
102 0 : rSh.SetTxtFmtColl( rSh.GetTxtCollFromPool( RES_POOLCOLL_STANDARD ) );
103 :
104 0 : if(!rItem.bSynchron || !(nCol|nRow))
105 : {
106 0 : SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
107 : OSL_ENSURE(pFact, "Dialogdiet fail!");
108 0 : ::GlossarySetActGroup fnSetActGroup = pFact->SetGlossaryActGroupFunc();
109 0 : if ( fnSetActGroup )
110 0 : (*fnSetActGroup)( rItem.sGlossaryGroup );
111 0 : SwGlossaryHdl* pGlosHdl = rSh.GetView().GetGlosHdl();
112 0 : pGlosHdl->SetCurGroup(rItem.sGlossaryGroup, sal_True);
113 0 : pGlosHdl->InsertGlossary( rItem.sGlossaryBlockName );
114 : }
115 :
116 0 : return pFmt;
117 : }
118 :
119 0 : static const SwFrmFmt *lcl_InsertLabText( SwWrtShell& rSh, const SwLabItem& rItem,
120 : SwFrmFmt &rFmt, SwFldMgr& rFldMgr,
121 : sal_uInt16 nCol, sal_uInt16 nRow, sal_Bool bLast )
122 : {
123 0 : SfxItemSet aSet(rSh.GetAttrPool(), RES_ANCHOR, RES_ANCHOR,
124 0 : RES_VERT_ORIENT, RES_VERT_ORIENT, RES_HORI_ORIENT, RES_HORI_ORIENT, 0 );
125 : sal_uInt16 nPhyPageNum, nVirtPageNum;
126 0 : rSh.GetPageNum( nPhyPageNum, nVirtPageNum );
127 :
128 : //anchor frame to page
129 0 : aSet.Put( SwFmtAnchor( FLY_AT_PAGE, nPhyPageNum ) );
130 0 : aSet.Put( SwFmtHoriOrient( rItem.lLeft + nCol * rItem.lHDist,
131 0 : text::HoriOrientation::NONE, text::RelOrientation::PAGE_FRAME ) );
132 0 : aSet.Put( SwFmtVertOrient( rItem.lUpper + nRow * rItem.lVDist,
133 0 : text::VertOrientation::NONE, text::RelOrientation::PAGE_FRAME ) );
134 0 : const SwFrmFmt *pFmt = rSh.NewFlyFrm(aSet, sal_True, &rFmt ); // Insert Fly
135 : OSL_ENSURE( pFmt, "Fly not inserted" );
136 :
137 0 : rSh.UnSelectFrm(); //Frame was selected automatically
138 :
139 0 : rSh.SetTxtFmtColl( rSh.GetTxtCollFromPool( RES_POOLCOLL_STANDARD ) );
140 :
141 : // If applicable "next dataset"
142 0 : String sDBName;
143 0 : if( (!rItem.bSynchron || !(nCol|nRow)) && (sDBName = InsertLabEnvText( rSh, rFldMgr, rItem.aWriting )).Len() && !bLast )
144 : {
145 0 : sDBName.SetToken( 3, DB_DELIM, OUString("True"));
146 0 : SwInsertFld_Data aData(TYP_DBNEXTSETFLD, 0, sDBName, aEmptyStr, 0, &rSh );
147 0 : rFldMgr.InsertFld( aData );
148 : }
149 :
150 0 : return pFmt;
151 : }
152 :
153 0 : void SwModule::InsertLab(SfxRequest& rReq, sal_Bool bLabel)
154 : {
155 : static sal_uInt16 nLabelTitleNo = 0;
156 : static sal_uInt16 nBCTitleNo = 0;
157 :
158 : // Create DB-Manager
159 0 : SwNewDBMgr* pNewDBMgr = new SwNewDBMgr;
160 :
161 : // Read SwLabItem from Config
162 0 : SwLabCfgItem aLabCfg(bLabel);
163 :
164 : // Move up Dialog
165 0 : SfxItemSet aSet( GetPool(), FN_LABEL, FN_LABEL, 0 );
166 0 : aSet.Put( aLabCfg.GetItem() );
167 :
168 0 : SwAbstractDialogFactory* pDialogFactory = SwAbstractDialogFactory::Create();
169 : OSL_ENSURE(pDialogFactory, "SwAbstractDialogFactory fail!");
170 :
171 0 : AbstractSwLabDlg* pDlg = pDialogFactory->CreateSwLabDlg( 0, aSet, pNewDBMgr, bLabel, DLG_LAB );
172 : OSL_ENSURE(pDlg, "Dialogdiet fail!");
173 :
174 0 : if ( RET_OK == pDlg->Execute() )
175 : {
176 : // Read dialog, store item in config
177 : const SwLabItem& rItem = (const SwLabItem&) pDlg->
178 0 : GetOutputItemSet()->Get(FN_LABEL);
179 0 : aLabCfg.GetItem() = rItem;
180 0 : aLabCfg.Commit();
181 :
182 : // Create new document
183 0 : SfxObjectShellLock xDocSh( new SwDocShell( SFX_CREATE_MODE_STANDARD));
184 0 : xDocSh->DoInitNew( 0 );
185 :
186 : // Printer
187 0 : Printer *pPrt = pDlg->GetPrt();
188 0 : if (pPrt)
189 : {
190 0 : SwDocShell *pDocSh = (SwDocShell*)(&*xDocSh);
191 0 : pDocSh->getIDocumentDeviceAccess()->setJobsetup(pPrt->GetJobSetup());
192 : }
193 :
194 0 : SfxViewFrame* pViewFrame = SfxViewFrame::DisplayNewDocument( *xDocSh, rReq );
195 :
196 0 : SwView *pNewView = (SwView*) pViewFrame->GetViewShell();
197 0 : pNewView->AttrChangedNotify( &pNewView->GetWrtShell() );// So that SelectShell is being called.
198 :
199 : // Set document title
200 0 : String aTmp;
201 0 : if(bLabel)
202 : {
203 0 : aTmp = String(SW_RES( STR_LAB_TITLE));
204 0 : aTmp += OUString::number(++nLabelTitleNo );
205 : }
206 : else
207 : {
208 0 : aTmp = pDlg->GetBusinessCardStr();
209 0 : aTmp += OUString::number( ++nBCTitleNo );
210 : }
211 0 : xDocSh->SetTitle( aTmp );
212 :
213 0 : pViewFrame->GetFrame().Appear();
214 :
215 : // Determine Shell
216 0 : SwWrtShell *pSh = pNewView->GetWrtShellPtr();
217 : OSL_ENSURE( pSh, "missing WrtShell" );
218 :
219 : { // block for locks the dispatcher!!
220 :
221 0 : SwWait aWait( (SwDocShell&)*xDocSh, sal_True );
222 :
223 0 : SET_CURR_SHELL(pSh);
224 0 : pSh->SetLabelDoc(rItem.bSynchron);
225 0 : pSh->DoUndo( sal_False );
226 0 : pSh->StartAllAction();
227 :
228 0 : pSh->SetNewDoc(); // Avoid performance problems
229 :
230 0 : SwPageDesc aDesc = pSh->GetPageDesc( 0 );
231 0 : SwFrmFmt& rFmt = aDesc.GetMaster();
232 :
233 : // Borders
234 0 : SvxLRSpaceItem aLRMargin( RES_LR_SPACE );
235 0 : SvxULSpaceItem aULMargin( RES_UL_SPACE );
236 0 : aLRMargin.SetLeft ((sal_uInt16) rItem.lLeft );
237 0 : aULMargin.SetUpper((sal_uInt16) rItem.lUpper);
238 0 : aLRMargin.SetRight( 0 );
239 0 : aULMargin.SetLower( 0 );
240 0 : rFmt.SetFmtAttr(aLRMargin);
241 0 : rFmt.SetFmtAttr(aULMargin);
242 :
243 : // Header and footer
244 0 : rFmt.SetFmtAttr(SwFmtHeader(sal_Bool(sal_False)));
245 0 : aDesc.ChgHeaderShare(sal_False);
246 0 : rFmt.SetFmtAttr(SwFmtFooter(sal_Bool(sal_False)));
247 0 : aDesc.ChgFooterShare(sal_False);
248 :
249 :
250 0 : aDesc.SetUseOn(nsUseOnPage::PD_ALL); // Site numbering
251 :
252 : // Set page size
253 : long lPgWidth, lPgHeight;
254 0 : lPgWidth = (rItem.lPWidth > MINLAY ? rItem.lPWidth : MINLAY);
255 0 : lPgHeight = (rItem.lPHeight > MINLAY ? rItem.lPHeight : MINLAY);
256 0 : rFmt.SetFmtAttr( SwFmtFrmSize( ATT_FIX_SIZE, lPgWidth, lPgHeight ));
257 : // Numbering type
258 0 : SvxNumberType aType;
259 0 : aType.SetNumberingType(SVX_NUM_NUMBER_NONE);
260 0 : aDesc.SetNumType( aType );
261 :
262 : // Followup template
263 0 : const SwPageDesc &rFollow = pSh->GetPageDesc( pSh->GetCurPageDesc() );
264 0 : aDesc.SetFollow( &rFollow );
265 :
266 0 : pPrt = pSh->getIDocumentDeviceAccess()->getPrinter( true );
267 0 : SvxPaperBinItem aItem( RES_PAPER_BIN );
268 0 : aItem.SetValue((sal_Int8)pPrt->GetPaperBin());
269 0 : rFmt.SetFmtAttr(aItem);
270 :
271 : // Determine orientation of the resulting page
272 0 : aDesc.SetLandscape(rItem.lPWidth > rItem.lPHeight);
273 :
274 0 : pSh->ChgPageDesc( 0, aDesc );
275 :
276 : // Insert frame
277 0 : SwFldMgr* pFldMgr = new SwFldMgr;
278 0 : pFldMgr->SetEvalExpFlds(sal_False);
279 :
280 : // Prepare border template
281 0 : SwFrmFmt* pFmt = pSh->GetFrmFmtFromPool( RES_POOLFRM_LABEL );
282 0 : sal_Int32 iResultWidth = rItem.lLeft + (rItem.nCols - 1) * rItem.lHDist + rItem.lWidth - rItem.lPWidth;
283 0 : sal_Int32 iResultHeight = rItem.lUpper + (rItem.nRows - 1) * rItem.lVDist + rItem.lHeight - rItem.lPHeight;
284 0 : sal_Int32 iWidth = (iResultWidth > 0 ? rItem.lWidth - (iResultWidth / rItem.nCols) - 1 : rItem.lWidth);
285 0 : sal_Int32 iHeight = (iResultHeight > 0 ? rItem.lHeight - (iResultHeight / rItem.nRows) - 1 : rItem.lHeight);
286 0 : SwFmtFrmSize aFrmSize( ATT_FIX_SIZE, iWidth, iHeight );
287 0 : pFmt->SetFmtAttr( aFrmSize );
288 :
289 : //frame represents label itself, no border space
290 0 : SvxULSpaceItem aFrmNoULSpace( 0, 0, RES_UL_SPACE );
291 0 : SvxLRSpaceItem aFrmNoLRSpace( 0, 0, 0, 0, RES_LR_SPACE );
292 0 : pFmt->SetFmtAttr( aFrmNoULSpace );
293 0 : pFmt->SetFmtAttr( aFrmNoLRSpace );
294 :
295 0 : const SwFrmFmt *pFirstFlyFmt = 0;
296 0 : if ( rItem.bPage )
297 : {
298 0 : SwFmtVertOrient aFrmVertOrient( pFmt->GetVertOrient() );
299 0 : aFrmVertOrient.SetVertOrient( text::VertOrientation::TOP );
300 0 : pFmt->SetFmtAttr(aFrmVertOrient);
301 :
302 0 : for ( sal_uInt16 i = 0; i < rItem.nRows; ++i )
303 : {
304 0 : for ( sal_uInt16 j = 0; j < rItem.nCols; ++j )
305 : {
306 0 : pSh->Push();
307 : const SwFrmFmt *pTmp = ( bLabel ?
308 : lcl_InsertLabText( *pSh, rItem, *pFmt, *pFldMgr, j, i,
309 0 : i == rItem.nRows - 1 && j == rItem.nCols - 1 ) :
310 0 : lcl_InsertBCText( *pSh, rItem, *pFmt, j, i ) );
311 0 : if (!(i|j))
312 : {
313 0 : pFirstFlyFmt = pTmp;
314 :
315 0 : if (rItem.bSynchron)
316 : {
317 : // if there is no content in the fly then
318 : // dont leave the fly!!!
319 0 : pSh->Push();
320 0 : pSh->SttDoc();
321 0 : sal_Bool bInFly = 0 != pSh->WizzardGetFly();
322 0 : pSh->Pop( bInFly );
323 :
324 0 : if( bInFly )
325 0 : pSh->EndDoc(sal_True); // select all content
326 : // in the fly
327 : else
328 0 : pSh->SetMark(); // set only the mark
329 :
330 : SwSectionData aSect(CONTENT_SECTION,
331 0 : OUString(MASTER_LABEL));
332 0 : pSh->InsertSection(aSect);
333 : }
334 : }
335 0 : else if (rItem.bSynchron)
336 : {
337 : SwSectionData aSect(FILE_LINK_SECTION,
338 0 : pSh->GetUniqueSectionName());
339 0 : OUStringBuffer sLinkName;
340 0 : sLinkName.append(sfx2::cTokenSeparator);
341 0 : sLinkName.append(sfx2::cTokenSeparator);
342 0 : sLinkName.append(MASTER_LABEL);
343 0 : aSect.SetLinkFileName(sLinkName.makeStringAndClear());
344 0 : aSect.SetProtectFlag(true);
345 0 : pSh->Insert(aDotStr); // Dummytext to allocate the Section
346 0 : pSh->SttDoc();
347 0 : pSh->EndDoc(sal_True); // Select everything in the frame
348 0 : pSh->InsertSection(aSect);
349 : }
350 0 : pSh->Pop( sal_False );
351 : }
352 0 : }
353 : }
354 : else
355 : {
356 : pFirstFlyFmt = bLabel ?
357 : lcl_InsertLabText( *pSh, rItem, *pFmt, *pFldMgr,
358 : static_cast< sal_uInt16 >(rItem.nCol - 1),
359 0 : static_cast< sal_uInt16 >(rItem.nRow - 1), sal_True ) :
360 : lcl_InsertBCText(*pSh, rItem, *pFmt,
361 : static_cast< sal_uInt16 >(rItem.nCol - 1),
362 0 : static_cast< sal_uInt16 >(rItem.nRow - 1));
363 : }
364 :
365 : //fill the user fields
366 0 : if(!bLabel)
367 : {
368 0 : uno::Reference< frame::XModel > xModel = pSh->GetView().GetDocShell()->GetBaseModel();
369 : OSL_ENSURE(pDialogFactory, "SwAbstractDialogFactory fail!");
370 0 : SwLabDlgMethod SwLabDlgUpdateFieldInformation = pDialogFactory->GetSwLabDlgStaticMethod ();
371 0 : SwLabDlgUpdateFieldInformation(xModel, rItem);
372 : }
373 :
374 0 : pFldMgr->SetEvalExpFlds(sal_True);
375 0 : pFldMgr->EvalExpFlds(pSh);
376 :
377 0 : delete pFldMgr;
378 :
379 0 : pSh->GotoFly(pFirstFlyFmt->GetName(), FLYCNTTYPE_ALL, sal_False);
380 :
381 0 : pSh->EndAllAction();
382 0 : pSh->DoUndo( sal_True );
383 : }
384 :
385 0 : if( rItem.aWriting.indexOf( '<' ) >= 0 )
386 : {
387 : // Open database browser on recently used database
388 0 : ShowDBObj( *pNewView, pSh->GetDBData() );
389 : }
390 :
391 0 : if( rItem.bSynchron )
392 : {
393 0 : SfxDispatcher* pDisp = pViewFrame->GetDispatcher();
394 : OSL_ENSURE(pDisp, "No dispatcher in frame?");
395 0 : pDisp->Execute(FN_SYNC_LABELS, SFX_CALLMODE_ASYNCHRON);
396 : }
397 0 : rReq.SetReturnValue(SfxVoidItem(bLabel ? FN_LABEL : FN_BUSINESS_CARD));
398 : }
399 0 : delete pDlg;
400 0 : delete pNewDBMgr;
401 99 : }
402 :
403 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|