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