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