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