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