Files
libreoffice/sw/source/ui/dbui/mmaddressblockpage.cxx
Noel Grandin 4c93c30c79 convert GETFOCUS constants to scoped enum
Change-Id: I7c324bb6358be28c119592850eb7607479279f09
2015-05-28 12:47:05 +02:00

1657 lines
59 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <mmaddressblockpage.hxx>
#include <mailmergewizard.hxx>
#include <swtypes.hxx>
#include <addresslistdialog.hxx>
#include <vcl/layout.hxx>
#include <vcl/txtattr.hxx>
#include <vcl/xtextedt.hxx>
#include <vcl/builderfactory.hxx>
#include <mmconfigitem.hxx>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
#include <com/sun/star/sdb/XColumn.hpp>
#include <comphelper/string.hxx>
#include <svtools/treelistentry.hxx>
#include <vector>
#include <boost/scoped_ptr.hpp>
#include <globals.hrc>
#include <dbui.hrc>
#include <helpid.h>
using namespace svt;
using namespace ::com::sun::star;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::sdb;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::sdbcx;
static void lcl_Move(Control* pCtrl, long nYOffset)
{
Point aPos(pCtrl->GetPosPixel());
aPos.Y() += nYOffset;
pCtrl->SetPosPixel(aPos);
}
SwMailMergeAddressBlockPage::SwMailMergeAddressBlockPage( SwMailMergeWizard* _pParent) :
svt::OWizardPage(_pParent, "MMAddressBlockPage",
"modules/swriter/ui/mmaddressblockpage.ui")
, m_pWizard(_pParent)
{
get(m_pAddressListPB, "addresslist");
get(m_pCurrentAddressFI, "currentaddress");
get(m_pStep2, "step2");
get(m_pStep3, "step3");
get(m_pStep4, "step4");
get(m_pSettingsFI, "settingsft");
get(m_pAddressCB, "address");
get(m_pSettingsWIN, "settingspreview");
Size aSize(LogicToPixel(Size(164 , 45), MAP_APPFONT));
m_pSettingsWIN->set_width_request(aSize.Width());
m_pSettingsWIN->set_height_request(aSize.Height());
get(m_pSettingsPB, "settings");
get(m_pHideEmptyParagraphsCB, "hideempty");
get(m_pAssignPB, "assign");
get(m_pPreviewWIN, "addresspreview");
aSize = LogicToPixel(Size(176, 46), MAP_APPFONT);
m_pPreviewWIN->set_width_request(aSize.Width());
m_pPreviewWIN->set_height_request(aSize.Height());
get(m_pDocumentIndexFI, "documentindex");
get(m_pPrevSetIB, "prev");
get(m_pNextSetIB, "next");
m_sDocument = m_pDocumentIndexFI->GetText();
m_sChangeAddress = get<Button>("differentlist")->GetText();
m_sCurrentAddress = m_pCurrentAddressFI->GetText();
m_pAddressListPB->SetClickHdl(LINK(this, SwMailMergeAddressBlockPage, AddressListHdl_Impl));
m_pSettingsPB->SetClickHdl(LINK(this, SwMailMergeAddressBlockPage, SettingsHdl_Impl));
m_pAssignPB->SetClickHdl(LINK(this, SwMailMergeAddressBlockPage, AssignHdl_Impl ));
m_pAddressCB->SetClickHdl(LINK(this, SwMailMergeAddressBlockPage, AddressBlockHdl_Impl));
m_pSettingsWIN->SetSelectHdl(LINK(this, SwMailMergeAddressBlockPage, AddressBlockSelectHdl_Impl));
m_pHideEmptyParagraphsCB->SetClickHdl(LINK(this, SwMailMergeAddressBlockPage, HideParagraphsHdl_Impl));
Link<> aLink = LINK(this, SwMailMergeAddressBlockPage, InsertDataHdl_Impl);
m_pPrevSetIB->SetClickHdl(aLink);
m_pNextSetIB->SetClickHdl(aLink);
}
SwMailMergeAddressBlockPage::~SwMailMergeAddressBlockPage()
{
disposeOnce();
}
void SwMailMergeAddressBlockPage::dispose()
{
m_pAddressListPB.clear();
m_pCurrentAddressFI.clear();
m_pStep2.clear();
m_pStep3.clear();
m_pStep4.clear();
m_pSettingsFI.clear();
m_pAddressCB.clear();
m_pSettingsWIN.clear();
m_pSettingsPB.clear();
m_pHideEmptyParagraphsCB.clear();
m_pAssignPB.clear();
m_pPreviewWIN.clear();
m_pDocumentIndexFI.clear();
m_pPrevSetIB.clear();
m_pNextSetIB.clear();
m_pWizard.clear();
svt::OWizardPage::dispose();
}
bool SwMailMergeAddressBlockPage::canAdvance() const
{
return m_pWizard->GetConfigItem().GetResultSet().is();
}
void SwMailMergeAddressBlockPage::ActivatePage()
{
SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
bool bIsLetter = rConfigItem.IsOutputToLetter();
//no address block is created for e-Mail
m_pStep2->Show(bIsLetter);
m_pStep3->Show(bIsLetter);
m_pStep4->Show(bIsLetter);
if (bIsLetter)
{
m_pHideEmptyParagraphsCB->Check( rConfigItem.IsHideEmptyParagraphs() );
m_pDocumentIndexFI->SetText(m_sDocument.replaceFirst("%1", "1"));
m_pSettingsWIN->Clear();
const uno::Sequence< OUString> aBlocks =
m_pWizard->GetConfigItem().GetAddressBlocks();
for(sal_Int32 nAddress = 0; nAddress < aBlocks.getLength(); ++nAddress)
m_pSettingsWIN->AddAddress(aBlocks[nAddress]);
m_pSettingsWIN->SelectAddress((sal_uInt16)rConfigItem.GetCurrentAddressBlockIndex());
m_pAddressCB->Check(rConfigItem.IsAddressBlock());
AddressBlockHdl_Impl(m_pAddressCB);
m_pSettingsWIN->SetLayout(1, 2);
InsertDataHdl_Impl(0);
}
}
bool SwMailMergeAddressBlockPage::commitPage( ::svt::WizardTypes::CommitPageReason _eReason )
{
if ( ::svt::WizardTypes::eTravelForward == _eReason && !m_pWizard->GetConfigItem().GetResultSet().is() )
return false;
return true;
}
IMPL_LINK_NOARG(SwMailMergeAddressBlockPage, AddressListHdl_Impl)
{
try
{
VclPtrInstance< SwAddressListDialog > xAddrDialog(this);
if(RET_OK == xAddrDialog->Execute())
{
SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
rConfigItem.SetCurrentConnection(
xAddrDialog->GetSource(),
xAddrDialog->GetConnection(),
xAddrDialog->GetColumnsSupplier(),
xAddrDialog->GetDBData());
OUString sFilter = xAddrDialog->GetFilter();
rConfigItem.SetFilter( sFilter );
InsertDataHdl_Impl(0);
GetWizard()->UpdateRoadmap();
GetWizard()->enableButtons(WizardButtonFlags::NEXT, GetWizard()->isStateEnabled(MM_GREETINGSPAGE));
}
}
catch (const uno::Exception& e)
{
OSL_FAIL(OUStringToOString(e.Message, osl_getThreadTextEncoding()).getStr());
ScopedVclPtrInstance<MessageDialog>::Create(this, e.Message)->Execute();
}
return 0;
}
IMPL_LINK(SwMailMergeAddressBlockPage, SettingsHdl_Impl, PushButton*, pButton)
{
VclPtr<SwSelectAddressBlockDialog> pDlg(
VclPtr<SwSelectAddressBlockDialog>::Create(pButton, m_pWizard->GetConfigItem()));
SwMailMergeConfigItem& rConfig = m_pWizard->GetConfigItem();
pDlg->SetAddressBlocks(rConfig.GetAddressBlocks(), m_pSettingsWIN->GetSelectedAddress());
pDlg->SetSettings(rConfig.IsIncludeCountry(), rConfig.GetExcludeCountry());
if(RET_OK == pDlg->Execute())
{
//the dialog provides the selected address at the first position!
const uno::Sequence< OUString> aBlocks =
pDlg->GetAddressBlocks();
rConfig.SetAddressBlocks(aBlocks);
m_pSettingsWIN->Clear();
for(sal_Int32 nAddress = 0; nAddress < aBlocks.getLength(); ++nAddress)
m_pSettingsWIN->AddAddress(aBlocks[nAddress]);
m_pSettingsWIN->SelectAddress(0);
m_pSettingsWIN->Invalidate(); // #i40408
rConfig.SetCountrySettings(pDlg->IsIncludeCountry(), pDlg->GetCountry());
InsertDataHdl_Impl(0);
}
pDlg.reset();
GetWizard()->UpdateRoadmap();
GetWizard()->enableButtons(WizardButtonFlags::NEXT, GetWizard()->isStateEnabled(MM_GREETINGSPAGE));
return 0;
}
IMPL_LINK(SwMailMergeAddressBlockPage, AssignHdl_Impl, PushButton*, pButton)
{
SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
const sal_uInt16 nSel = m_pSettingsWIN->GetSelectedAddress();
const uno::Sequence< OUString> aBlocks = rConfigItem.GetAddressBlocks();
VclPtr<SwAssignFieldsDialog> pDlg(
VclPtr<SwAssignFieldsDialog>::Create(pButton, m_pWizard->GetConfigItem(), aBlocks[nSel], true));
if(RET_OK == pDlg->Execute())
{
//preview update
InsertDataHdl_Impl(0);
GetWizard()->UpdateRoadmap();
GetWizard()->enableButtons(WizardButtonFlags::NEXT, GetWizard()->isStateEnabled(MM_GREETINGSPAGE));
}
return 0;
}
void SwMailMergeAddressBlockPage::EnableAddressBlock(bool bAll, bool bSelective)
{
m_pSettingsFI->Enable(bAll);
m_pAddressCB->Enable(bAll);
bSelective &= bAll;
m_pHideEmptyParagraphsCB->Enable(bSelective);
m_pSettingsWIN->Enable(bSelective);
m_pSettingsPB->Enable(bSelective);
m_pStep3->Enable(bSelective);
m_pStep4->Enable(bSelective);
}
IMPL_LINK(SwMailMergeAddressBlockPage, AddressBlockHdl_Impl, CheckBox*, pBox)
{
EnableAddressBlock(pBox->IsEnabled(), pBox->IsChecked());
SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
rConfigItem.SetAddressBlock(m_pAddressCB->IsChecked());
m_pWizard->UpdateRoadmap();
return 0;
}
IMPL_LINK_NOARG(SwMailMergeAddressBlockPage, AddressBlockSelectHdl_Impl)
{
const sal_uInt16 nSel = m_pSettingsWIN->GetSelectedAddress();
const uno::Sequence< OUString> aBlocks =
m_pWizard->GetConfigItem().GetAddressBlocks();
m_pPreviewWIN->SetAddress(SwAddressPreview::FillData(aBlocks[nSel],
m_pWizard->GetConfigItem()));
m_pWizard->GetConfigItem().SetCurrentAddressBlockIndex( nSel );
GetWizard()->UpdateRoadmap();
GetWizard()->enableButtons(WizardButtonFlags::NEXT, GetWizard()->isStateEnabled(MM_GREETINGSPAGE));
return 0;
}
IMPL_LINK(SwMailMergeAddressBlockPage, HideParagraphsHdl_Impl, CheckBox*, pBox)
{
SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
rConfigItem.SetHideEmptyParagraphs( pBox->IsChecked() );
return 0;
}
IMPL_LINK(SwMailMergeAddressBlockPage, InsertDataHdl_Impl, ImageButton*, pButton)
{
//if no pButton is given, the first set has to be pre-set
SwMailMergeConfigItem& rConfig = m_pWizard->GetConfigItem();
m_pWizard->EnterWait();
if(!pButton)
{
rConfig.GetResultSet();
}
else
{
bool bNext = pButton == m_pNextSetIB;
sal_Int32 nPos = rConfig.GetResultSetPosition();
rConfig.MoveResultSet( bNext ? ++nPos : --nPos);
}
m_pWizard->LeaveWait();
sal_Int32 nPos = rConfig.GetResultSetPosition();
bool bEnable = true;
if(nPos < 1)
{
bEnable = false;
nPos = 1;
}
else
{
//if output type is letter
if(m_pSettingsWIN->IsVisible())
{
//Fill data into preview
const sal_uInt16 nSel = m_pSettingsWIN->GetSelectedAddress();
const uno::Sequence< OUString> aBlocks =
m_pWizard->GetConfigItem().GetAddressBlocks();
m_pPreviewWIN->SetAddress(SwAddressPreview::FillData(aBlocks[nSel], rConfig));
}
}
m_pPrevSetIB->Enable(bEnable);
m_pDocumentIndexFI->SetText(m_sDocument.replaceFirst("%1", OUString::number(nPos)));
GetWizard()->enableButtons(WizardButtonFlags::NEXT, GetWizard()->isStateEnabled(MM_GREETINGSPAGE));
bool bHasResultSet = rConfig.GetResultSet().is();
m_pCurrentAddressFI->Show(bHasResultSet);
if(bHasResultSet)
{
m_pCurrentAddressFI->SetText(m_sCurrentAddress.replaceFirst("%1", rConfig.GetCurrentDBData().sDataSource));
m_pAddressListPB->SetText(m_sChangeAddress);
}
EnableAddressBlock(bHasResultSet, m_pAddressCB->IsChecked());
return 0;
}
SwSelectAddressBlockDialog::SwSelectAddressBlockDialog(
vcl::Window* pParent, SwMailMergeConfigItem& rConfig)
: SfxModalDialog(pParent, "SelectBlockDialog",
"modules/swriter/ui/selectblockdialog.ui")
, m_rConfig(rConfig)
{
get(m_pPreview, "preview");
Size aSize(m_pPreview->LogicToPixel(Size(192, 100), MAP_APPFONT));
m_pPreview->set_width_request(aSize.Width());
m_pPreview->set_height_request(aSize.Height());
get(m_pNewPB, "new");
get(m_pCustomizePB, "edit");
get(m_pDeletePB, "delete");
get(m_pNeverRB, "never");
get(m_pAlwaysRB, "always");
get(m_pDependentRB, "dependent");
get(m_pCountryED, "country");
Link<> aCustomizeHdl = LINK(this, SwSelectAddressBlockDialog, NewCustomizeHdl_Impl);
m_pNewPB->SetClickHdl(aCustomizeHdl);
m_pCustomizePB->SetClickHdl(aCustomizeHdl);
m_pDeletePB->SetClickHdl(LINK(this, SwSelectAddressBlockDialog, DeleteHdl_Impl));
Link<> aLk = LINK(this, SwSelectAddressBlockDialog, IncludeHdl_Impl);
m_pNeverRB->SetClickHdl(aLk);
m_pAlwaysRB->SetClickHdl(aLk);
m_pDependentRB->SetClickHdl(aLk);
m_pPreview->SetLayout(2, 2);
m_pPreview->EnableScrollBar();
}
SwSelectAddressBlockDialog::~SwSelectAddressBlockDialog()
{
disposeOnce();
}
void SwSelectAddressBlockDialog::dispose()
{
m_pPreview.clear();
m_pNewPB.clear();
m_pCustomizePB.clear();
m_pDeletePB.clear();
m_pNeverRB.clear();
m_pAlwaysRB.clear();
m_pDependentRB.clear();
m_pCountryED.clear();
SfxModalDialog::dispose();
}
void SwSelectAddressBlockDialog::SetAddressBlocks(const uno::Sequence< OUString>& rBlocks,
sal_uInt16 nSelectedAddress)
{
m_aAddressBlocks = rBlocks;
for(sal_Int32 nAddress = 0; nAddress < m_aAddressBlocks.getLength(); ++nAddress)
m_pPreview->AddAddress(m_aAddressBlocks[nAddress]);
m_pPreview->SelectAddress(nSelectedAddress);
}
// return the address blocks and put the selected one to the first position
const uno::Sequence< OUString >& SwSelectAddressBlockDialog::GetAddressBlocks()
{
//put the selected block to the first position
const sal_Int32 nSelect = static_cast<sal_Int32>(m_pPreview->GetSelectedAddress());
if(nSelect)
{
uno::Sequence< OUString >aTemp = m_aAddressBlocks;
OUString* pTemp = aTemp.getArray();
pTemp[0] = m_aAddressBlocks[nSelect];
sal_Int32 nIndex = 0;
const sal_Int32 nNumBlocks = m_aAddressBlocks.getLength();
for(sal_Int32 nAddress = 1; nAddress < nNumBlocks; ++nAddress)
{
if(nIndex == nSelect)
++nIndex;
pTemp[nAddress] = m_aAddressBlocks[nIndex];
nIndex++;
}
m_aAddressBlocks = aTemp;
}
return m_aAddressBlocks;
}
void SwSelectAddressBlockDialog::SetSettings(
bool bIsCountry, const OUString& rCountry)
{
RadioButton *pActive = m_pNeverRB;
if(bIsCountry)
{
pActive = !rCountry.isEmpty() ? m_pDependentRB : m_pAlwaysRB;
m_pCountryED->SetText(rCountry);
}
pActive->Check();
IncludeHdl_Impl(pActive);
m_pDeletePB->Enable(m_aAddressBlocks.getLength() > 1);
}
OUString SwSelectAddressBlockDialog::GetCountry() const
{
if(m_pDependentRB->IsChecked())
return m_pCountryED->GetText();
return OUString();
}
IMPL_LINK(SwSelectAddressBlockDialog, DeleteHdl_Impl, PushButton*, pButton)
{
if(m_aAddressBlocks.getLength())
{
const sal_Int32 nSelected = static_cast<sal_Int32>(m_pPreview->GetSelectedAddress());
OUString* pAddressBlocks = m_aAddressBlocks.getArray();
sal_Int32 nSource = 0;
for(sal_Int32 nTarget = 0; nTarget < m_aAddressBlocks.getLength() - 1; nTarget++)
{
if(nSource == nSelected)
++nSource;
pAddressBlocks[nTarget] = pAddressBlocks[nSource++];
}
m_aAddressBlocks.realloc(m_aAddressBlocks.getLength() - 1);
if(m_aAddressBlocks.getLength() <= 1)
pButton->Enable(false);
m_pPreview->RemoveSelectedAddress();
}
return 0;
}
IMPL_LINK(SwSelectAddressBlockDialog, NewCustomizeHdl_Impl, PushButton*, pButton)
{
bool bCustomize = pButton == m_pCustomizePB;
SwCustomizeAddressBlockDialog::DialogType nType = bCustomize ?
SwCustomizeAddressBlockDialog::ADDRESSBLOCK_EDIT :
SwCustomizeAddressBlockDialog::ADDRESSBLOCK_NEW;
VclPtr<SwCustomizeAddressBlockDialog> pDlg(
VclPtr<SwCustomizeAddressBlockDialog>::Create(pButton,m_rConfig,nType));
if(bCustomize)
{
pDlg->SetAddress(m_aAddressBlocks[m_pPreview->GetSelectedAddress()]);
}
if(RET_OK == pDlg->Execute())
{
const OUString sNew = pDlg->GetAddress();
if(bCustomize)
{
m_pPreview->ReplaceSelectedAddress(sNew);
m_aAddressBlocks[m_pPreview->GetSelectedAddress()] = sNew;
}
else
{
m_pPreview->AddAddress(sNew);
m_aAddressBlocks.realloc(m_aAddressBlocks.getLength() + 1);
const sal_Int32 nSelect = m_aAddressBlocks.getLength() - 1;
m_aAddressBlocks[nSelect] = sNew;
m_pPreview->SelectAddress(static_cast<sal_uInt16>(nSelect));
}
m_pDeletePB->Enable( m_aAddressBlocks.getLength() > 1);
}
return 0;
}
IMPL_LINK(SwSelectAddressBlockDialog, IncludeHdl_Impl, RadioButton*, pButton)
{
m_pCountryED->Enable(m_pDependentRB == pButton);
return 0;
}
#define USER_DATA_SALUTATION -1
#define USER_DATA_PUNCTUATION -2
#define USER_DATA_TEXT -3
#define USER_DATA_NONE -4
SwCustomizeAddressBlockDialog::SwCustomizeAddressBlockDialog(
vcl::Window* pParent, SwMailMergeConfigItem& rConfig, DialogType eType)
: SfxModalDialog(pParent, "AddressBlockDialog",
"modules/swriter/ui/addressblockdialog.ui")
, m_aTextFilter("<>")
, m_rConfigItem(rConfig)
, m_eType(eType)
{
get(m_pOK, "ok");
get(m_pPreviewWIN, "addrpreview");
get(m_pFieldCB, "custom");
m_pFieldCB->SetTextFilter(&m_aTextFilter);
get(m_pFieldFT, "customft");
get(m_pDownIB, "down");
get(m_pRightIB, "right");
get(m_pLeftIB, "left");
get(m_pUpIB, "up");
get(m_pDragED, "addressdest");
m_pDragED->SetAddressDialog(this);
get(m_pDragFT, "addressdestft");
get(m_pRemoveFieldIB, "fromaddr");
get(m_pInsertFieldIB, "toaddr");
get(m_pAddressElementsLB, "addresses");
m_pAddressElementsLB->set_height_request(16 * m_pAddressElementsLB->GetTextHeight());
m_pAddressElementsLB->SetAddressDialog(this);
get(m_pAddressElementsFT, "addressesft");
if( eType >= GREETING_FEMALE )
{
m_pFieldFT->Show();
m_pFieldCB->Show();
SvTreeListEntry* pEntry = m_pAddressElementsLB->InsertEntry(SW_RESSTR(ST_SALUTATION));
pEntry->SetUserData(reinterpret_cast<void*>((sal_Int32)USER_DATA_SALUTATION) );
pEntry = m_pAddressElementsLB->InsertEntry(SW_RESSTR(ST_PUNCTUATION));
pEntry->SetUserData(reinterpret_cast<void*>((sal_Int32)USER_DATA_PUNCTUATION) );
pEntry = m_pAddressElementsLB->InsertEntry(SW_RESSTR(ST_TEXT));
pEntry->SetUserData(reinterpret_cast<void*>((sal_Int32)USER_DATA_TEXT) );
ResStringArray aSalutArr(SW_RES(RA_SALUTATION));
for(sal_uInt32 i = 0; i < aSalutArr.Count(); ++i)
m_aSalutations.push_back(aSalutArr.GetString(i));
ResStringArray aPunctArr(SW_RES(RA_PUNCTUATION));
for(sal_uInt32 i = 0; i < aPunctArr.Count(); ++i)
m_aPunctuations.push_back(aPunctArr.GetString(i));
m_pDragED->SetText(" ");
SetText(SW_RESSTR(eType == GREETING_MALE ? ST_TITLE_MALE : ST_TITLE_FEMALE));
m_pAddressElementsFT->SetText(SW_RESSTR(ST_SALUTATIONELEMENTS));
m_pInsertFieldIB->SetQuickHelpText(SW_RESSTR(ST_INSERTSALUTATIONFIELD));
m_pRemoveFieldIB->SetQuickHelpText(SW_RESSTR(ST_REMOVESALUTATIONFIELD));
m_pDragFT->SetText(SW_RESSTR(ST_DRAGSALUTATION));
}
else
{
if(eType == ADDRESSBLOCK_EDIT)
SetText(SW_RESSTR(ST_TITLE_EDIT));
m_pDragED->SetText("\n\n\n\n\n");
}
const ResStringArray& rHeaders = m_rConfigItem.GetDefaultAddressHeaders();
for(sal_uInt32 i = 0; i < rHeaders.Count(); ++i)
{
SvTreeListEntry* pEntry = m_pAddressElementsLB->InsertEntry(rHeaders.GetString( i ));
pEntry->SetUserData(reinterpret_cast<void*>((sal_IntPtr)i));
}
m_pOK->SetClickHdl(LINK(this, SwCustomizeAddressBlockDialog, OKHdl_Impl));
m_pAddressElementsLB->SetSelectHdl(LINK(this, SwCustomizeAddressBlockDialog, ListBoxSelectHdl_Impl ));
m_pDragED->SetModifyHdl(LINK(this, SwCustomizeAddressBlockDialog, EditModifyHdl_Impl));
m_pDragED->SetSelectionChangedHdl( LINK( this, SwCustomizeAddressBlockDialog, SelectionChangedHdl_Impl));
Link<> aFieldsLink = LINK(this, SwCustomizeAddressBlockDialog, FieldChangeHdl_Impl);
m_pFieldCB->SetModifyHdl(aFieldsLink);
m_pFieldCB->SetSelectHdl(aFieldsLink);
Link<> aImgButtonHdl = LINK(this, SwCustomizeAddressBlockDialog, ImageButtonHdl_Impl);
m_pInsertFieldIB->SetClickHdl(aImgButtonHdl);
m_pRemoveFieldIB->SetClickHdl(aImgButtonHdl);
m_pUpIB->SetClickHdl(aImgButtonHdl);
m_pLeftIB->SetClickHdl(aImgButtonHdl);
m_pRightIB->SetClickHdl(aImgButtonHdl);
m_pDownIB->SetClickHdl(aImgButtonHdl);
UpdateImageButtons_Impl();
}
SwCustomizeAddressBlockDialog::~SwCustomizeAddressBlockDialog()
{
disposeOnce();
}
void SwCustomizeAddressBlockDialog::dispose()
{
m_pAddressElementsFT.clear();
m_pAddressElementsLB.clear();
m_pInsertFieldIB.clear();
m_pRemoveFieldIB.clear();
m_pDragFT.clear();
m_pDragED.clear();
m_pUpIB.clear();
m_pLeftIB.clear();
m_pRightIB.clear();
m_pDownIB.clear();
m_pFieldFT.clear();
m_pFieldCB.clear();
m_pPreviewWIN.clear();
m_pOK.clear();
SfxModalDialog::dispose();
}
IMPL_LINK_NOARG(SwCustomizeAddressBlockDialog, OKHdl_Impl)
{
EndDialog(RET_OK);
return 0;
}
IMPL_LINK(SwCustomizeAddressBlockDialog, ListBoxSelectHdl_Impl, DDListBox*, pBox)
{
sal_Int32 nUserData = (sal_Int32)reinterpret_cast<sal_IntPtr>(pBox->FirstSelected()->GetUserData());
// Check if the selected entry is already in the address and then forbid inserting
m_pInsertFieldIB->Enable(nUserData >= 0 || !HasItem_Impl(nUserData));
return 0;
}
IMPL_LINK_NOARG(SwCustomizeAddressBlockDialog, EditModifyHdl_Impl)
{
m_pPreviewWIN->SetAddress(SwAddressPreview::FillData(GetAddress(), m_rConfigItem));
UpdateImageButtons_Impl();
return 0;
}
IMPL_LINK(SwCustomizeAddressBlockDialog, ImageButtonHdl_Impl, ImageButton*, pButton)
{
if (m_pInsertFieldIB == pButton)
{
SvTreeListEntry* pEntry = m_pAddressElementsLB->GetCurEntry();
if(pEntry)
{
m_pDragED->InsertNewEntry("<" + m_pAddressElementsLB->GetEntryText(pEntry) + ">");
}
}
else if (m_pRemoveFieldIB == pButton)
{
m_pDragED->RemoveCurrentEntry();
}
else
{
sal_uInt16 nMove = MOVE_ITEM_DOWN;
if (m_pUpIB == pButton)
nMove = MOVE_ITEM_UP;
else if (m_pLeftIB == pButton)
nMove = MOVE_ITEM_LEFT;
else if (m_pRightIB == pButton)
nMove = MOVE_ITEM_RIGHT;
m_pDragED->MoveCurrentItem(nMove);
}
UpdateImageButtons_Impl();
return 0;
}
sal_Int32 SwCustomizeAddressBlockDialog::GetSelectedItem_Impl()
{
sal_Int32 nRet = USER_DATA_NONE;
const OUString sSelected = m_pDragED->GetCurrentItem();
if(!sSelected.isEmpty())
for(sal_uLong i = 0; i < m_pAddressElementsLB->GetEntryCount(); ++i)
{
SvTreeListEntry* pEntry = m_pAddressElementsLB->GetEntry(i);
const OUString sEntry = m_pAddressElementsLB->GetEntryText(pEntry);
if( sEntry == sSelected.copy( 1, sSelected.getLength() - 2 ) )
{
nRet = (sal_Int32)reinterpret_cast<sal_IntPtr>(pEntry->GetUserData());
break;
}
}
return nRet;
}
bool SwCustomizeAddressBlockDialog::HasItem_Impl(sal_Int32 nUserData)
{
//get the entry from the ListBox
OUString sEntry;
for(sal_uLong i = 0; i < m_pAddressElementsLB->GetEntryCount(); ++i)
{
SvTreeListEntry* pEntry = m_pAddressElementsLB->GetEntry(i);
if((sal_Int32)reinterpret_cast<sal_IntPtr>(pEntry->GetUserData()) == nUserData)
{
sEntry = m_pAddressElementsLB->GetEntryText(pEntry);
break;
}
}
//search for this entry in the content
return m_pDragED->GetText().indexOf("<" + sEntry + ">") >= 0;
}
IMPL_LINK(SwCustomizeAddressBlockDialog, SelectionChangedHdl_Impl, AddressMultiLineEdit*, pEdit)
{
// called in case the selection of the edit field changes.
// determine selection - if it's one of the editable fields then
// enable the related ComboBox and fill it
static bool bOnEntry = false;
if(bOnEntry)
return 0;
bOnEntry = true;
sal_Int32 nSelected = GetSelectedItem_Impl();
if(USER_DATA_NONE != nSelected)
pEdit->SelectCurrentItem();
if(m_pFieldCB->IsVisible() && (USER_DATA_NONE != nSelected) && (nSelected < 0))
{
//search in ListBox if it's one of the first entries
OUString sSelect;
::std::vector<OUString>* pVector = 0;
switch(nSelected) {
case USER_DATA_SALUTATION:
sSelect = m_sCurrentSalutation;
pVector = &m_aSalutations;
break;
case USER_DATA_PUNCTUATION:
sSelect = m_sCurrentPunctuation;
pVector = &m_aPunctuations;
break;
case USER_DATA_TEXT:
sSelect = m_sCurrentText;
break;
}
m_pFieldCB->Clear();
if(pVector) {
::std::vector<OUString>::iterator aIterator;
for( aIterator = pVector->begin(); aIterator != pVector->end(); ++aIterator)
m_pFieldCB->InsertEntry(*aIterator);
}
m_pFieldCB->SetText(sSelect);
m_pFieldCB->Enable(true);
m_pFieldFT->Enable(true);
}
else
{
m_pFieldCB->Enable(false);
m_pFieldFT->Enable(false);
}
UpdateImageButtons_Impl();
bOnEntry = false;
return 0;
}
IMPL_LINK_NOARG(SwCustomizeAddressBlockDialog, FieldChangeHdl_Impl)
{
//changing the field content changes the related members, too
sal_Int32 nSelected = GetSelectedItem_Impl();
const OUString sContent = m_pFieldCB->GetText();
switch(nSelected) {
case USER_DATA_SALUTATION:
m_sCurrentSalutation = sContent;
break;
case USER_DATA_PUNCTUATION:
m_sCurrentPunctuation = sContent;
break;
case USER_DATA_TEXT:
m_sCurrentText = sContent;
break;
}
UpdateImageButtons_Impl();
m_pPreviewWIN->SetAddress(GetAddress());
m_pDragED->Modify();
return 0;
}
void SwCustomizeAddressBlockDialog::UpdateImageButtons_Impl()
{
sal_uInt16 nMove = m_pDragED->IsCurrentItemMoveable();
m_pUpIB->Enable(nMove & MOVE_ITEM_UP );
m_pLeftIB->Enable(nMove & MOVE_ITEM_LEFT );
m_pRightIB->Enable(nMove & MOVE_ITEM_RIGHT );
m_pDownIB->Enable(nMove & MOVE_ITEM_DOWN);
m_pRemoveFieldIB->Enable(m_pDragED->HasCurrentItem());
SvTreeListEntry* pEntry = m_pAddressElementsLB->GetCurEntry();
m_pInsertFieldIB->Enable( pEntry &&
(0 < (sal_Int32)reinterpret_cast<sal_IntPtr>(pEntry->GetUserData()) || !m_pFieldCB->GetText().isEmpty()));
}
void SwCustomizeAddressBlockDialog::SetAddress(const OUString& rAddress)
{
m_pDragED->SetText( rAddress );
UpdateImageButtons_Impl();
m_pDragED->Modify();
}
OUString SwCustomizeAddressBlockDialog::GetAddress()
{
OUString sAddress(m_pDragED->GetAddress());
//remove placeholders by the actual content
if(m_pFieldFT->IsVisible())
{
for(sal_uLong i = 0; i < m_pAddressElementsLB->GetEntryCount(); ++i)
{
SvTreeListEntry* pEntry = m_pAddressElementsLB->GetEntry(i);
const OUString sEntry = "<" + m_pAddressElementsLB->GetEntryText(pEntry) + ">";
sal_Int32 nUserData = (sal_Int32)reinterpret_cast<sal_IntPtr>(pEntry->GetUserData());
switch(nUserData)
{
case USER_DATA_SALUTATION:
sAddress = sAddress.replaceFirst(sEntry, m_sCurrentSalutation);
break;
case USER_DATA_PUNCTUATION:
sAddress = sAddress.replaceFirst(sEntry, m_sCurrentPunctuation);
break;
case USER_DATA_TEXT:
sAddress = sAddress.replaceFirst(sEntry, m_sCurrentText);
break;
}
}
}
return sAddress;
}
class SwAssignFieldsControl : public Control
{
friend class SwAssignFieldsDialog;
VclPtr<ScrollBar> m_aVScroll;
VclPtr<HeaderBar> m_aHeaderHB;
VclPtr<Window> m_aWindow;
::std::vector<VclPtr<FixedText> > m_aFieldNames;
::std::vector<VclPtr<ListBox> > m_aMatches;
::std::vector<VclPtr<FixedText> > m_aPreviews;
SwMailMergeConfigItem* m_rConfigItem;
Link<> m_aModifyHdl;
long m_nLBStartTopPos;
long m_nYOffset;
long m_nFirstYPos;
DECL_LINK(ScrollHdl_Impl, ScrollBar*);
DECL_LINK(MatchHdl_Impl, ListBox*);
DECL_LINK(GotFocusHdl_Impl, ListBox*);
virtual bool PreNotify( NotifyEvent& rNEvt ) SAL_OVERRIDE;
virtual void Command( const CommandEvent& rCEvt ) SAL_OVERRIDE;
void MakeVisible( sal_Int32 nIndex );
public:
SwAssignFieldsControl(vcl::Window* pParent, WinBits nBits);
virtual ~SwAssignFieldsControl();
virtual void dispose() SAL_OVERRIDE;
void Init(SwMailMergeConfigItem& rConfigItem);
void SetModifyHdl(const Link<>& rModifyHdl)
{
m_aModifyHdl = rModifyHdl;
m_aModifyHdl.Call(this);
}
virtual void Resize() SAL_OVERRIDE;
virtual Size GetOptimalSize() const SAL_OVERRIDE;
};
VCL_BUILDER_FACTORY_ARGS(SwAssignFieldsControl, WB_BORDER)
SwAssignFieldsControl::SwAssignFieldsControl(vcl::Window* pParent, WinBits nBits) :
Control(pParent, nBits | WB_DIALOGCONTROL | WB_TABSTOP | WB_DIALOGCONTROL),
m_aVScroll(VclPtr<ScrollBar>::Create(this)),
m_aHeaderHB(VclPtr<HeaderBar>::Create(this, WB_BUTTONSTYLE | WB_BOTTOMBORDER)),
m_aWindow(VclPtr<vcl::Window>::Create(this, WB_BORDER | WB_DIALOGCONTROL)),
m_rConfigItem(NULL),
m_nLBStartTopPos(0),
m_nYOffset(0),
m_nFirstYPos(0)
{
long nHBHeight = m_aHeaderHB->CalcWindowSizePixel().Height();
Size aOutputSize(GetOutputSize());
m_aVScroll->Show();
m_aHeaderHB->SetSizePixel(
Size(aOutputSize.Width(), nHBHeight));
m_aHeaderHB->Show();
m_aWindow->SetPosPixel(Point( 0, nHBHeight) );
m_aWindow->SetSizePixel(Size(aOutputSize.Width() - m_aVScroll->GetSizePixel().Width(), aOutputSize.Height() - nHBHeight));
m_aWindow->Show();
}
Size SwAssignFieldsControl::GetOptimalSize() const
{
return LogicToPixel(Size(248 , 120), MAP_APPFONT);
}
void SwAssignFieldsControl::Init(SwMailMergeConfigItem& rConfigItem)
{
m_rConfigItem = &rConfigItem;
Size aOutputSize(GetOutputSize());
long nHBHeight = m_aHeaderHB->CalcWindowSizePixel().Height();
//get the name of the default headers
const ResStringArray& rHeaders = rConfigItem.GetDefaultAddressHeaders();
//get the actual data
uno::Reference< XColumnsSupplier > xColsSupp( rConfigItem.GetResultSet(), uno::UNO_QUERY);
//get the name of the actual columns
uno::Reference <XNameAccess> xColAccess = xColsSupp.is() ? xColsSupp->getColumns() : 0;
uno::Sequence< OUString > aFields;
if(xColAccess.is())
aFields = xColAccess->getElementNames();
const OUString* pFields = aFields.getConstArray();
//get the current assignment list
//each position in this sequence matches the position in the header array rHeaders
//if no assignment is available an empty sequence will be returned
uno::Sequence< OUString> aAssignments = rConfigItem.GetColumnAssignment( rConfigItem.GetCurrentDBData() );
Link<> aMatchHdl = LINK(this, SwAssignFieldsControl, MatchHdl_Impl);
Link<> aFocusHdl = LINK(this, SwAssignFieldsControl, GotFocusHdl_Impl);
//fill the controls
long nControlWidth = aOutputSize.Width() / 3;
long nControlHeight = -1;
for(sal_uInt32 i = 0; i < rHeaders.Count(); ++i)
{
const OUString rHeader = rHeaders.GetString( i );
VclPtr<FixedText> pNewText = VclPtr<FixedText>::Create(m_aWindow.get(), WB_VCENTER);
pNewText->SetText("<" + rHeader + ">");
VclPtr<ListBox> pNewLB = VclPtr<ListBox>::Create(m_aWindow.get(), WB_DROPDOWN | WB_VCENTER | WB_TABSTOP);
pNewText->set_mnemonic_widget(pNewLB);
pNewLB->InsertEntry(SW_RESSTR(SW_STR_NONE));
pNewLB->SelectEntryPos(0);
pNewLB->SetDropDownLineCount(5);
if (nControlHeight == -1) //first time
{
nControlHeight = std::max(pNewLB->get_preferred_size().Height(),
pNewText->get_preferred_size().Height());
}
for(sal_Int32 nField = 0; nField < aFields.getLength(); ++nField)
pNewLB->InsertEntry(pFields[nField]);
VclPtr<FixedText> pNewPreview = VclPtr<FixedText>::Create(m_aWindow.get(), WB_VCENTER);
pNewText->SetSizePixel(Size(nControlWidth - 6, nControlHeight));
pNewLB->SetSizePixel(Size(nControlWidth - 6, nControlHeight));
pNewPreview->SetSizePixel(Size(aOutputSize.Width() - 2 * nControlWidth, nControlHeight));
//select the ListBox
//if there is an assignment
if(static_cast<sal_uInt32>(aAssignments.getLength()) > i && !aAssignments[i].isEmpty())
pNewLB->SelectEntry(aAssignments[i]);
else //otherwise the current column name may match one of the db columns
pNewLB->SelectEntry(rHeader);
//then the preview can be filled accordingly
if(xColAccess.is() && pNewLB->GetSelectEntryPos() > 0 &&
xColAccess->hasByName(pNewLB->GetSelectEntry()))
{
uno::Any aCol = xColAccess->getByName(pNewLB->GetSelectEntry());
uno::Reference< XColumn > xColumn;
aCol >>= xColumn;
if(xColumn.is())
{
try
{
pNewPreview->SetText(xColumn->getString());
}
catch (const SQLException&)
{
}
}
}
if(!i)
{
//determine the vertical offset, use the bottom position of the ListBox
m_nFirstYPos = m_nYOffset = pNewLB->GetPosPixel().Y();
m_nLBStartTopPos = m_nYOffset;
m_nYOffset += pNewLB->GetSizePixel().Height() + 6;
}
long nMove = m_nYOffset * i;
pNewLB->SetSelectHdl(aMatchHdl);
pNewLB->SetGetFocusHdl(aFocusHdl);
m_aFieldNames.push_back(pNewText);
m_aMatches.push_back(pNewLB);
m_aPreviews.push_back(pNewPreview);
pNewText->Show();
pNewText->SetPosPixel(Point(6, nMove));
pNewLB->Show();
pNewLB->SetPosPixel(Point(nControlWidth, nMove));
pNewPreview->Show();
pNewPreview->SetPosPixel(Point(2 * nControlWidth + 6, nMove));
}
m_aVScroll->SetRange(Range(0, rHeaders.Count()));
m_aVScroll->SetPageSize((aOutputSize.Height() - nHBHeight - m_nLBStartTopPos)/ m_nYOffset);
m_aVScroll->EnableDrag();
m_aVScroll->SetVisibleSize(m_aVScroll->GetPageSize());
m_aVScroll->SetScrollHdl(LINK(this, SwAssignFieldsControl, ScrollHdl_Impl));
m_aVScroll->SetPosPixel(Point(aOutputSize.Width() - m_aVScroll->GetSizePixel().Width(), nHBHeight));
m_aVScroll->SetSizePixel(Size(m_aVScroll->GetSizePixel().Width(), aOutputSize.Height() - nHBHeight));
}
SwAssignFieldsControl::~SwAssignFieldsControl()
{
disposeOnce();
}
void SwAssignFieldsControl::dispose()
{
for(auto aFIIter = m_aFieldNames.begin(); aFIIter != m_aFieldNames.end(); ++aFIIter)
aFIIter->disposeAndClear();
for(auto aLBIter = m_aMatches.begin(); aLBIter != m_aMatches.end(); ++aLBIter)
aLBIter->disposeAndClear();
for(auto aFIIter = m_aPreviews.begin(); aFIIter != m_aPreviews.end(); ++aFIIter)
aFIIter->disposeAndClear();
m_aFieldNames.clear();
m_aMatches.clear();
m_aPreviews.clear();
m_aVScroll.disposeAndClear();
m_aHeaderHB.disposeAndClear();
m_aWindow.disposeAndClear();
Control::dispose();
}
void SwAssignFieldsControl::Resize()
{
Window::Resize();
Size aOutputSize = GetOutputSize();
long nHBHeight = m_aHeaderHB->CalcWindowSizePixel().Height();
m_aWindow->SetSizePixel(Size(aOutputSize.Width() - m_aVScroll->GetSizePixel().Width(), aOutputSize.Height() - nHBHeight));
m_aVScroll->SetPosPixel(Point(aOutputSize.Width() - m_aVScroll->GetSizePixel().Width(), nHBHeight));
m_aVScroll->SetSizePixel(Size(m_aVScroll->GetSizePixel().Width(), aOutputSize.Height() - nHBHeight));
if(m_nYOffset)
m_aVScroll->SetPageSize((aOutputSize.Height() - nHBHeight - m_nLBStartTopPos)/ m_nYOffset);
m_aVScroll->SetVisibleSize(m_aVScroll->GetPageSize());
m_aVScroll->DoScroll(0);
sal_Int32 nColWidth = aOutputSize.Width() / 3;
m_aHeaderHB->SetSizePixel(Size(aOutputSize.Width(), nHBHeight));
m_aHeaderHB->SetItemSize(1, nColWidth);
m_aHeaderHB->SetItemSize(2, nColWidth);
m_aHeaderHB->SetItemSize(3, nColWidth);
if (m_aFieldNames.empty() || m_aMatches.empty())
return;
long nControlHeight = std::max(m_aFieldNames[0]->get_preferred_size().Height(),
m_aMatches[0]->get_preferred_size().Height());
for(auto aFIIter = m_aFieldNames.begin(); aFIIter != m_aFieldNames.end(); ++aFIIter)
(*aFIIter)->SetSizePixel(Size(nColWidth - 6, nControlHeight));
for(auto aLBIter = m_aMatches.begin(); aLBIter != m_aMatches.end(); ++aLBIter)
{
long nPosY = (*aLBIter)->GetPosPixel().Y();
(*aLBIter)->SetPosSizePixel(Point(nColWidth, nPosY), Size(nColWidth - 6, nControlHeight));
}
for(auto aFIIter = m_aPreviews.begin(); aFIIter != m_aPreviews.end(); ++aFIIter)
{
long nPosY = (*aFIIter)->GetPosPixel().Y();
(*aFIIter)->SetPosSizePixel(Point(2 * nColWidth + 6, nPosY), Size(nColWidth, nControlHeight));
}
}
void SwAssignFieldsControl::Command( const CommandEvent& rCEvt )
{
switch ( rCEvt.GetCommand() )
{
case CommandEventId::Wheel:
case CommandEventId::StartAutoScroll:
case CommandEventId::AutoScroll:
{
const CommandWheelData* pWheelData = rCEvt.GetWheelData();
if(pWheelData && !pWheelData->IsHorz() && CommandWheelMode::ZOOM != pWheelData->GetMode())
{
HandleScrollCommand( rCEvt, 0, m_aVScroll.get() );
}
}
break;
default:
Control::Command(rCEvt);
}
}
bool SwAssignFieldsControl::PreNotify( NotifyEvent& rNEvt )
{
if(rNEvt.GetType() == MouseNotifyEvent::COMMAND)
{
const CommandEvent* pCEvt = rNEvt.GetCommandEvent();
if( pCEvt->GetCommand() == CommandEventId::Wheel )
{
Command(*pCEvt);
return true;
}
}
return Control::PreNotify(rNEvt);
}
void SwAssignFieldsControl::MakeVisible( sal_Int32 nIndex )
{
long nThumb = m_aVScroll->GetThumbPos();
long nPage = m_aVScroll->GetPageSize();
if(nThumb > nIndex)
m_aVScroll->SetThumbPos( nIndex );
else if( (nThumb + nPage) < nIndex)
m_aVScroll->SetThumbPos( nIndex - nPage );
else
return;
ScrollHdl_Impl( m_aVScroll.get() );
}
IMPL_LINK(SwAssignFieldsControl, ScrollHdl_Impl, ScrollBar*, pScroll)
{
long nThumb = pScroll->GetThumbPos();
// the scrollbar moves on a per line basis
// the height of a line is stored in m_nYOffset
// nThumb determines which line has to be set at the top (m_nYOffset)
// The first line has to be -(nThumb * m_nYOffset) in the negative
long nMove = m_nFirstYPos - (*m_aMatches.begin())->GetPosPixel().Y() - (nThumb * m_nYOffset);
SetUpdateMode(false);
for(auto aFIIter = m_aFieldNames.begin(); aFIIter != m_aFieldNames.end(); ++aFIIter)
lcl_Move(*aFIIter, nMove);
for(auto aLBIter = m_aMatches.begin(); aLBIter != m_aMatches.end(); ++aLBIter)
lcl_Move(*aLBIter, nMove);
for(auto aFIIter = m_aPreviews.begin(); aFIIter != m_aPreviews.end(); ++aFIIter)
lcl_Move(*aFIIter, nMove);
SetUpdateMode(true);
return 0;
}
IMPL_LINK(SwAssignFieldsControl, MatchHdl_Impl, ListBox*, pBox)
{
const OUString sColumn = pBox->GetSelectEntry();
uno::Reference< XColumnsSupplier > xColsSupp( m_rConfigItem->GetResultSet(), uno::UNO_QUERY);
uno::Reference <XNameAccess> xColAccess = xColsSupp.is() ? xColsSupp->getColumns() : 0;
OUString sPreview;
if(xColAccess.is() && xColAccess->hasByName(sColumn))
{
uno::Any aCol = xColAccess->getByName(sColumn);
uno::Reference< XColumn > xColumn;
aCol >>= xColumn;
if(xColumn.is())
{
try
{
sPreview = xColumn->getString();
}
catch (const sdbc::SQLException&)
{
}
}
}
sal_Int32 nIndex = 0;
for(auto aLBIter = m_aMatches.begin(); aLBIter != m_aMatches.end(); ++aLBIter, ++nIndex)
{
if(*aLBIter == pBox)
{
m_aPreviews[nIndex]->SetText(sPreview);
break;
}
}
m_aModifyHdl.Call(0);
return 0;
}
IMPL_LINK(SwAssignFieldsControl, GotFocusHdl_Impl, ListBox*, pBox)
{
if(GetFocusFlags::Tab & pBox->GetGetFocusFlags())
{
sal_Int32 nIndex = 0;
for(auto aLBIter = m_aMatches.begin(); aLBIter != m_aMatches.end(); ++aLBIter, ++nIndex)
{
if(*aLBIter == pBox)
{
MakeVisible(nIndex);
break;
}
}
}
return 0;
}
SwAssignFieldsDialog::SwAssignFieldsDialog(
vcl::Window* pParent, SwMailMergeConfigItem& rConfigItem,
const OUString& rPreview,
bool bIsAddressBlock) :
SfxModalDialog(pParent, "AssignFieldsDialog", "modules/swriter/ui/assignfieldsdialog.ui"),
m_sNone(SW_RESSTR(SW_STR_NONE)),
m_rPreviewString(rPreview),
m_rConfigItem(rConfigItem)
{
get(m_pMatchingFI, "MATCHING_LABEL");
get(m_pPreviewFI, "PREVIEW_LABEL");
get(m_pOK, "ok");
get(m_pPreviewWIN, "PREVIEW");
Size aSize(LogicToPixel(Size(248 , 45), MAP_APPFONT));
m_pPreviewWIN->set_width_request(aSize.Width());
m_pPreviewWIN->set_height_request(aSize.Height());
get(m_pFieldsControl, "FIELDS");
m_pFieldsControl->Init(rConfigItem);
//resize the HeaderBar
OUString sAddressElement( SW_RESSTR(ST_ADDRESSELEMENT) );
const OUString sMatchesTo( SW_RESSTR(ST_MATCHESTO) );
const OUString sPreview( SW_RESSTR(ST_PREVIEW) );
if(!bIsAddressBlock)
{
m_pPreviewFI->SetText(SW_RESSTR(ST_SALUTATIONPREVIEW));
m_pMatchingFI->SetText(SW_RESSTR(ST_SALUTATIONMATCHING));
sAddressElement = SW_RESSTR(ST_SALUTATIONELEMENT);
}
Size aOutputSize(m_pFieldsControl->m_aHeaderHB->GetSizePixel());
sal_Int32 nFirstWidth;
sal_Int32 nSecondWidth = nFirstWidth = aOutputSize.Width() / 3;
const HeaderBarItemBits nHeadBits = HeaderBarItemBits::VCENTER | HeaderBarItemBits::FIXED| HeaderBarItemBits::FIXEDPOS;
m_pFieldsControl->m_aHeaderHB->InsertItem( 1, sAddressElement, nFirstWidth, nHeadBits|HeaderBarItemBits::LEFT);
m_pFieldsControl->m_aHeaderHB->InsertItem( 2, sMatchesTo, nSecondWidth, nHeadBits|HeaderBarItemBits::LEFT);
m_pFieldsControl->m_aHeaderHB->InsertItem( 3, sPreview,
aOutputSize.Width() - nFirstWidth - nSecondWidth, nHeadBits|HeaderBarItemBits::LEFT);
m_pFieldsControl->SetModifyHdl(LINK(this, SwAssignFieldsDialog, AssignmentModifyHdl_Impl ));
m_pMatchingFI->SetText(m_pMatchingFI->GetText().replaceAll("%1", sMatchesTo));
m_pOK->SetClickHdl(LINK(this, SwAssignFieldsDialog, OkHdl_Impl));
}
SwAssignFieldsDialog::~SwAssignFieldsDialog()
{
disposeOnce();
}
void SwAssignFieldsDialog::dispose()
{
m_pMatchingFI.clear();
m_pFieldsControl.clear();
m_pPreviewFI.clear();
m_pPreviewWIN.clear();
m_pOK.clear();
SfxModalDialog::dispose();
}
uno::Sequence< OUString > SwAssignFieldsDialog::CreateAssignments()
{
uno::Sequence< OUString > aAssignments(
m_rConfigItem.GetDefaultAddressHeaders().Count());
OUString* pAssignments = aAssignments.getArray();
sal_Int32 nIndex = 0;
for(auto aLBIter = m_pFieldsControl->m_aMatches.begin();
aLBIter != m_pFieldsControl->m_aMatches.end();
++aLBIter, ++nIndex)
{
const OUString sSelect = (*aLBIter)->GetSelectEntry();
pAssignments[nIndex] = (m_sNone != sSelect) ? sSelect : OUString();
}
return aAssignments;
}
IMPL_LINK_NOARG(SwAssignFieldsDialog, OkHdl_Impl)
{
m_rConfigItem.SetColumnAssignment(
m_rConfigItem.GetCurrentDBData(),
CreateAssignments() );
EndDialog(RET_OK);
return 0;
}
IMPL_LINK_NOARG(SwAssignFieldsDialog, AssignmentModifyHdl_Impl)
{
uno::Sequence< OUString > aAssignments = CreateAssignments();
const OUString sPreview = SwAddressPreview::FillData(
m_rPreviewString, m_rConfigItem, &aAssignments);
m_pPreviewWIN->SetAddress(sPreview);
return 0;
}
DDListBox::DDListBox(vcl::Window* pParent, WinBits nStyle)
: SvTreeListBox(pParent, nStyle)
, m_pParentDialog(NULL)
{
SetStyle( GetStyle() | /*WB_HASBUTTONS|WB_HASBUTTONSATROOT|*/
WB_CLIPCHILDREN );
SetSelectionMode( SINGLE_SELECTION );
SetDragDropMode( DragDropMode::CTRL_COPY );
EnableAsyncDrag(true);
// expand selection to the complete width of the ListBox
SetHighlightRange();
Show();
}
DDListBox::~DDListBox()
{
disposeOnce();
}
void DDListBox::dispose()
{
m_pParentDialog.clear();
SvTreeListBox::dispose();
}
VCL_BUILDER_DECL_FACTORY(DDListBox)
{
WinBits nWinStyle = WB_TABSTOP;
OString sBorder = VclBuilder::extractCustomProperty(rMap);
if (!sBorder.isEmpty())
nWinStyle |= WB_BORDER;
rRet = VclPtr<DDListBox>::Create(pParent, nWinStyle);
}
void DDListBox::SetAddressDialog(SwCustomizeAddressBlockDialog *pParent)
{
m_pParentDialog = pParent;
}
void DDListBox::StartDrag( sal_Int8 /*nAction*/, const Point& /*rPosPixel*/ )
{
SvTreeListEntry* pEntry = GetCurEntry();
if(pEntry)
{
ReleaseMouse();
TransferDataContainer* pContainer = new TransferDataContainer;
uno::Reference<
datatransfer::XTransferable > xRef( pContainer );
sal_Int32 nUserData = (sal_Int32)reinterpret_cast<sal_IntPtr>(pEntry->GetUserData());
//special entries can only be once in the address / greeting
if(nUserData >= 0 || !m_pParentDialog->HasItem_Impl(nUserData))
{
pContainer->CopyString( "<" + GetEntryText(pEntry) + ">" );
pContainer->StartDrag( this, DND_ACTION_COPY, GetDragFinishedHdl() );
}
}
}
AddressMultiLineEdit::AddressMultiLineEdit(vcl::Window* pParent, WinBits nBits)
: VclMultiLineEdit(pParent, nBits)
, m_pParentDialog(NULL)
{
GetTextView()->SupportProtectAttribute(true);
StartListening(*GetTextEngine());
EnableFocusSelectionHide(false);
}
AddressMultiLineEdit::~AddressMultiLineEdit()
{
disposeOnce();
}
void AddressMultiLineEdit::dispose()
{
EndListening(*GetTextEngine());
m_pParentDialog.clear();
VclMultiLineEdit::dispose();
}
Size AddressMultiLineEdit::GetOptimalSize() const
{
return LogicToPixel(Size(160, 60), MAP_APPFONT);
}
VCL_BUILDER_DECL_FACTORY(AddressMultiLineEdit)
{
WinBits nWinStyle = WB_LEFT|WB_TABSTOP;
OString sBorder = VclBuilder::extractCustomProperty(rMap);
if (!sBorder.isEmpty())
nWinStyle |= WB_BORDER;
rRet = VclPtr<AddressMultiLineEdit>::Create(pParent, nWinStyle);
}
void AddressMultiLineEdit::SetAddressDialog(SwCustomizeAddressBlockDialog *pParent)
{
m_pParentDialog = pParent;
}
void AddressMultiLineEdit::Notify(SfxBroadcaster& /*rBC*/, const SfxHint& rHint)
{
if (m_aSelectionLink.IsSet() && dynamic_cast<const TextHint*>(&rHint))
{
const TextHint& rTextHint = static_cast<const TextHint&>(rHint);
if (rTextHint.GetId() == TEXT_HINT_VIEWSELECTIONCHANGED ||
rTextHint.GetId() == TEXT_HINT_VIEWCARETCHANGED)
{
m_aSelectionLink.Call(this);
}
}
}
bool AddressMultiLineEdit::PreNotify( NotifyEvent& rNEvt )
{
bool nHandled = false;
if( MouseNotifyEvent::KEYINPUT == rNEvt.GetType() &&
rNEvt.GetKeyEvent()->GetCharCode())
{
nHandled = true;
}
else if(MouseNotifyEvent::MOUSEBUTTONDOWN == rNEvt.GetType()) {
const MouseEvent *pMEvt = rNEvt.GetMouseEvent();
if(pMEvt->GetClicks() >= 2)
nHandled = true;
}
if(!nHandled)
nHandled = VclMultiLineEdit::PreNotify( rNEvt );
return nHandled;
}
void AddressMultiLineEdit::SetText( const OUString& rStr )
{
VclMultiLineEdit::SetText(rStr);
//set attributes to all address tokens
ExtTextEngine* pTextEngine = GetTextEngine();
TextAttribProtect aProtectAttr;
sal_uLong nParaCount = pTextEngine->GetParagraphCount();
for(sal_uLong nPara = 0; nPara < nParaCount; ++nPara)
{
sal_Int32 nIndex = 0;
const OUString sPara = pTextEngine->GetText( nPara );
if(!sPara.isEmpty() && !sPara.endsWith(" "))
{
TextPaM aPaM(nPara, sPara.getLength());
pTextEngine->ReplaceText(TextSelection( aPaM ), " ");
}
while(true)
{
sal_Int32 nStart = sPara.indexOf( '<', nIndex );
sal_Int32 nEnd = nStart == -1 ? -1 : sPara.indexOf( '>', nStart );
nIndex = nEnd;
if(nStart != -1 && nEnd != -1)
pTextEngine->SetAttrib( aProtectAttr, nPara, nStart, nEnd + 1, false );
else
break;
}
}
// add two empty paragraphs at the end
if(m_pParentDialog->m_eType == SwCustomizeAddressBlockDialog::ADDRESSBLOCK_NEW ||
m_pParentDialog->m_eType == SwCustomizeAddressBlockDialog::ADDRESSBLOCK_EDIT)
{
sal_Int32 nLastLen = pTextEngine->GetText(nParaCount - 1).getLength();
if(nLastLen)
{
TextPaM aPaM(nParaCount ? nParaCount - 1 : 0, nLastLen);
pTextEngine->ReplaceText(TextSelection( aPaM ), "\n \n ");
}
}
}
// Insert the new entry in front of the entry at the beginning of the selection
void AddressMultiLineEdit::InsertNewEntry( const OUString& rStr )
{
// insert new entry after current selected one.
ExtTextView* pTextView = GetTextView();
const TextSelection& rSelection = pTextView->GetSelection();
sal_uLong nPara = rSelection.GetStart().GetPara();
sal_uInt16 nIndex = rSelection.GetEnd().GetIndex();
ExtTextEngine *pTextEngine = GetTextEngine();
const TextCharAttrib *pAttrib;
if(0 != (pAttrib = pTextEngine->FindCharAttrib( rSelection.GetStart(), TEXTATTR_PROTECTED )))
nIndex = pAttrib->GetEnd();
InsertNewEntryAtPosition( rStr, nPara, nIndex );
// select the new entry
pAttrib = pTextEngine->FindCharAttrib(TextPaM(nPara, nIndex),TEXTATTR_PROTECTED);
const sal_uInt16 nEnd = pAttrib ? pAttrib->GetEnd() : nIndex;
TextSelection aEntrySel(TextPaM(nPara, nIndex), TextPaM(nPara, nEnd));
pTextView->SetSelection(aEntrySel);
Invalidate();
Modify();
}
void AddressMultiLineEdit::InsertNewEntryAtPosition( const OUString& rStr, sal_uLong nPara, sal_uInt16 nIndex )
{
ExtTextEngine* pTextEngine = GetTextEngine();
TextPaM aInsertPos( nPara, nIndex );
pTextEngine->ReplaceText( aInsertPos, rStr );
//restore the attributes
SetText( GetAddress() );
//select the newly inserted/moved element
TextSelection aEntrySel(aInsertPos);
ExtTextView* pTextView = GetTextView();
pTextView->SetSelection(aEntrySel);
m_aSelectionLink.Call(this);
}
void AddressMultiLineEdit::RemoveCurrentEntry()
{
ExtTextEngine* pTextEngine = GetTextEngine();
ExtTextView* pTextView = GetTextView();
const TextSelection& rSelection = pTextView->GetSelection();
const TextCharAttrib* pBeginAttrib = pTextEngine->FindCharAttrib( rSelection.GetStart(), TEXTATTR_PROTECTED );
if(pBeginAttrib &&
(pBeginAttrib->GetStart() <= rSelection.GetStart().GetIndex()
&& pBeginAttrib->GetEnd() >= rSelection.GetEnd().GetIndex()))
{
sal_uLong nPara = rSelection.GetStart().GetPara();
TextSelection aEntrySel(TextPaM( nPara, pBeginAttrib->GetStart()), TextPaM(nPara, pBeginAttrib->GetEnd()));
pTextEngine->ReplaceText(aEntrySel, OUString());
//restore the attributes
SetText( GetAddress() );
Modify();
}
}
void AddressMultiLineEdit::MoveCurrentItem(sal_uInt16 nMove)
{
ExtTextEngine* pTextEngine = GetTextEngine();
ExtTextView* pTextView = GetTextView();
const TextSelection& rSelection = pTextView->GetSelection();
const TextCharAttrib* pBeginAttrib = pTextEngine->FindCharAttrib( rSelection.GetStart(), TEXTATTR_PROTECTED );
if(pBeginAttrib &&
(pBeginAttrib->GetStart() <= rSelection.GetStart().GetIndex()
&& pBeginAttrib->GetEnd() >= rSelection.GetEnd().GetIndex()))
{
//current item has been found
sal_uLong nPara = rSelection.GetStart().GetPara();
sal_uInt16 nIndex = pBeginAttrib->GetStart();
TextSelection aEntrySel(TextPaM( nPara, pBeginAttrib->GetStart()), TextPaM(nPara, pBeginAttrib->GetEnd()));
const OUString sCurrentItem = pTextEngine->GetText(aEntrySel);
pTextEngine->RemoveAttrib( nPara, *pBeginAttrib );
pTextEngine->ReplaceText(aEntrySel, OUString());
switch(nMove)
{
case MOVE_ITEM_LEFT :
if(nIndex)
{
//go left to find a predecessor or simple text
--nIndex;
const OUString sPara = pTextEngine->GetText( nPara );
sal_Int32 nSearchIndex = sPara.lastIndexOf( '>', nIndex+1 );
if( nSearchIndex != -1 && nSearchIndex == nIndex )
{
nSearchIndex = sPara.lastIndexOf( '<', nIndex );
if( nSearchIndex != -1 )
nIndex = nSearchIndex;
}
}
break;
case MOVE_ITEM_RIGHT:
{
//go right to find a successor or simple text
++nIndex;
const TextCharAttrib* pEndAttrib = pTextEngine->FindCharAttrib( rSelection.GetStart(), TEXTATTR_PROTECTED );
if(pEndAttrib && pEndAttrib->GetEnd() >= nIndex)
{
nIndex = pEndAttrib->GetEnd();
}
}
break;
case MOVE_ITEM_UP :
--nPara;
nIndex = 0;
break;
case MOVE_ITEM_DOWN :
++nPara;
nIndex = 0;
break;
}
//add a new paragraph if there is none yet
if(nPara >= pTextEngine->GetParagraphCount())
{
TextPaM aTemp(nPara - 1, pTextEngine->GetTextLen( nPara - 1 ));
pTextEngine->ReplaceText(aTemp, "\n");
}
InsertNewEntryAtPosition( sCurrentItem, nPara, nIndex );
// select the new entry [#i40817]
const TextCharAttrib *pAttrib = pTextEngine->FindCharAttrib(TextPaM(nPara, nIndex),TEXTATTR_PROTECTED);
if (pAttrib)
aEntrySel = TextSelection(TextPaM(nPara, nIndex), TextPaM(nPara, pAttrib->GetEnd()));
pTextView->SetSelection(aEntrySel);
Invalidate();
Modify();
}
}
sal_uInt16 AddressMultiLineEdit::IsCurrentItemMoveable()
{
sal_uInt16 nRet = 0;
ExtTextEngine* pTextEngine = GetTextEngine();
ExtTextView* pTextView = GetTextView();
const TextSelection& rSelection = pTextView->GetSelection();
const TextCharAttrib* pBeginAttrib = pTextEngine->FindCharAttrib( rSelection.GetStart(), TEXTATTR_PROTECTED );
if(pBeginAttrib &&
(pBeginAttrib->GetStart() <= rSelection.GetStart().GetIndex()
&& pBeginAttrib->GetEnd() >= rSelection.GetEnd().GetIndex()))
{
if(pBeginAttrib->GetStart())
nRet |= MOVE_ITEM_LEFT;
//if there is an entry it can always be move to the right and down
nRet |= MOVE_ITEM_RIGHT|MOVE_ITEM_DOWN;
if(rSelection.GetStart().GetPara() > 0)
nRet |= MOVE_ITEM_UP;
}
return nRet;
}
bool AddressMultiLineEdit::HasCurrentItem()
{
ExtTextEngine* pTextEngine = GetTextEngine();
ExtTextView* pTextView = GetTextView();
const TextSelection& rSelection = pTextView->GetSelection();
const TextCharAttrib* pBeginAttrib = pTextEngine->FindCharAttrib( rSelection.GetStart(), TEXTATTR_PROTECTED );
return (pBeginAttrib &&
(pBeginAttrib->GetStart() <= rSelection.GetStart().GetIndex()
&& pBeginAttrib->GetEnd() >= rSelection.GetEnd().GetIndex()));
}
OUString AddressMultiLineEdit::GetCurrentItem()
{
ExtTextEngine* pTextEngine = GetTextEngine();
ExtTextView* pTextView = GetTextView();
const TextSelection& rSelection = pTextView->GetSelection();
const TextCharAttrib* pBeginAttrib = pTextEngine->FindCharAttrib( rSelection.GetStart(), TEXTATTR_PROTECTED );
if(pBeginAttrib &&
(pBeginAttrib->GetStart() <= rSelection.GetStart().GetIndex()
&& pBeginAttrib->GetEnd() >= rSelection.GetEnd().GetIndex()))
{
sal_uLong nPara = rSelection.GetStart().GetPara();
TextSelection aEntrySel(TextPaM( nPara, pBeginAttrib->GetStart()), TextPaM(nPara, pBeginAttrib->GetEnd()));
return pTextEngine->GetText( aEntrySel );
}
return OUString();
}
void AddressMultiLineEdit::SelectCurrentItem()
{
ExtTextEngine* pTextEngine = GetTextEngine();
ExtTextView* pTextView = GetTextView();
const TextSelection& rSelection = pTextView->GetSelection();
const TextCharAttrib* pBeginAttrib = pTextEngine->FindCharAttrib( rSelection.GetStart(), TEXTATTR_PROTECTED );
if(pBeginAttrib &&
(pBeginAttrib->GetStart() <= rSelection.GetStart().GetIndex()
&& pBeginAttrib->GetEnd() >= rSelection.GetEnd().GetIndex()))
{
sal_uLong nPara = rSelection.GetStart().GetPara();
TextSelection aEntrySel(TextPaM( nPara, pBeginAttrib->GetStart()), TextPaM(nPara, pBeginAttrib->GetEnd()));
pTextView->SetSelection(aEntrySel);
Invalidate();
}
}
OUString AddressMultiLineEdit::GetAddress()
{
OUString sRet;
ExtTextEngine* pTextEngine = GetTextEngine();
sal_uLong nParaCount = pTextEngine->GetParagraphCount();
for(sal_uLong nPara = nParaCount; nPara; --nPara)
{
const OUString sPara = comphelper::string::stripEnd(pTextEngine->GetText(nPara - 1), ' ');
//don't add empty trailing paragraphs
if(!sRet.isEmpty() || !sPara.isEmpty())
{
sRet = sPara + sRet;
//insert the para break
if(nPara > 1)
sRet = "\n" + sRet;
}
}
return sRet;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */