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 : 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 : delete m_pExampleFrame;
159 0 : File::remove( m_sExampleURL );
160 :
161 0 : }
162 :
163 0 : void SwMailMergeLayoutPage::ActivatePage()
164 : {
165 0 : SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
166 0 : bool bGreetingLine = rConfigItem.IsGreetingLine(false) && !rConfigItem.IsGreetingInserted();
167 0 : bool bAddressBlock = rConfigItem.IsAddressBlock() && !rConfigItem.IsAddressInserted();
168 :
169 0 : m_pPosition->Enable(bAddressBlock);
170 0 : AlignToTextHdl_Impl(m_pAlignToBodyCB);
171 :
172 0 : m_pGreetingLine->Enable(bGreetingLine);
173 :
174 : //check if greeting and/or address frame have to be inserted/removed
175 0 : if(m_pExampleWrtShell) // initially there's nothing to check
176 : {
177 0 : if(!rConfigItem.IsGreetingInserted() &&
178 0 : m_bIsGreetingInserted != bGreetingLine )
179 : {
180 0 : if( m_bIsGreetingInserted )
181 : {
182 0 : m_pExampleWrtShell->DelFullPara();
183 0 : m_bIsGreetingInserted = false;
184 : }
185 : else
186 : {
187 0 : InsertGreeting(*m_pExampleWrtShell, m_pWizard->GetConfigItem(), true);
188 0 : m_bIsGreetingInserted = true;
189 : }
190 : }
191 0 : if(!rConfigItem.IsAddressInserted() &&
192 0 : rConfigItem.IsAddressBlock() != ( 0 != m_pAddressBlockFormat ))
193 : {
194 0 : if( m_pAddressBlockFormat )
195 : {
196 0 : m_pExampleWrtShell->Push();
197 0 : m_pExampleWrtShell->GotoFly( m_pAddressBlockFormat->GetName() );
198 0 : m_pExampleWrtShell->DelRight();
199 0 : m_pAddressBlockFormat = 0;
200 0 : m_pExampleWrtShell->Pop(false);
201 : }
202 : else
203 : {
204 0 : long nLeft = static_cast< long >(m_pLeftMF->Denormalize(m_pLeftMF->GetValue(FUNIT_TWIP)));
205 0 : long nTop = static_cast< long >(m_pTopMF->Denormalize(m_pTopMF->GetValue(FUNIT_TWIP)));
206 : m_pAddressBlockFormat = InsertAddressFrame(
207 0 : *m_pExampleWrtShell, m_pWizard->GetConfigItem(),
208 : Point(nLeft, nTop),
209 0 : m_pAlignToBodyCB->IsChecked(), true);
210 : }
211 : }
212 :
213 : }
214 0 : }
215 :
216 0 : bool SwMailMergeLayoutPage::commitPage( ::svt::WizardTypes::CommitPageReason _eReason )
217 : {
218 : //now insert the frame and the greeting
219 0 : SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
220 0 : if(::svt::WizardTypes::eTravelForward == _eReason)
221 : {
222 0 : long nLeft = static_cast< long >(m_pLeftMF->Denormalize(m_pLeftMF->GetValue(FUNIT_TWIP)));
223 0 : long nTop = static_cast< long >(m_pTopMF->Denormalize(m_pTopMF->GetValue(FUNIT_TWIP)));
224 : InsertAddressAndGreeting(
225 : m_pWizard->GetSwView(),
226 : rConfigItem,
227 : Point(nLeft, nTop),
228 0 : m_pAlignToBodyCB->IsChecked());
229 : }
230 0 : return true;
231 : }
232 :
233 0 : SwFrmFmt* SwMailMergeLayoutPage::InsertAddressAndGreeting(SwView* pView,
234 : SwMailMergeConfigItem& rConfigItem,
235 : const Point& rAddressPosition,
236 : bool bAlignToBody)
237 : {
238 0 : SwFrmFmt* pAddressBlockFormat = 0;
239 0 : pView->GetWrtShell().StartUndo(UNDO_INSERT);
240 0 : if(rConfigItem.IsAddressBlock() && !rConfigItem.IsAddressInserted())
241 : {
242 : //insert the frame
243 0 : Point aAddressPosition(DEFAULT_LEFT_DISTANCE, DEFAULT_TOP_DISTANCE);
244 0 : if(rAddressPosition.X() > 0 && rAddressPosition.Y() > 0)
245 0 : aAddressPosition = rAddressPosition;
246 0 : pAddressBlockFormat = InsertAddressFrame( pView->GetWrtShell(),
247 : rConfigItem,
248 0 : aAddressPosition, bAlignToBody, false);
249 0 : rConfigItem.SetAddressInserted(pAddressBlockFormat->GetName());
250 : }
251 : //now the greeting
252 0 : if(rConfigItem.IsGreetingLine(false) && !rConfigItem.IsGreetingInserted())
253 : {
254 0 : InsertGreeting( pView->GetWrtShell(), rConfigItem, false);
255 0 : rConfigItem.SetGreetingInserted();
256 : }
257 0 : pView->GetWrtShell().EndUndo(UNDO_INSERT);
258 0 : return pAddressBlockFormat;
259 : }
260 :
261 0 : SwFrmFmt* SwMailMergeLayoutPage::InsertAddressFrame(
262 : SwWrtShell& rShell,
263 : SwMailMergeConfigItem& rConfigItem,
264 : const Point& rDestination,
265 : bool bAlignLeft,
266 : bool bExample)
267 : {
268 : // insert the address block and the greeting line
269 0 : SfxItemSet aSet(rShell.GetAttrPool(), RES_ANCHOR, RES_ANCHOR,
270 : RES_VERT_ORIENT, RES_VERT_ORIENT,
271 : RES_HORI_ORIENT, RES_HORI_ORIENT,
272 : RES_BOX, RES_BOX,
273 : RES_FRM_SIZE, RES_FRM_SIZE,
274 : RES_SURROUND, RES_SURROUND,
275 0 : 0 );
276 0 : aSet.Put(SwFmtAnchor(FLY_AT_PAGE, 1));
277 0 : if(bAlignLeft)
278 0 : aSet.Put(SwFmtHoriOrient( 0, text::HoriOrientation::NONE, text::RelOrientation::PAGE_PRINT_AREA ));
279 : else
280 0 : aSet.Put(SwFmtHoriOrient( rDestination.X(), text::HoriOrientation::NONE, text::RelOrientation::PAGE_FRAME ));
281 0 : aSet.Put(SwFmtVertOrient( rDestination.Y(), text::VertOrientation::NONE, text::RelOrientation::PAGE_FRAME ));
282 0 : aSet.Put(SwFmtFrmSize( ATT_MIN_SIZE, DEFAULT_ADDRESS_WIDTH, DEFAULT_ADDRESS_HEIGHT ));
283 : // the example gets a border around the frame, the real document doesn't get one
284 0 : if(!bExample)
285 0 : aSet.Put(SvxBoxItem( RES_BOX ));
286 0 : aSet.Put(SwFmtSurround( SURROUND_NONE ));
287 :
288 0 : rShell.NewFlyFrm(aSet, true );
289 0 : SwFrmFmt* pRet = rShell.GetFlyFrmFmt();
290 : OSL_ENSURE( pRet, "Fly not inserted" );
291 :
292 0 : rShell.UnSelectFrm();
293 0 : const Sequence< OUString> aBlocks = rConfigItem.GetAddressBlocks();
294 0 : if(bExample)
295 : {
296 0 : rShell.Insert(aBlocks[0]);
297 : }
298 : else
299 : {
300 : //the placeholders should be replaced by the appropriate fields
301 0 : SwFldMgr aFldMgr(&rShell);
302 : //create a database string source.command.commandtype.column
303 0 : const SwDBData& rData = rConfigItem.GetCurrentDBData();
304 0 : OUString sDBName(rData.sDataSource + OUString(DB_DELIM)
305 0 : + rData.sCommand + OUString(DB_DELIM));
306 0 : const OUString sDatabaseConditionPrefix(sDBName.replace(DB_DELIM, '.'));
307 0 : sDBName += OUString::number(rData.nCommandType) + OUString(DB_DELIM);
308 :
309 : // if only the country is in an address line the
310 : // paragraph has to be hidden depending on the
311 : // IsIncludeCountry()/GetExcludeCountry() settings
312 :
313 0 : bool bIncludeCountry = rConfigItem.IsIncludeCountry();
314 0 : bool bHideEmptyParagraphs = rConfigItem.IsHideEmptyParagraphs();
315 0 : const OUString rExcludeCountry = rConfigItem.GetExcludeCountry();
316 0 : bool bSpecialReplacementForCountry = (!bIncludeCountry || !rExcludeCountry.isEmpty());
317 :
318 0 : const ResStringArray& rHeaders = rConfigItem.GetDefaultAddressHeaders();
319 : Sequence< OUString> aAssignment =
320 0 : rConfigItem.GetColumnAssignment( rConfigItem.GetCurrentDBData() );
321 0 : const OUString* pAssignment = aAssignment.getConstArray();
322 : const OUString sCountryColumn(
323 0 : (aAssignment.getLength() > MM_PART_COUNTRY && !aAssignment[MM_PART_COUNTRY].isEmpty())
324 0 : ? aAssignment[MM_PART_COUNTRY]
325 0 : : rHeaders.GetString(MM_PART_COUNTRY));
326 :
327 0 : OUString sHideParagraphsExpression;
328 0 : SwAddressIterator aIter(aBlocks[0]);
329 0 : while(aIter.HasMore())
330 : {
331 0 : SwMergeAddressItem aItem = aIter.Next();
332 0 : if(aItem.bIsColumn)
333 : {
334 0 : OUString sConvertedColumn = aItem.sText;
335 0 : for(sal_uInt32 nColumn = 0;
336 0 : nColumn < rHeaders.Count() &&
337 0 : nColumn < static_cast<sal_uInt32>(aAssignment.getLength());
338 : ++nColumn)
339 : {
340 0 : if (rHeaders.GetString(nColumn).equals(aItem.sText) &&
341 0 : !pAssignment[nColumn].isEmpty())
342 : {
343 0 : sConvertedColumn = pAssignment[nColumn];
344 0 : break;
345 : }
346 : }
347 0 : const OUString sDB(sDBName + sConvertedColumn);
348 :
349 0 : if(!sHideParagraphsExpression.isEmpty())
350 0 : sHideParagraphsExpression += " AND ";
351 0 : sHideParagraphsExpression += "![" + sDatabaseConditionPrefix + sConvertedColumn + "]";
352 :
353 0 : if( bSpecialReplacementForCountry && sCountryColumn == sConvertedColumn )
354 : {
355 : // now insert a hidden paragraph field
356 0 : if( !rExcludeCountry.isEmpty() )
357 : {
358 0 : const OUString sExpression("[" + sDatabaseConditionPrefix + sCountryColumn + "]");
359 : SwInsertFld_Data aData(TYP_CONDTXTFLD, 0,
360 0 : sExpression + " != \"" + rExcludeCountry + "\"",
361 : sExpression,
362 0 : 0, &rShell );
363 0 : aFldMgr.InsertFld( aData );
364 : }
365 : else
366 : {
367 0 : SwInsertFld_Data aData(TYP_HIDDENPARAFLD, 0, "", "", 0, &rShell );
368 0 : aFldMgr.InsertFld( aData );
369 : }
370 : }
371 : else
372 : {
373 0 : SwInsertFld_Data aData(TYP_DBFLD, 0, sDB, aEmptyOUStr, 0, &rShell );
374 0 : aFldMgr.InsertFld( aData );
375 0 : }
376 : }
377 0 : else if(!aItem.bIsReturn)
378 : {
379 0 : rShell.Insert(aItem.sText);
380 : }
381 : else
382 : {
383 0 : if(bHideEmptyParagraphs)
384 : {
385 0 : SwInsertFld_Data aData(TYP_HIDDENPARAFLD, 0, sHideParagraphsExpression, aEmptyOUStr, 0, &rShell );
386 0 : aFldMgr.InsertFld( aData );
387 : }
388 0 : sHideParagraphsExpression = "";
389 : //now add a new paragraph
390 0 : rShell.SplitNode();
391 : }
392 0 : }
393 0 : if(bHideEmptyParagraphs && !sHideParagraphsExpression.isEmpty())
394 : {
395 0 : SwInsertFld_Data aData(TYP_HIDDENPARAFLD, 0, sHideParagraphsExpression, aEmptyOUStr, 0, &rShell );
396 0 : aFldMgr.InsertFld( aData );
397 0 : }
398 : }
399 0 : return pRet;
400 : }
401 :
402 0 : void SwMailMergeLayoutPage::InsertGreeting(SwWrtShell& rShell, SwMailMergeConfigItem& rConfigItem, bool bExample)
403 : {
404 : //set the cursor to the desired position - if no text content is here then
405 : //new paragraphs are inserted
406 0 : const SwRect& rPageRect = rShell.GetAnyCurRect(RECT_PAGE);
407 0 : const Point aGreetingPos( DEFAULT_LEFT_DISTANCE + rPageRect.Left(), GREETING_TOP_DISTANCE );
408 :
409 0 : const bool bRet = rShell.SetShadowCrsrPos( aGreetingPos, FILL_SPACE );
410 :
411 0 : if(!bRet)
412 : {
413 : //there's already text at the desired position
414 : //go to start of the doc, directly!
415 0 : rShell.SttEndDoc(true);
416 : //and go by paragraph until the position is reached
417 0 : long nYPos = rShell.GetCharRect().Top();
418 0 : while(nYPos < GREETING_TOP_DISTANCE)
419 : {
420 0 : if(!rShell.FwdPara())
421 0 : break;
422 0 : nYPos = rShell.GetCharRect().Top();
423 : }
424 : //text needs to be appended
425 0 : while(nYPos < GREETING_TOP_DISTANCE)
426 : {
427 0 : if(!rShell.AppendTxtNode())
428 0 : break;
429 0 : nYPos = rShell.GetCharRect().Top();
430 : }
431 : }
432 : else
433 : {
434 : //we may end up inside of a paragraph if the left margin is not at DEFAULT_LEFT_DISTANCE
435 0 : rShell.MovePara(GetfnParaCurr(), GetfnParaStart());
436 : }
437 0 : bool bSplitNode = !rShell.GetText().isEmpty();
438 0 : sal_Int32 nMoves = rConfigItem.GetGreetingMoves();
439 0 : if( !bExample && 0 != nMoves )
440 : {
441 0 : if(nMoves < 0)
442 : {
443 0 : rShell.MoveParagraph( nMoves );
444 : }
445 : else
446 0 : while(nMoves)
447 : {
448 0 : bool bMoved = rShell.MoveParagraph( 1 );
449 0 : if(!bMoved)
450 : {
451 : //insert a new paragraph before the greeting line
452 0 : rShell.SplitNode();
453 : }
454 0 : --nMoves;
455 : }
456 : }
457 : //now insert the greeting text - if we have any?
458 0 : const bool bIndividual = rConfigItem.IsIndividualGreeting(false);
459 0 : if(bIndividual)
460 : {
461 : //lock expression fields - prevents hiding of the paragraph to insert into
462 0 : rShell.LockExpFlds();
463 0 : if(bExample)
464 : {
465 0 : for(sal_Int8 eGender = SwMailMergeConfigItem::FEMALE;
466 : eGender <= SwMailMergeConfigItem::NEUTRAL; ++eGender)
467 : {
468 : Sequence< OUString > aEntries =
469 0 : rConfigItem.GetGreetings((SwMailMergeConfigItem::Gender)eGender);
470 0 : sal_Int32 nCurrent = rConfigItem.GetCurrentGreeting((SwMailMergeConfigItem::Gender)eGender);
471 0 : if( nCurrent >= 0 && nCurrent < aEntries.getLength())
472 : {
473 : // Greeting
474 0 : rShell.Insert(aEntries[nCurrent]);
475 0 : break;
476 : }
477 0 : }
478 : }
479 : else
480 : {
481 0 : SwFldMgr aFldMgr(&rShell);
482 : //three paragraphs, each with an appropriate hidden paragraph field
483 : //are to be inserted
484 :
485 : //name of the gender column
486 0 : const OUString sGenderColumn = rConfigItem.GetAssignedColumn(MM_PART_GENDER);
487 0 : const OUString sNameColumn = rConfigItem.GetAssignedColumn(MM_PART_LASTNAME);
488 :
489 0 : const OUString& rFemaleGenderValue = rConfigItem.GetFemaleGenderValue();
490 0 : bool bHideEmptyParagraphs = rConfigItem.IsHideEmptyParagraphs();
491 0 : const SwDBData& rData = rConfigItem.GetCurrentDBData();
492 0 : const OUString sCommonBase(rData.sDataSource + "." + rData.sCommand + ".");
493 0 : const OUString sConditionBase("[" + sCommonBase + sGenderColumn + "]");
494 0 : const OUString sNameColumnBase("[" + sCommonBase + sNameColumn + "]");
495 :
496 0 : const OUString sDBName(rData.sDataSource + OUString(DB_DELIM)
497 0 : + rData.sCommand + OUString(DB_DELIM)
498 0 : + OUString::number(rData.nCommandType) + OUString(DB_DELIM));
499 :
500 : // Female: [database.sGenderColumn] != "rFemaleGenderValue" && [database.NameColumn]
501 : // Male: [database.sGenderColumn] == "rFemaleGenderValue" && [database.rGenderColumn]
502 : // Neutral: [database.sNameColumn]
503 : OSL_ENSURE(!sGenderColumn.isEmpty() && !rFemaleGenderValue.isEmpty(),
504 : "gender settings not available - how to form the condition?");
505 : //column used as lastname
506 0 : for(sal_Int8 eGender = SwMailMergeConfigItem::FEMALE;
507 : eGender <= SwMailMergeConfigItem::NEUTRAL; ++eGender)
508 : {
509 0 : Sequence< OUString> aEntries = rConfigItem.GetGreetings((SwMailMergeConfigItem::Gender)eGender);
510 0 : sal_Int32 nCurrent = rConfigItem.GetCurrentGreeting((SwMailMergeConfigItem::Gender)eGender);
511 0 : if( nCurrent >= 0 && nCurrent < aEntries.getLength())
512 : {
513 0 : const OUString sGreeting = aEntries[nCurrent];
514 0 : OUString sCondition;
515 0 : OUString sHideParagraphsExpression;
516 0 : switch(eGender)
517 : {
518 : case SwMailMergeConfigItem::FEMALE:
519 0 : sCondition = sConditionBase + " != \"" + rFemaleGenderValue
520 0 : + "\" OR NOT " + sNameColumnBase;
521 0 : sHideParagraphsExpression = "!" + sNameColumnBase;
522 0 : break;
523 : case SwMailMergeConfigItem::MALE:
524 0 : sCondition = sConditionBase + " == \"" + rFemaleGenderValue
525 0 : + "\" OR NOT " + sNameColumnBase;
526 0 : break;
527 : case SwMailMergeConfigItem::NEUTRAL:
528 0 : sCondition = sNameColumnBase;
529 0 : break;
530 : }
531 :
532 0 : if(bHideEmptyParagraphs && !sHideParagraphsExpression.isEmpty())
533 : {
534 0 : OUString sComplete = "(" + sCondition + ") OR (" + sHideParagraphsExpression + ")";
535 0 : SwInsertFld_Data aData(TYP_HIDDENPARAFLD, 0, sComplete, aEmptyOUStr, 0, &rShell );
536 0 : aFldMgr.InsertFld( aData );
537 : }
538 : else
539 : {
540 0 : SwInsertFld_Data aData(TYP_HIDDENPARAFLD, 0, sCondition, aEmptyOUStr, 0, &rShell );
541 0 : aFldMgr.InsertFld( aData );
542 : }
543 : //now the text has to be inserted
544 0 : const ResStringArray& rHeaders = rConfigItem.GetDefaultAddressHeaders();
545 : Sequence< OUString> aAssignment =
546 0 : rConfigItem.GetColumnAssignment( rConfigItem.GetCurrentDBData() );
547 0 : const OUString* pAssignment = aAssignment.getConstArray();
548 0 : SwAddressIterator aIter(sGreeting);
549 0 : while(aIter.HasMore())
550 : {
551 0 : SwMergeAddressItem aItem = aIter.Next();
552 0 : if(aItem.bIsColumn)
553 : {
554 0 : OUString sConvertedColumn = aItem.sText;
555 0 : for(sal_uInt32 nColumn = 0;
556 0 : nColumn < rHeaders.Count() &&
557 0 : nColumn < static_cast<sal_uInt32>(aAssignment.getLength());
558 : ++nColumn)
559 : {
560 0 : if (rHeaders.GetString(nColumn).equals(aItem.sText) &&
561 0 : !pAssignment[nColumn].isEmpty())
562 : {
563 0 : sConvertedColumn = pAssignment[nColumn];
564 0 : break;
565 : }
566 : }
567 : SwInsertFld_Data aData(TYP_DBFLD, 0,
568 0 : sDBName + sConvertedColumn,
569 0 : aEmptyOUStr, 0, &rShell );
570 0 : aFldMgr.InsertFld( aData );
571 : }
572 : else
573 : {
574 0 : rShell.Insert(aItem.sText);
575 : }
576 0 : }
577 : //now add a new paragraph
578 0 : rShell.SplitNode();
579 : }
580 0 : }
581 :
582 : }
583 0 : rShell.UnlockExpFlds();
584 : }
585 : else
586 : {
587 0 : Sequence< OUString> aEntries = rConfigItem.GetGreetings(SwMailMergeConfigItem::NEUTRAL);
588 0 : sal_Int32 nCurrent = rConfigItem.GetCurrentGreeting(SwMailMergeConfigItem::NEUTRAL);
589 : // Greeting
590 0 : rShell.Insert(( nCurrent >= 0 && nCurrent < aEntries.getLength() )
591 0 : ? aEntries[nCurrent] : OUString());
592 : }
593 : // now insert a new paragraph here if necessary
594 0 : if(bSplitNode)
595 : {
596 0 : rShell.Push();
597 0 : rShell.SplitNode();
598 0 : rShell.Pop(false);
599 : }
600 : //put the cursor to the start of the paragraph
601 0 : rShell.SttPara();
602 :
603 : OSL_ENSURE(0 == rShell.GetTableFmt(), "What to do with a table here?");
604 0 : }
605 :
606 0 : IMPL_LINK_NOARG(SwMailMergeLayoutPage, PreviewLoadedHdl_Impl)
607 : {
608 0 : m_pExampleContainerWIN->Show(true);
609 :
610 0 : Reference< XModel > & xModel = m_pExampleFrame->GetModel();
611 : //now the ViewOptions should be set properly
612 0 : Reference< XViewSettingsSupplier > xSettings(xModel->getCurrentController(), UNO_QUERY);
613 0 : m_xViewProperties = xSettings->getViewSettings();
614 0 : Reference< XUnoTunnel > xDocTunnel(xModel, UNO_QUERY);
615 0 : SwXTextDocument* pXDoc = reinterpret_cast<SwXTextDocument*>(xDocTunnel->getSomething(SwXTextDocument::getUnoTunnelId()));
616 0 : SwDocShell* pDocShell = pXDoc->GetDocShell();
617 0 : m_pExampleWrtShell = pDocShell->GetWrtShell();
618 : OSL_ENSURE(m_pExampleWrtShell, "No SwWrtShell found!");
619 0 : if(!m_pExampleWrtShell)
620 0 : return 0;
621 :
622 0 : SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
623 0 : if(rConfigItem.IsAddressBlock())
624 : {
625 : m_pAddressBlockFormat = InsertAddressFrame(
626 : *m_pExampleWrtShell, rConfigItem,
627 : Point(DEFAULT_LEFT_DISTANCE, DEFAULT_TOP_DISTANCE),
628 0 : m_pAlignToBodyCB->IsChecked(), true);
629 : }
630 0 : if(rConfigItem.IsGreetingLine(false))
631 : {
632 0 : InsertGreeting(*m_pExampleWrtShell, rConfigItem, true);
633 0 : m_bIsGreetingInserted = true;
634 : }
635 :
636 0 : Any aZoom;
637 0 : aZoom <<= (sal_Int16)DocumentZoomType::ENTIRE_PAGE;
638 0 : m_xViewProperties->setPropertyValue(UNO_NAME_ZOOM_TYPE, aZoom);
639 :
640 : const SwFmtFrmSize& rPageSize = m_pExampleWrtShell->GetPageDesc(
641 0 : m_pExampleWrtShell->GetCurPageDesc()).GetMaster().GetFrmSize();
642 0 : m_pLeftMF->SetMax(rPageSize.GetWidth() - DEFAULT_LEFT_DISTANCE);
643 0 : m_pTopMF->SetMax(rPageSize.GetHeight() - DEFAULT_TOP_DISTANCE);
644 0 : return 0;
645 : }
646 :
647 0 : IMPL_LINK(SwMailMergeLayoutPage, ZoomHdl_Impl, ListBox*, pBox)
648 : {
649 0 : if(m_pExampleWrtShell)
650 : {
651 0 : sal_Int16 eType = DocumentZoomType::BY_VALUE;
652 0 : short nZoom = 50;
653 0 : switch(pBox->GetSelectEntryPos())
654 : {
655 0 : case 0 : eType = DocumentZoomType::ENTIRE_PAGE; break;
656 0 : case 1 : nZoom = 50; break;
657 0 : case 2 : nZoom = 75; break;
658 0 : case 3 : nZoom = 100; break;
659 : }
660 0 : Any aZoom;
661 0 : aZoom <<= eType;
662 0 : m_xViewProperties->setPropertyValue(UNO_NAME_ZOOM_TYPE, aZoom);
663 0 : aZoom <<= nZoom;
664 0 : m_xViewProperties->setPropertyValue(UNO_NAME_ZOOM_VALUE, aZoom);
665 :
666 : }
667 0 : return 0;
668 : }
669 :
670 0 : IMPL_LINK_NOARG(SwMailMergeLayoutPage, ChangeAddressHdl_Impl)
671 : {
672 0 : if(m_pExampleWrtShell && m_pAddressBlockFormat)
673 : {
674 0 : long nLeft = static_cast< long >(m_pLeftMF->Denormalize(m_pLeftMF->GetValue(FUNIT_TWIP)));
675 0 : long nTop = static_cast< long >(m_pTopMF->Denormalize(m_pTopMF->GetValue(FUNIT_TWIP)));
676 :
677 0 : SfxItemSet aSet(m_pExampleWrtShell->GetAttrPool(), RES_ANCHOR, RES_ANCHOR,
678 : RES_VERT_ORIENT, RES_VERT_ORIENT,
679 : RES_HORI_ORIENT, RES_HORI_ORIENT,
680 0 : 0 );
681 0 : if(m_pAlignToBodyCB->IsChecked())
682 0 : aSet.Put(SwFmtHoriOrient( 0, text::HoriOrientation::NONE, text::RelOrientation::PAGE_PRINT_AREA ));
683 : else
684 0 : aSet.Put(SwFmtHoriOrient( nLeft, text::HoriOrientation::NONE, text::RelOrientation::PAGE_FRAME ));
685 0 : aSet.Put(SwFmtVertOrient( nTop, text::VertOrientation::NONE, text::RelOrientation::PAGE_FRAME ));
686 0 : m_pExampleWrtShell->GetDoc()->SetFlyFrmAttr( *m_pAddressBlockFormat, aSet );
687 : }
688 0 : return 0;
689 : }
690 :
691 0 : IMPL_LINK(SwMailMergeLayoutPage, GreetingsHdl_Impl, PushButton*, pButton)
692 : {
693 0 : bool bDown = pButton == m_pDownPB;
694 0 : bool bMoved = m_pExampleWrtShell->MoveParagraph( bDown ? 1 : -1 );
695 0 : if (bMoved || bDown)
696 0 : m_pWizard->GetConfigItem().MoveGreeting(bDown ? 1 : -1 );
697 0 : if(!bMoved && bDown)
698 : {
699 : //insert a new paragraph before the greeting line
700 0 : m_pExampleWrtShell->SplitNode();
701 : }
702 :
703 0 : return 0;
704 : }
705 :
706 0 : IMPL_LINK(SwMailMergeLayoutPage, AlignToTextHdl_Impl, CheckBox*, pBox)
707 : {
708 0 : bool bCheck = pBox->IsChecked() && pBox->IsEnabled();
709 0 : m_pLeftFT->Enable(!bCheck);
710 0 : m_pLeftMF->Enable(!bCheck);
711 0 : ChangeAddressHdl_Impl( 0 );
712 0 : return 0;
713 0 : }
714 :
715 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|