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