xref: /trunk/main/sw/source/ui/dbui/mmlayoutpage.cxx (revision efeef26f)
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