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 <cstdarg>
21 :
22 : #include <hintids.hxx>
23 :
24 : #include <comphelper/string.hxx>
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 : #include <boost/scoped_ptr.hpp>
76 :
77 : using namespace ::com::sun::star;
78 :
79 : // is in appenv.cxx
80 : extern OUString InsertLabEnvText( SwWrtShell& , SwFldMgr& , const OUString& );
81 :
82 : const char MASTER_LABEL[] = "MasterLabel";
83 :
84 0 : static const SwFrmFmt *lcl_InsertBCText( SwWrtShell& rSh, const SwLabItem& rItem,
85 : SwFrmFmt &rFmt,
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( SwFmtAnchor( FLY_AT_PAGE, nPhyPageNum ) );
95 0 : aSet.Put( SwFmtHoriOrient( rItem.lLeft + nCol * rItem.lHDist,
96 0 : text::HoriOrientation::NONE, text::RelOrientation::PAGE_FRAME ) );
97 0 : aSet.Put( SwFmtVertOrient( rItem.lUpper + nRow * rItem.lVDist,
98 0 : text::VertOrientation::NONE, text::RelOrientation::PAGE_FRAME ) );
99 0 : const SwFrmFmt *pFmt = rSh.NewFlyFrm(aSet, sal_True, &rFmt ); // Insert Fly
100 : OSL_ENSURE( pFmt, "Fly not inserted" );
101 :
102 0 : rSh.UnSelectFrm(); //Frame was selected automatically
103 :
104 0 : rSh.SetTxtFmtColl( rSh.GetTxtCollFromPool( RES_POOLCOLL_STANDARD ) );
105 :
106 0 : if(!rItem.bSynchron || !(nCol|nRow))
107 : {
108 0 : SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
109 : OSL_ENSURE(pFact, "Dialogdiet fail!");
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, sal_True);
115 0 : pGlosHdl->InsertGlossary( rItem.sGlossaryBlockName );
116 : }
117 :
118 0 : return pFmt;
119 : }
120 :
121 0 : static const SwFrmFmt *lcl_InsertLabText( SwWrtShell& rSh, const SwLabItem& rItem,
122 : SwFrmFmt &rFmt, SwFldMgr& rFldMgr,
123 : sal_uInt16 nCol, sal_uInt16 nRow, sal_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( SwFmtAnchor( FLY_AT_PAGE, nPhyPageNum ) );
132 0 : aSet.Put( SwFmtHoriOrient( rItem.lLeft + nCol * rItem.lHDist,
133 0 : text::HoriOrientation::NONE, text::RelOrientation::PAGE_FRAME ) );
134 0 : aSet.Put( SwFmtVertOrient( rItem.lUpper + nRow * rItem.lVDist,
135 0 : text::VertOrientation::NONE, text::RelOrientation::PAGE_FRAME ) );
136 0 : const SwFrmFmt *pFmt = rSh.NewFlyFrm(aSet, sal_True, &rFmt ); // Insert Fly
137 : OSL_ENSURE( pFmt, "Fly not inserted" );
138 :
139 0 : rSh.UnSelectFrm(); //Frame was selected automatically
140 :
141 0 : rSh.SetTxtFmtColl( rSh.GetTxtCollFromPool( RES_POOLCOLL_STANDARD ) );
142 :
143 : // If applicable "next dataset"
144 0 : OUString sDBName;
145 0 : if( (!rItem.bSynchron || !(nCol|nRow)) && !(sDBName = InsertLabEnvText( rSh, rFldMgr, rItem.aWriting )).isEmpty() && !bLast )
146 : {
147 0 : sDBName = comphelper::string::setToken(sDBName, 3, DB_DELIM, "True");
148 0 : SwInsertFld_Data aData(TYP_DBNEXTSETFLD, 0, sDBName, aEmptyOUStr, 0, &rSh );
149 0 : rFldMgr.InsertFld( aData );
150 : }
151 :
152 0 : return pFmt;
153 : }
154 :
155 0 : void SwModule::InsertLab(SfxRequest& rReq, sal_Bool bLabel)
156 : {
157 : static sal_uInt16 nLabelTitleNo = 0;
158 : static sal_uInt16 nBCTitleNo = 0;
159 :
160 : // Create DB-Manager
161 0 : boost::scoped_ptr<SwNewDBMgr> pNewDBMgr(new SwNewDBMgr);
162 :
163 : // Read SwLabItem from Config
164 0 : SwLabCfgItem aLabCfg(bLabel);
165 :
166 : // Move up Dialog
167 0 : SfxItemSet aSet( GetPool(), FN_LABEL, FN_LABEL, 0 );
168 0 : aSet.Put( aLabCfg.GetItem() );
169 :
170 0 : SwAbstractDialogFactory* pDialogFactory = SwAbstractDialogFactory::Create();
171 : OSL_ENSURE(pDialogFactory, "SwAbstractDialogFactory fail!");
172 :
173 0 : boost::scoped_ptr<AbstractSwLabDlg> pDlg(pDialogFactory->CreateSwLabDlg(0, aSet, pNewDBMgr.get(), bLabel));
174 : OSL_ENSURE(pDlg, "Dialogdiet fail!");
175 :
176 0 : if ( RET_OK == pDlg->Execute() )
177 : {
178 : // Read dialog, store item in config
179 0 : const SwLabItem& rItem = (const SwLabItem&) pDlg->
180 0 : GetOutputItemSet()->Get(FN_LABEL);
181 0 : aLabCfg.GetItem() = rItem;
182 0 : aLabCfg.Commit();
183 :
184 : // Create new document
185 0 : SfxObjectShellLock xDocSh( new SwDocShell( SFX_CREATE_MODE_STANDARD));
186 0 : xDocSh->DoInitNew( 0 );
187 :
188 : // Printer
189 0 : Printer *pPrt = pDlg->GetPrt();
190 0 : if (pPrt)
191 : {
192 0 : SwDocShell *pDocSh = (SwDocShell*)(&*xDocSh);
193 0 : pDocSh->getIDocumentDeviceAccess()->setJobsetup(pPrt->GetJobSetup());
194 : }
195 :
196 0 : SfxViewFrame* pViewFrame = SfxViewFrame::DisplayNewDocument( *xDocSh, rReq );
197 :
198 0 : SwView *pNewView = (SwView*) pViewFrame->GetViewShell();
199 0 : pNewView->AttrChangedNotify( &pNewView->GetWrtShell() );// So that SelectShell is being called.
200 :
201 : // Set document title
202 0 : OUString aTmp;
203 0 : if(bLabel)
204 : {
205 0 : aTmp = SW_RES( STR_LAB_TITLE);
206 0 : aTmp += OUString::number(++nLabelTitleNo );
207 : }
208 : else
209 : {
210 0 : aTmp = pDlg->GetBusinessCardStr();
211 0 : aTmp += OUString::number( ++nBCTitleNo );
212 : }
213 0 : xDocSh->SetTitle( aTmp );
214 :
215 0 : pViewFrame->GetFrame().Appear();
216 :
217 : // Determine Shell
218 0 : SwWrtShell *pSh = pNewView->GetWrtShellPtr();
219 : OSL_ENSURE( pSh, "missing WrtShell" );
220 :
221 : { // block for locks the dispatcher!!
222 :
223 0 : SwWait aWait( (SwDocShell&)*xDocSh, true );
224 :
225 0 : SET_CURR_SHELL(pSh);
226 0 : pSh->SetLabelDoc(rItem.bSynchron);
227 0 : pSh->DoUndo( sal_False );
228 0 : pSh->StartAllAction();
229 :
230 0 : pSh->SetNewDoc(); // Avoid performance problems
231 :
232 0 : SwPageDesc aDesc = pSh->GetPageDesc( 0 );
233 0 : SwFrmFmt& rFmt = aDesc.GetMaster();
234 :
235 : // Borders
236 0 : SvxLRSpaceItem aLRMargin( RES_LR_SPACE );
237 0 : SvxULSpaceItem aULMargin( RES_UL_SPACE );
238 0 : aLRMargin.SetLeft ((sal_uInt16) rItem.lLeft );
239 0 : aULMargin.SetUpper((sal_uInt16) rItem.lUpper);
240 0 : aLRMargin.SetRight( 0 );
241 0 : aULMargin.SetLower( 0 );
242 0 : rFmt.SetFmtAttr(aLRMargin);
243 0 : rFmt.SetFmtAttr(aULMargin);
244 :
245 : // Header and footer
246 0 : rFmt.SetFmtAttr(SwFmtHeader(sal_Bool(sal_False)));
247 0 : aDesc.ChgHeaderShare(sal_False);
248 0 : rFmt.SetFmtAttr(SwFmtFooter(sal_Bool(sal_False)));
249 0 : aDesc.ChgFooterShare(sal_False);
250 :
251 0 : aDesc.SetUseOn(nsUseOnPage::PD_ALL); // Site numbering
252 :
253 : // Set page size
254 : long lPgWidth, lPgHeight;
255 0 : lPgWidth = (rItem.lPWidth > MINLAY ? rItem.lPWidth : MINLAY);
256 0 : lPgHeight = (rItem.lPHeight > MINLAY ? rItem.lPHeight : MINLAY);
257 0 : rFmt.SetFmtAttr( SwFmtFrmSize( ATT_FIX_SIZE, lPgWidth, lPgHeight ));
258 : // Numbering type
259 0 : SvxNumberType aType;
260 0 : aType.SetNumberingType(SVX_NUM_NUMBER_NONE);
261 0 : aDesc.SetNumType( aType );
262 :
263 : // Followup template
264 0 : const SwPageDesc &rFollow = pSh->GetPageDesc( pSh->GetCurPageDesc() );
265 0 : aDesc.SetFollow( &rFollow );
266 :
267 0 : pPrt = pSh->getIDocumentDeviceAccess()->getPrinter( true );
268 0 : SvxPaperBinItem aItem( RES_PAPER_BIN );
269 0 : aItem.SetValue((sal_Int8)pPrt->GetPaperBin());
270 0 : rFmt.SetFmtAttr(aItem);
271 :
272 : // Determine orientation of the resulting page
273 0 : aDesc.SetLandscape(rItem.lPWidth > rItem.lPHeight);
274 :
275 0 : pSh->ChgPageDesc( 0, aDesc );
276 :
277 : // Insert frame
278 0 : boost::scoped_ptr<SwFldMgr> pFldMgr(new SwFldMgr);
279 0 : pFldMgr->SetEvalExpFlds(sal_False);
280 :
281 : // Prepare border template
282 0 : SwFrmFmt* pFmt = pSh->GetFrmFmtFromPool( RES_POOLFRM_LABEL );
283 0 : sal_Int32 iResultWidth = rItem.lLeft + (rItem.nCols - 1) * rItem.lHDist + rItem.lWidth - rItem.lPWidth;
284 0 : sal_Int32 iResultHeight = rItem.lUpper + (rItem.nRows - 1) * rItem.lVDist + rItem.lHeight - rItem.lPHeight;
285 0 : sal_Int32 iWidth = (iResultWidth > 0 ? rItem.lWidth - (iResultWidth / rItem.nCols) - 1 : rItem.lWidth);
286 0 : sal_Int32 iHeight = (iResultHeight > 0 ? rItem.lHeight - (iResultHeight / rItem.nRows) - 1 : rItem.lHeight);
287 0 : SwFmtFrmSize aFrmSize( ATT_FIX_SIZE, iWidth, iHeight );
288 0 : pFmt->SetFmtAttr( aFrmSize );
289 :
290 : //frame represents label itself, no border space
291 0 : SvxULSpaceItem aFrmNoULSpace( 0, 0, RES_UL_SPACE );
292 0 : SvxLRSpaceItem aFrmNoLRSpace( 0, 0, 0, 0, RES_LR_SPACE );
293 0 : pFmt->SetFmtAttr( aFrmNoULSpace );
294 0 : pFmt->SetFmtAttr( aFrmNoLRSpace );
295 :
296 0 : const SwFrmFmt *pFirstFlyFmt = 0;
297 0 : if ( rItem.bPage )
298 : {
299 0 : SwFmtVertOrient aFrmVertOrient( pFmt->GetVertOrient() );
300 0 : aFrmVertOrient.SetVertOrient( text::VertOrientation::TOP );
301 0 : pFmt->SetFmtAttr(aFrmVertOrient);
302 :
303 0 : for ( sal_uInt16 i = 0; i < rItem.nRows; ++i )
304 : {
305 0 : for ( sal_uInt16 j = 0; j < rItem.nCols; ++j )
306 : {
307 0 : pSh->Push();
308 : const SwFrmFmt *pTmp = ( bLabel ?
309 0 : lcl_InsertLabText( *pSh, rItem, *pFmt, *pFldMgr, j, i,
310 0 : i == rItem.nRows - 1 && j == rItem.nCols - 1 ) :
311 0 : lcl_InsertBCText( *pSh, rItem, *pFmt, j, i ) );
312 0 : if (!(i|j))
313 : {
314 0 : pFirstFlyFmt = pTmp;
315 :
316 0 : if (rItem.bSynchron)
317 : {
318 : // if there is no content in the fly then
319 : // dont leave the fly!!!
320 0 : pSh->Push();
321 0 : pSh->SttDoc();
322 0 : sal_Bool bInFly = 0 != pSh->WizzardGetFly();
323 0 : pSh->Pop( bInFly );
324 :
325 0 : if( bInFly )
326 0 : pSh->EndDoc(sal_True); // select all content
327 : // in the fly
328 : else
329 0 : pSh->SetMark(); // set only the mark
330 :
331 : SwSectionData aSect(CONTENT_SECTION,
332 0 : OUString(MASTER_LABEL));
333 0 : pSh->InsertSection(aSect);
334 : }
335 : }
336 0 : else if (rItem.bSynchron)
337 : {
338 : SwSectionData aSect(FILE_LINK_SECTION,
339 0 : pSh->GetUniqueSectionName());
340 0 : OUStringBuffer sLinkName;
341 0 : sLinkName.append(sfx2::cTokenSeparator);
342 0 : sLinkName.append(sfx2::cTokenSeparator);
343 0 : sLinkName.append(MASTER_LABEL);
344 0 : aSect.SetLinkFileName(sLinkName.makeStringAndClear());
345 0 : aSect.SetProtectFlag(true);
346 0 : pSh->Insert("."); // Dummytext to allocate the Section
347 0 : pSh->SttDoc();
348 0 : pSh->EndDoc(sal_True); // Select everything in the frame
349 0 : pSh->InsertSection(aSect);
350 : }
351 0 : pSh->Pop( sal_False );
352 : }
353 0 : }
354 : }
355 : else
356 : {
357 : pFirstFlyFmt = bLabel ?
358 0 : lcl_InsertLabText( *pSh, rItem, *pFmt, *pFldMgr,
359 : static_cast< sal_uInt16 >(rItem.nCol - 1),
360 0 : static_cast< sal_uInt16 >(rItem.nRow - 1), sal_True ) :
361 : lcl_InsertBCText(*pSh, rItem, *pFmt,
362 : static_cast< sal_uInt16 >(rItem.nCol - 1),
363 0 : static_cast< sal_uInt16 >(rItem.nRow - 1));
364 : }
365 :
366 : //fill the user fields
367 0 : if(!bLabel)
368 : {
369 0 : uno::Reference< frame::XModel > xModel = pSh->GetView().GetDocShell()->GetBaseModel();
370 : OSL_ENSURE(pDialogFactory, "SwAbstractDialogFactory fail!");
371 0 : SwLabDlgMethod SwLabDlgUpdateFieldInformation = pDialogFactory->GetSwLabDlgStaticMethod ();
372 0 : SwLabDlgUpdateFieldInformation(xModel, rItem);
373 : }
374 :
375 0 : pFldMgr->SetEvalExpFlds(sal_True);
376 0 : pFldMgr->EvalExpFlds(pSh);
377 :
378 0 : pFldMgr.reset();
379 :
380 0 : if (pFirstFlyFmt)
381 0 : pSh->GotoFly(pFirstFlyFmt->GetName(), FLYCNTTYPE_ALL, sal_False);
382 :
383 0 : pSh->EndAllAction();
384 0 : pSh->DoUndo( sal_True );
385 : }
386 :
387 0 : if( rItem.aWriting.indexOf( '<' ) >= 0 )
388 : {
389 : // Open database browser on recently used database
390 0 : ShowDBObj( *pNewView, pSh->GetDBData() );
391 : }
392 :
393 0 : if( rItem.bSynchron )
394 : {
395 0 : SfxDispatcher* pDisp = pViewFrame->GetDispatcher();
396 : OSL_ENSURE(pDisp, "No dispatcher in frame?");
397 0 : pDisp->Execute(FN_SYNC_LABELS, SFX_CALLMODE_ASYNCHRON);
398 : }
399 0 : rReq.SetReturnValue(SfxVoidItem(bLabel ? FN_LABEL : FN_BUSINESS_CARD));
400 0 : }
401 0 : }
402 :
403 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|