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 <swtypes.hxx>
21 : #include <mmlayoutpage.hxx>
22 : #include <mailmergewizard.hxx>
23 : #include <mmconfigitem.hxx>
24 : #include <mailmergehelper.hxx>
25 : #include <unotools.hxx>
26 : #include <comphelper/string.hxx>
27 : #include <unotools/tempfile.hxx>
28 : #include <uitool.hxx>
29 : #include <svx/dlgutil.hxx>
30 : #include <view.hxx>
31 : #include <swundo.hxx>
32 : #include <sfx2/dispatch.hxx>
33 : #include <svl/stritem.hxx>
34 : #include <sfx2/docfilt.hxx>
35 : #include <com/sun/star/text/XParagraphCursor.hpp>
36 : #include <com/sun/star/view/XViewSettingsSupplier.hpp>
37 : #include <com/sun/star/view/DocumentZoomType.hpp>
38 : #include <fldmgr.hxx>
39 : #include <fldbas.hxx>
40 : #include <poolfmt.hxx>
41 : #include <unotxdoc.hxx>
42 : #include <docsh.hxx>
43 : #include <doc.hxx>
44 : #include <wrtsh.hxx>
45 : #include <fmtsrnd.hxx>
46 : #include <pagedesc.hxx>
47 : #include <fmtanchr.hxx>
48 : #include <fmtornt.hxx>
49 : #include <fmtfsize.hxx>
50 : #include <editeng/boxitem.hxx>
51 : #include <svl/urihelper.hxx>
52 : #include <shellio.hxx>
53 : #include <osl/file.hxx>
54 : #include <unoprnms.hxx>
55 :
56 : #include <mmlayoutpage.hrc>
57 : #include <dbui.hrc>
58 : #include <unomid.h>
59 :
60 : using namespace osl;
61 : using namespace svt;
62 : using namespace ::com::sun::star;
63 : using namespace ::com::sun::star::uno;
64 : using namespace ::com::sun::star::text;
65 : using namespace ::com::sun::star::frame;
66 : using namespace ::com::sun::star::lang;
67 : using namespace ::com::sun::star::view;
68 :
69 : #define DEFAULT_LEFT_DISTANCE (MM50*5) // 2,5 cm
70 : #define DEFAULT_TOP_DISTANCE (MM50*11) // 5,5 cm
71 : #define GREETING_TOP_DISTANCE (MM50*25) //12,5 cm
72 : #define DEFAULT_ADDRESS_WIDTH (MM50*15)// 7,5 cm
73 : #define DEFAULT_ADDRESS_HEIGHT (MM50*7) // 3,5cm
74 :
75 0 : SwMailMergeLayoutPage::SwMailMergeLayoutPage( SwMailMergeWizard* _pParent) :
76 : svt::OWizardPage( _pParent, SW_RES(DLG_MM_LAYOUT_PAGE)),
77 : #ifdef _MSC_VER
78 : #pragma warning (disable : 4355)
79 : #endif
80 : m_aHeaderFI( this, SW_RES( FI_HEADER )),
81 : m_aPositionFL( this, SW_RES( FL_POSITION )),
82 : m_aAlignToBodyCB( this, SW_RES( CB_ALIGN )),
83 : m_aLeftFT( this, SW_RES( FT_LEFT )),
84 : m_aLeftMF( this, SW_RES( MF_LEFT )),
85 : m_aTopFT( this, SW_RES( FT_TOP )),
86 : m_aTopMF( this, SW_RES( MF_TOP )),
87 : m_aGreetingLineFL( this, SW_RES( FL_GREETINGLINE )),
88 : m_aUpFT( this, SW_RES( FT_UP )),
89 : m_aUpPB( this, SW_RES( MF_UP )),
90 : m_aDownFT( this, SW_RES( FT_DOWN )),
91 : m_aDownPB( this, SW_RES( PB_DOWN )),
92 : m_aExampleContainerWIN( this, SW_RES( WIN_EXAMPLECONTAINER )),
93 : m_aZoomFT( this, SW_RES( FT_ZOOM )),
94 : m_aZoomLB( this, SW_RES( LB_ZOOM )),
95 : #ifdef _MSC_VER
96 : #pragma warning (default : 4355)
97 : #endif
98 : m_pExampleFrame(0),
99 : m_pExampleWrtShell(0),
100 : m_pAddressBlockFormat(0),
101 : m_bIsGreetingInserted(false),
102 0 : m_pWizard(_pParent)
103 : {
104 0 : FreeResource();
105 :
106 : const SfxFilter *pSfxFlt = SwIoSystem::GetFilterOfFormat(
107 : OUString( FILTER_XML ),
108 0 : SwDocShell::Factory().GetFilterContainer() );
109 : //save the current document into a temporary file
110 : {
111 : //temp file needs it's own block
112 : //creating with extension is not supported by a static method :-(
113 : OUString const sExt(
114 0 : comphelper::string::stripStart(pSfxFlt->GetDefaultExtension(),'*'));
115 0 : utl::TempFile aTempFile( OUString(), &sExt );
116 0 : m_sExampleURL = aTempFile.GetURL();
117 0 : aTempFile.EnableKillingFile();
118 : }
119 0 : SwView* pView = m_pWizard->GetSwView();
120 0 : uno::Sequence< beans::PropertyValue > aValues(1);
121 0 : beans::PropertyValue* pValues = aValues.getArray();
122 0 : pValues[0].Name = "FilterName";
123 0 : pValues[0].Value <<= OUString(pSfxFlt->GetFilterName());
124 :
125 0 : uno::Reference< frame::XStorable > xStore( pView->GetDocShell()->GetModel(), uno::UNO_QUERY);
126 0 : xStore->storeToURL( m_sExampleURL, aValues );
127 :
128 0 : Link aLink(LINK(this, SwMailMergeLayoutPage, PreviewLoadedHdl_Impl));
129 : m_pExampleFrame = new SwOneExampleFrame( m_aExampleContainerWIN,
130 0 : EX_SHOW_DEFAULT_PAGE, &aLink, &m_sExampleURL );
131 :
132 0 : m_aExampleContainerWIN.Show(false);
133 :
134 0 : m_aLeftMF.SetValue(m_aLeftMF.Normalize(DEFAULT_LEFT_DISTANCE), FUNIT_TWIP);
135 0 : m_aTopMF.SetValue(m_aTopMF.Normalize(DEFAULT_TOP_DISTANCE), FUNIT_TWIP);
136 :
137 0 : m_aZoomLB.InsertEntry(OUString("50 %"), 1);
138 0 : m_aZoomLB.InsertEntry(OUString("75 %"), 2);
139 0 : m_aZoomLB.InsertEntry(OUString("100 %"), 3);
140 0 : m_aZoomLB.SelectEntryPos(0); //page size
141 0 : m_aZoomLB.SetSelectHdl(LINK(this, SwMailMergeLayoutPage, ZoomHdl_Impl));
142 :
143 0 : Link aFrameHdl = LINK(this, SwMailMergeLayoutPage, ChangeAddressHdl_Impl);
144 0 : m_aLeftMF.SetUpHdl(aFrameHdl);
145 0 : m_aLeftMF.SetDownHdl(aFrameHdl);
146 0 : m_aLeftMF.SetLoseFocusHdl(aFrameHdl);
147 0 : m_aTopMF.SetUpHdl(aFrameHdl);
148 0 : m_aTopMF.SetDownHdl(aFrameHdl);
149 0 : m_aTopMF.SetLoseFocusHdl(aFrameHdl);
150 :
151 0 : FieldUnit eFieldUnit = ::GetDfltMetric(sal_False);
152 0 : ::SetFieldUnit( m_aLeftMF, eFieldUnit );
153 0 : ::SetFieldUnit( m_aTopMF, eFieldUnit );
154 :
155 0 : Link aUpDownHdl = LINK(this, SwMailMergeLayoutPage, GreetingsHdl_Impl );
156 0 : m_aUpPB.SetClickHdl(aUpDownHdl);
157 0 : m_aDownPB.SetClickHdl(aUpDownHdl);
158 0 : m_aAlignToBodyCB.SetClickHdl(LINK(this, SwMailMergeLayoutPage, AlignToTextHdl_Impl));
159 0 : m_aAlignToBodyCB.Check();
160 0 : }
161 :
162 0 : SwMailMergeLayoutPage::~SwMailMergeLayoutPage()
163 : {
164 0 : delete m_pExampleFrame;
165 0 : File::remove( m_sExampleURL );
166 :
167 0 : }
168 :
169 0 : void SwMailMergeLayoutPage::ActivatePage()
170 : {
171 0 : SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
172 0 : sal_Bool bGreetingLine = rConfigItem.IsGreetingLine(sal_False) && !rConfigItem.IsGreetingInserted();
173 0 : sal_Bool bAddressBlock = rConfigItem.IsAddressBlock() && !rConfigItem.IsAddressInserted();
174 :
175 0 : m_aPositionFL.Enable(bAddressBlock);
176 0 : m_aLeftFT.Enable(bAddressBlock);
177 0 : m_aTopFT.Enable(bAddressBlock);
178 0 : m_aLeftMF.Enable(bAddressBlock);
179 0 : m_aTopMF.Enable(bAddressBlock);
180 0 : AlignToTextHdl_Impl( &m_aAlignToBodyCB );
181 :
182 0 : m_aGreetingLineFL.Enable(bGreetingLine);
183 0 : m_aUpPB.Enable(bGreetingLine);
184 0 : m_aDownPB.Enable(bGreetingLine);
185 0 : m_aUpFT.Enable(bGreetingLine);
186 0 : m_aDownFT.Enable(bGreetingLine);
187 :
188 : //check if greeting and/or address frame have to be inserted/removed
189 0 : if(m_pExampleWrtShell) // initially there's nothing to check
190 : {
191 0 : if(!rConfigItem.IsGreetingInserted() &&
192 0 : m_bIsGreetingInserted != (0 != bGreetingLine) )
193 : {
194 0 : if( m_bIsGreetingInserted )
195 : {
196 0 : m_pExampleWrtShell->DelFullPara();
197 0 : m_bIsGreetingInserted = false;
198 : }
199 : else
200 : {
201 0 : InsertGreeting(*m_pExampleWrtShell, m_pWizard->GetConfigItem(), true);
202 0 : m_bIsGreetingInserted = true;
203 : }
204 : }
205 0 : if(!rConfigItem.IsAddressInserted() &&
206 0 : rConfigItem.IsAddressBlock() != ( 0 != m_pAddressBlockFormat ))
207 : {
208 0 : if( m_pAddressBlockFormat )
209 : {
210 0 : m_pExampleWrtShell->Push();
211 0 : m_pExampleWrtShell->GotoFly( m_pAddressBlockFormat->GetName() );
212 0 : m_pExampleWrtShell->DelRight();
213 0 : m_pAddressBlockFormat = 0;
214 0 : m_pExampleWrtShell->Pop(sal_False);
215 : }
216 : else
217 : {
218 0 : long nLeft = static_cast< long >(m_aLeftMF.Denormalize(m_aLeftMF.GetValue(FUNIT_TWIP)));
219 0 : long nTop = static_cast< long >(m_aTopMF.Denormalize(m_aTopMF.GetValue(FUNIT_TWIP)));
220 : m_pAddressBlockFormat = InsertAddressFrame(
221 0 : *m_pExampleWrtShell, m_pWizard->GetConfigItem(),
222 : Point(nLeft, nTop),
223 0 : m_aAlignToBodyCB.IsChecked(), true);
224 : }
225 : }
226 :
227 : }
228 0 : }
229 :
230 0 : sal_Bool SwMailMergeLayoutPage::commitPage( ::svt::WizardTypes::CommitPageReason _eReason )
231 : {
232 : //now insert the frame and the greeting
233 0 : SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
234 0 : if(::svt::WizardTypes::eTravelForward == _eReason)
235 : {
236 0 : long nLeft = static_cast< long >(m_aLeftMF.Denormalize(m_aLeftMF.GetValue(FUNIT_TWIP)));
237 0 : long nTop = static_cast< long >(m_aTopMF.Denormalize(m_aTopMF.GetValue(FUNIT_TWIP)));
238 : InsertAddressAndGreeting(
239 : m_pWizard->GetSwView(),
240 : rConfigItem,
241 : Point(nLeft, nTop),
242 0 : m_aAlignToBodyCB.IsChecked());
243 : }
244 0 : return sal_True;
245 : }
246 :
247 0 : SwFrmFmt* SwMailMergeLayoutPage::InsertAddressAndGreeting(SwView* pView,
248 : SwMailMergeConfigItem& rConfigItem,
249 : const Point& rAddressPosition,
250 : bool bAlignToBody)
251 : {
252 0 : SwFrmFmt* pAddressBlockFormat = 0;
253 0 : pView->GetWrtShell().StartUndo(UNDO_INSERT);
254 0 : if(rConfigItem.IsAddressBlock() && !rConfigItem.IsAddressInserted())
255 : {
256 : //insert the frame
257 0 : Point aAddressPosition(DEFAULT_LEFT_DISTANCE, DEFAULT_TOP_DISTANCE);
258 0 : if(rAddressPosition.X() > 0 && rAddressPosition.Y() > 0)
259 0 : aAddressPosition = rAddressPosition;
260 0 : pAddressBlockFormat = InsertAddressFrame( pView->GetWrtShell(),
261 : rConfigItem,
262 0 : aAddressPosition, bAlignToBody, false);
263 0 : rConfigItem.SetAddressInserted(pAddressBlockFormat->GetName());
264 : }
265 : //now the greeting
266 0 : if(rConfigItem.IsGreetingLine(sal_False) && !rConfigItem.IsGreetingInserted())
267 : {
268 0 : InsertGreeting( pView->GetWrtShell(), rConfigItem, false);
269 0 : rConfigItem.SetGreetingInserted();
270 : }
271 0 : pView->GetWrtShell().EndUndo(UNDO_INSERT);
272 0 : return pAddressBlockFormat;
273 : }
274 :
275 0 : SwFrmFmt* SwMailMergeLayoutPage::InsertAddressFrame(
276 : SwWrtShell& rShell,
277 : SwMailMergeConfigItem& rConfigItem,
278 : const Point& rDestination,
279 : bool bAlignLeft,
280 : bool bExample)
281 : {
282 : // insert the address block and the greeting line
283 0 : SfxItemSet aSet(rShell.GetAttrPool(), RES_ANCHOR, RES_ANCHOR,
284 : RES_VERT_ORIENT, RES_VERT_ORIENT,
285 : RES_HORI_ORIENT, RES_HORI_ORIENT,
286 : RES_BOX, RES_BOX,
287 : RES_FRM_SIZE, RES_FRM_SIZE,
288 : RES_SURROUND, RES_SURROUND,
289 0 : 0 );
290 0 : aSet.Put(SwFmtAnchor(FLY_AT_PAGE, 1));
291 0 : if(bAlignLeft)
292 0 : aSet.Put(SwFmtHoriOrient( 0, text::HoriOrientation::NONE, text::RelOrientation::PAGE_PRINT_AREA ));
293 : else
294 0 : aSet.Put(SwFmtHoriOrient( rDestination.X(), text::HoriOrientation::NONE, text::RelOrientation::PAGE_FRAME ));
295 0 : aSet.Put(SwFmtVertOrient( rDestination.Y(), text::VertOrientation::NONE, text::RelOrientation::PAGE_FRAME ));
296 0 : aSet.Put(SwFmtFrmSize( ATT_MIN_SIZE, DEFAULT_ADDRESS_WIDTH, DEFAULT_ADDRESS_HEIGHT ));
297 : // the example gets a border around the frame, the real document doesn't get one
298 0 : if(!bExample)
299 0 : aSet.Put(SvxBoxItem( RES_BOX ));
300 0 : aSet.Put(SwFmtSurround( SURROUND_NONE ));
301 :
302 0 : rShell.NewFlyFrm(aSet, sal_True );
303 0 : SwFrmFmt* pRet = rShell.GetFlyFrmFmt();
304 : OSL_ENSURE( pRet, "Fly not inserted" );
305 :
306 0 : rShell.UnSelectFrm();
307 0 : const Sequence< OUString> aBlocks = rConfigItem.GetAddressBlocks();
308 0 : if(bExample)
309 : {
310 0 : rShell.Insert(aBlocks[0]);
311 : }
312 : else
313 : {
314 : //the placeholders should be replaced by the appropriate fields
315 0 : SwFldMgr aFldMgr(&rShell);
316 : //create a database string source.command.commandtype.column
317 0 : const SwDBData& rData = rConfigItem.GetCurrentDBData();
318 0 : String sDBName(rData.sDataSource);
319 0 : sDBName += DB_DELIM;
320 0 : sDBName += String(rData.sCommand);
321 0 : sDBName += DB_DELIM;
322 0 : String sDatabaseConditionPrefix(sDBName);
323 0 : sDatabaseConditionPrefix.SearchAndReplaceAll(DB_DELIM, '.');
324 0 : sDBName += OUString::number(rData.nCommandType);
325 0 : sDBName += DB_DELIM;
326 :
327 : // if only the country is in an address line the
328 : // paragraph has to be hidden depending on the
329 : // IsIncludeCountry()/GetExcludeCountry() settings
330 :
331 0 : sal_Bool bIncludeCountry = rConfigItem.IsIncludeCountry();
332 0 : sal_Bool bHideEmptyParagraphs = rConfigItem.IsHideEmptyParagraphs();
333 0 : const OUString rExcludeCountry = rConfigItem.GetExcludeCountry();
334 0 : bool bSpecialReplacementForCountry = (!bIncludeCountry || !rExcludeCountry.isEmpty());
335 :
336 0 : const ResStringArray& rHeaders = rConfigItem.GetDefaultAddressHeaders();
337 0 : String sCountryColumn = rHeaders.GetString(MM_PART_COUNTRY);
338 : Sequence< OUString> aAssignment =
339 0 : rConfigItem.GetColumnAssignment( rConfigItem.GetCurrentDBData() );
340 0 : const OUString* pAssignment = aAssignment.getConstArray();
341 0 : if(aAssignment.getLength() > MM_PART_COUNTRY && !aAssignment[MM_PART_COUNTRY].isEmpty())
342 0 : sCountryColumn = aAssignment[MM_PART_COUNTRY];
343 : //
344 0 : String sHideParagraphsExpression;
345 0 : SwAddressIterator aIter(aBlocks[0]);
346 0 : while(aIter.HasMore())
347 : {
348 0 : SwMergeAddressItem aItem = aIter.Next();
349 0 : if(aItem.bIsColumn)
350 : {
351 0 : String sConvertedColumn = aItem.sText;
352 0 : for(sal_uInt16 nColumn = 0;
353 0 : nColumn < rHeaders.Count() && nColumn < aAssignment.getLength();
354 : ++nColumn)
355 : {
356 0 : if (rHeaders.GetString(nColumn).equals(aItem.sText) &&
357 0 : !pAssignment[nColumn].isEmpty())
358 : {
359 0 : sConvertedColumn = pAssignment[nColumn];
360 0 : break;
361 : }
362 : }
363 0 : String sDB(sDBName);
364 0 : sDB += sConvertedColumn;
365 :
366 0 : if(sHideParagraphsExpression.Len())
367 0 : sHideParagraphsExpression.AppendAscii(" AND ");
368 0 : sHideParagraphsExpression += '!';
369 0 : sHideParagraphsExpression += '[';
370 0 : sHideParagraphsExpression += sDatabaseConditionPrefix;
371 0 : sHideParagraphsExpression += sConvertedColumn;
372 0 : sHideParagraphsExpression += ']';
373 :
374 0 : if( bSpecialReplacementForCountry && sCountryColumn == sConvertedColumn )
375 : {
376 : // now insert a hidden paragraph field
377 0 : String sExpression;
378 0 : if( !rExcludeCountry.isEmpty() )
379 : {
380 0 : sExpression = sDatabaseConditionPrefix;
381 0 : sExpression.Insert('[', 0);
382 0 : sExpression += sCountryColumn;
383 0 : sExpression.AppendAscii("]");
384 :
385 0 : String sCondition(sExpression);
386 0 : sCondition.AppendAscii(" != \"");
387 0 : sCondition += String(rExcludeCountry);
388 0 : sCondition += '\"';
389 :
390 0 : SwInsertFld_Data aData(TYP_CONDTXTFLD, 0, sCondition, sExpression, 0, &rShell );
391 0 : aFldMgr.InsertFld( aData );
392 : }
393 : else
394 : {
395 0 : SwInsertFld_Data aData(TYP_HIDDENPARAFLD, 0, sExpression, aEmptyStr, 0, &rShell );
396 0 : aFldMgr.InsertFld( aData );
397 0 : }
398 : }
399 : else
400 : {
401 0 : SwInsertFld_Data aData(TYP_DBFLD, 0, sDB, aEmptyStr, 0, &rShell );
402 0 : aFldMgr.InsertFld( aData );
403 0 : }
404 : }
405 0 : else if(!aItem.bIsReturn)
406 : {
407 0 : rShell.Insert(aItem.sText);
408 : }
409 : else
410 : {
411 0 : if(bHideEmptyParagraphs)
412 : {
413 0 : SwInsertFld_Data aData(TYP_HIDDENPARAFLD, 0, sHideParagraphsExpression, aEmptyStr, 0, &rShell );
414 0 : aFldMgr.InsertFld( aData );
415 : }
416 0 : sHideParagraphsExpression.Erase();
417 : //now add a new paragraph
418 0 : rShell.SplitNode();
419 : }
420 0 : }
421 0 : if(bHideEmptyParagraphs && sHideParagraphsExpression.Len())
422 : {
423 0 : SwInsertFld_Data aData(TYP_HIDDENPARAFLD, 0, sHideParagraphsExpression, aEmptyStr, 0, &rShell );
424 0 : aFldMgr.InsertFld( aData );
425 0 : }
426 : }
427 0 : return pRet;
428 : }
429 :
430 0 : void SwMailMergeLayoutPage::InsertGreeting(SwWrtShell& rShell, SwMailMergeConfigItem& rConfigItem, bool bExample)
431 : {
432 : //set the cursor to the desired position - if no text content is here then
433 : //new paragraphs are inserted
434 0 : const SwRect& rPageRect = rShell.GetAnyCurRect(RECT_PAGE);
435 0 : const Point aGreetingPos( DEFAULT_LEFT_DISTANCE + rPageRect.Left(), GREETING_TOP_DISTANCE );
436 :
437 0 : const sal_Bool bRet = rShell.SetShadowCrsrPos( aGreetingPos, FILL_SPACE );
438 :
439 0 : if(!bRet)
440 : {
441 : //there's already text at the desired position
442 : //go to start of the doc, directly!
443 0 : rShell.SttEndDoc(sal_True);
444 : //and go by paragraph until the position is reached
445 0 : long nYPos = rShell.GetCharRect().Top();
446 0 : while(nYPos < GREETING_TOP_DISTANCE)
447 : {
448 0 : if(!rShell.FwdPara())
449 0 : break;
450 0 : nYPos = rShell.GetCharRect().Top();
451 : }
452 : //text needs to be appended
453 0 : while(nYPos < GREETING_TOP_DISTANCE)
454 : {
455 0 : if(!rShell.AppendTxtNode())
456 0 : break;
457 0 : nYPos = rShell.GetCharRect().Top();
458 : }
459 : }
460 : else
461 : {
462 : //we may end up inside of a paragraph if the left margin is not at DEFAULT_LEFT_DISTANCE
463 0 : rShell.MovePara(GetfnParaCurr(), GetfnParaStart());
464 : }
465 0 : bool bSplitNode = rShell.GetText().Len() > 0;
466 0 : sal_Int32 nMoves = rConfigItem.GetGreetingMoves();
467 0 : if( !bExample && 0 != nMoves )
468 : {
469 0 : if(nMoves < 0)
470 : {
471 0 : rShell.MoveParagraph( nMoves );
472 : }
473 : else
474 0 : while(nMoves)
475 : {
476 0 : bool bMoved = rShell.MoveParagraph( 1 );
477 0 : if(!bMoved)
478 : {
479 : //insert a new paragraph before the greeting line
480 0 : rShell.SplitNode();
481 : }
482 0 : --nMoves;
483 : }
484 : }
485 : //now insert the greeting text - if we have any?
486 0 : const sal_Bool bIndividual = rConfigItem.IsIndividualGreeting(sal_False);
487 0 : String sGreeting;
488 0 : if(bIndividual)
489 : {
490 : //lock expression fields - prevents hiding of the paragraph to insert into
491 0 : rShell.LockExpFlds();
492 0 : if(bExample)
493 : {
494 0 : for(sal_Int8 eGender = SwMailMergeConfigItem::FEMALE;
495 : eGender <= SwMailMergeConfigItem::NEUTRAL; ++eGender)
496 : {
497 : Sequence< OUString > aEntries =
498 0 : rConfigItem.GetGreetings((SwMailMergeConfigItem::Gender)eGender);
499 0 : sal_Int32 nCurrent = rConfigItem.GetCurrentGreeting((SwMailMergeConfigItem::Gender)eGender);
500 0 : if( nCurrent >= 0 && nCurrent < aEntries.getLength())
501 : {
502 0 : sGreeting = aEntries[nCurrent];
503 0 : rShell.Insert(sGreeting);
504 0 : break;
505 : }
506 0 : }
507 : }
508 : else
509 : {
510 0 : SwFldMgr aFldMgr(&rShell);
511 : //three paragraphs, each with an appropriate hidden paragraph field
512 : //are to be inserted
513 :
514 : //name of the gender column
515 0 : String sGenderColumn = rConfigItem.GetAssignedColumn(MM_PART_GENDER);
516 0 : String sNameColumn = rConfigItem.GetAssignedColumn(MM_PART_LASTNAME);
517 :
518 0 : const OUString& rFemaleGenderValue = rConfigItem.GetFemaleGenderValue();
519 0 : sal_Bool bHideEmptyParagraphs = rConfigItem.IsHideEmptyParagraphs();
520 0 : const SwDBData& rData = rConfigItem.GetCurrentDBData();
521 0 : String sConditionBase(rData.sDataSource);
522 0 : sConditionBase += '.';
523 0 : sConditionBase += String(rData.sCommand);
524 0 : sConditionBase += '.';
525 : //split the name column from here
526 0 : String sNameColumnBase(sConditionBase);
527 :
528 0 : sConditionBase += String(sGenderColumn);
529 0 : sConditionBase += ']';
530 0 : sConditionBase.Insert('[', 0);
531 :
532 0 : sNameColumnBase += String(sNameColumn);
533 0 : sNameColumnBase += ']';
534 0 : sNameColumnBase.Insert('[', 0);
535 :
536 0 : String sDBName(rData.sDataSource);
537 0 : sDBName += DB_DELIM;
538 0 : sDBName += String(rData.sCommand);
539 0 : sDBName += DB_DELIM;
540 0 : sDBName += OUString::number(rData.nCommandType);
541 0 : sDBName += DB_DELIM;
542 :
543 : // Female: [database.sGenderColumn] != "rFemaleGenderValue" && [database.NameColumn]
544 : // Male: [database.sGenderColumn] == "rFemaleGenderValue" && [database.rGenderColumn]
545 : // Neutral: [database.sNameColumn]
546 : OSL_ENSURE(sGenderColumn.Len() && !rFemaleGenderValue.isEmpty(),
547 : "gender settings not available - how to form the condition?");
548 : //column used as lastname
549 0 : for(sal_Int8 eGender = SwMailMergeConfigItem::FEMALE;
550 : eGender <= SwMailMergeConfigItem::NEUTRAL; ++eGender)
551 : {
552 0 : Sequence< OUString> aEntries = rConfigItem.GetGreetings((SwMailMergeConfigItem::Gender)eGender);
553 0 : sal_Int32 nCurrent = rConfigItem.GetCurrentGreeting((SwMailMergeConfigItem::Gender)eGender);
554 0 : if( nCurrent >= 0 && nCurrent < aEntries.getLength())
555 : {
556 0 : sGreeting = aEntries[nCurrent];
557 0 : String sCondition(sConditionBase);
558 0 : String sHideParagraphsExpression;
559 0 : switch(eGender)
560 : {
561 : case SwMailMergeConfigItem::FEMALE:
562 0 : sCondition.AppendAscii(" != \"");
563 0 : sCondition += String(rFemaleGenderValue);
564 0 : sCondition.AppendAscii("\" OR NOT ");
565 0 : sCondition += String(sNameColumnBase);
566 :
567 0 : sHideParagraphsExpression += '!';
568 0 : sHideParagraphsExpression += sNameColumnBase;
569 0 : break;
570 : case SwMailMergeConfigItem::MALE:
571 0 : sCondition.AppendAscii(" == \"");
572 0 : sCondition += String(rFemaleGenderValue);
573 0 : sCondition.AppendAscii("\" OR NOT ");
574 0 : sCondition += String(sNameColumnBase);
575 0 : break;
576 : case SwMailMergeConfigItem::NEUTRAL:
577 0 : sCondition = sNameColumnBase;
578 0 : break;
579 : }
580 :
581 0 : if(bHideEmptyParagraphs && sHideParagraphsExpression.Len())
582 : {
583 0 : String sComplete( sCondition );
584 0 : sComplete.Insert('(', 0);
585 0 : sComplete.AppendAscii( ") OR (");
586 0 : sComplete += sHideParagraphsExpression;
587 0 : sComplete += ')';
588 0 : SwInsertFld_Data aData(TYP_HIDDENPARAFLD, 0, sComplete, aEmptyStr, 0, &rShell );
589 0 : aFldMgr.InsertFld( aData );
590 : }
591 : else
592 : {
593 0 : SwInsertFld_Data aData(TYP_HIDDENPARAFLD, 0, sCondition, aEmptyStr, 0, &rShell );
594 0 : aFldMgr.InsertFld( aData );
595 : }
596 : //now the text has to be inserted
597 0 : const ResStringArray& rHeaders = rConfigItem.GetDefaultAddressHeaders();
598 : Sequence< OUString> aAssignment =
599 0 : rConfigItem.GetColumnAssignment( rConfigItem.GetCurrentDBData() );
600 0 : const OUString* pAssignment = aAssignment.getConstArray();
601 0 : SwAddressIterator aIter(sGreeting);
602 0 : while(aIter.HasMore())
603 : {
604 0 : SwMergeAddressItem aItem = aIter.Next();
605 0 : if(aItem.bIsColumn)
606 : {
607 0 : String sDB(sDBName);
608 0 : String sConvertedColumn = aItem.sText;
609 0 : for(sal_uInt16 nColumn = 0;
610 0 : nColumn < rHeaders.Count() && nColumn < aAssignment.getLength();
611 : ++nColumn)
612 : {
613 0 : if (rHeaders.GetString(nColumn).equals(aItem.sText) &&
614 0 : !pAssignment[nColumn].isEmpty())
615 : {
616 0 : sConvertedColumn = pAssignment[nColumn];
617 0 : break;
618 : }
619 : }
620 0 : sDB += sConvertedColumn;
621 0 : SwInsertFld_Data aData(TYP_DBFLD, 0, sDB, aEmptyStr, 0, &rShell );
622 0 : aFldMgr.InsertFld( aData );
623 : }
624 : else
625 : {
626 0 : rShell.Insert(aItem.sText);
627 : }
628 0 : }
629 : //now add a new paragraph
630 0 : rShell.SplitNode();
631 : }
632 0 : }
633 :
634 : }
635 0 : rShell.UnlockExpFlds();
636 : }
637 : else
638 : {
639 0 : Sequence< OUString> aEntries = rConfigItem.GetGreetings(SwMailMergeConfigItem::NEUTRAL);
640 0 : sal_Int32 nCurrent = rConfigItem.GetCurrentGreeting(SwMailMergeConfigItem::NEUTRAL);
641 0 : if( nCurrent >= 0 && nCurrent < aEntries.getLength())
642 0 : sGreeting = aEntries[nCurrent];
643 0 : rShell.Insert(sGreeting);
644 : }
645 : // now insert a new paragraph here if necessary
646 0 : if(bSplitNode)
647 : {
648 0 : rShell.Push();
649 0 : rShell.SplitNode();
650 0 : rShell.Pop(sal_False);
651 : }
652 : //put the cursor to the start of the paragraph
653 0 : rShell.SttPara();
654 :
655 0 : OSL_ENSURE(0 == rShell.GetTableFmt(), "What to do with a table here?");
656 0 : }
657 :
658 0 : IMPL_LINK_NOARG(SwMailMergeLayoutPage, PreviewLoadedHdl_Impl)
659 : {
660 0 : m_aExampleContainerWIN.Show(true);
661 :
662 0 : Reference< XModel > & xModel = m_pExampleFrame->GetModel();
663 : //now the ViewOptions should be set properly
664 0 : Reference< XViewSettingsSupplier > xSettings(xModel->getCurrentController(), UNO_QUERY);
665 0 : m_xViewProperties = xSettings->getViewSettings();
666 0 : Reference< XUnoTunnel > xDocTunnel(xModel, UNO_QUERY);
667 0 : SwXTextDocument* pXDoc = reinterpret_cast<SwXTextDocument*>(xDocTunnel->getSomething(SwXTextDocument::getUnoTunnelId()));
668 0 : SwDocShell* pDocShell = pXDoc->GetDocShell();
669 0 : m_pExampleWrtShell = pDocShell->GetWrtShell();
670 : OSL_ENSURE(m_pExampleWrtShell, "No SwWrtShell found!");
671 0 : if(!m_pExampleWrtShell)
672 0 : return 0;
673 :
674 0 : SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
675 0 : if(rConfigItem.IsAddressBlock())
676 : {
677 : m_pAddressBlockFormat = InsertAddressFrame(
678 : *m_pExampleWrtShell, rConfigItem,
679 : Point(DEFAULT_LEFT_DISTANCE, DEFAULT_TOP_DISTANCE),
680 0 : m_aAlignToBodyCB.IsChecked(), true);
681 : }
682 0 : if(rConfigItem.IsGreetingLine(sal_False))
683 : {
684 0 : InsertGreeting(*m_pExampleWrtShell, rConfigItem, true);
685 0 : m_bIsGreetingInserted = true;
686 : }
687 :
688 0 : Any aZoom;
689 0 : aZoom <<= (sal_Int16)DocumentZoomType::ENTIRE_PAGE;
690 0 : m_xViewProperties->setPropertyValue(OUString::createFromAscii(SW_PROP_NAME_STR(UNO_NAME_ZOOM_TYPE)), aZoom);
691 :
692 : const SwFmtFrmSize& rPageSize = m_pExampleWrtShell->GetPageDesc(
693 0 : m_pExampleWrtShell->GetCurPageDesc()).GetMaster().GetFrmSize();
694 0 : m_aLeftMF.SetMax(rPageSize.GetWidth() - DEFAULT_LEFT_DISTANCE);
695 0 : m_aTopMF.SetMax(rPageSize.GetHeight() - DEFAULT_TOP_DISTANCE);
696 0 : return 0;
697 : }
698 :
699 0 : IMPL_LINK(SwMailMergeLayoutPage, ZoomHdl_Impl, ListBox*, pBox)
700 : {
701 0 : if(m_pExampleWrtShell)
702 : {
703 0 : sal_Int16 eType = DocumentZoomType::BY_VALUE;
704 0 : short nZoom = 50;
705 0 : switch(pBox->GetSelectEntryPos())
706 : {
707 0 : case 0 : eType = DocumentZoomType::ENTIRE_PAGE; break;
708 0 : case 1 : nZoom = 50; break;
709 0 : case 2 : nZoom = 75; break;
710 0 : case 3 : nZoom = 100; break;
711 : }
712 0 : Any aZoom;
713 0 : aZoom <<= eType;
714 0 : m_xViewProperties->setPropertyValue(OUString::createFromAscii(SW_PROP_NAME_STR(UNO_NAME_ZOOM_TYPE)), aZoom);
715 0 : aZoom <<= nZoom;
716 0 : m_xViewProperties->setPropertyValue(OUString::createFromAscii(SW_PROP_NAME_STR(UNO_NAME_ZOOM_VALUE)), aZoom);
717 :
718 : }
719 0 : return 0;
720 : }
721 :
722 0 : IMPL_LINK_NOARG(SwMailMergeLayoutPage, ChangeAddressHdl_Impl)
723 : {
724 0 : if(m_pExampleWrtShell && m_pAddressBlockFormat)
725 : {
726 0 : long nLeft = static_cast< long >(m_aLeftMF.Denormalize(m_aLeftMF.GetValue(FUNIT_TWIP)));
727 0 : long nTop = static_cast< long >(m_aTopMF.Denormalize(m_aTopMF.GetValue(FUNIT_TWIP)));
728 :
729 0 : SfxItemSet aSet(m_pExampleWrtShell->GetAttrPool(), RES_ANCHOR, RES_ANCHOR,
730 : RES_VERT_ORIENT, RES_VERT_ORIENT,
731 : RES_HORI_ORIENT, RES_HORI_ORIENT,
732 0 : 0 );
733 0 : if(m_aAlignToBodyCB.IsChecked())
734 0 : aSet.Put(SwFmtHoriOrient( 0, text::HoriOrientation::NONE, text::RelOrientation::PAGE_PRINT_AREA ));
735 : else
736 0 : aSet.Put(SwFmtHoriOrient( nLeft, text::HoriOrientation::NONE, text::RelOrientation::PAGE_FRAME ));
737 0 : aSet.Put(SwFmtVertOrient( nTop, text::VertOrientation::NONE, text::RelOrientation::PAGE_FRAME ));
738 0 : m_pExampleWrtShell->GetDoc()->SetFlyFrmAttr( *m_pAddressBlockFormat, aSet );
739 : }
740 0 : return 0;
741 : }
742 :
743 0 : IMPL_LINK(SwMailMergeLayoutPage, GreetingsHdl_Impl, PushButton*, pButton)
744 : {
745 0 : bool bDown = pButton == &m_aDownPB;
746 0 : bool bMoved = m_pExampleWrtShell->MoveParagraph( bDown ? 1 : -1 );
747 0 : if (bMoved || bDown)
748 0 : m_pWizard->GetConfigItem().MoveGreeting(bDown ? 1 : -1 );
749 0 : if(!bMoved && bDown)
750 : {
751 : //insert a new paragraph before the greeting line
752 0 : m_pExampleWrtShell->SplitNode();
753 : }
754 :
755 0 : return 0;
756 : }
757 :
758 0 : IMPL_LINK(SwMailMergeLayoutPage, AlignToTextHdl_Impl, CheckBox*, pBox)
759 : {
760 0 : sal_Bool bCheck = pBox->IsChecked() && pBox->IsEnabled();
761 0 : m_aLeftFT.Enable(!bCheck);
762 0 : m_aLeftMF.Enable(!bCheck);
763 0 : ChangeAddressHdl_Impl( 0 );
764 0 : return 0;
765 0 : }
766 :
767 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|