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