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