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