diff options
Diffstat (limited to 'svx/source/form/tabwin.cxx')
-rw-r--r-- | svx/source/form/tabwin.cxx | 441 |
1 files changed, 441 insertions, 0 deletions
diff --git a/svx/source/form/tabwin.cxx b/svx/source/form/tabwin.cxx new file mode 100644 index 000000000000..50736536bfd0 --- /dev/null +++ b/svx/source/form/tabwin.cxx @@ -0,0 +1,441 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: tabwin.cxx,v $ + * $Revision: 1.28 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include "tabwin.hxx" +#include "svx/fmtools.hxx" +#include "fmservs.hxx" +#include "stringlistresource.hxx" + +#include <svx/svxids.hrc> +#include <svx/dbaexchange.hxx> +#include <com/sun/star/sdb/CommandType.hpp> +#include <com/sun/star/sdbcx/XTablesSupplier.hpp> +#include <com/sun/star/sdb/XQueriesSupplier.hpp> +#include <com/sun/star/sdbc/XPreparedStatement.hpp> +#include <com/sun/star/awt/XControlContainer.hpp> +#include <com/sun/star/util/XLocalizedAliases.hpp> +#include <comphelper/processfactory.hxx> +#include <comphelper/stl_types.hxx> + +#ifndef _SVX_FMHELP_HRC +#include "fmhelp.hrc" +#endif +#include <svx/fmshell.hxx> +#include "fmshimp.hxx" +#include "svx/dbtoolsclient.hxx" +#include <svx/fmpage.hxx> + +#ifndef _SVX_FMPGEIMP_HXX +#include "fmpgeimp.hxx" +#endif + +#ifndef _SVX_FMPROP_HRC +#include "fmprop.hrc" +#endif + +#ifndef _SVX_FMRESIDS_HRC +#include "fmresids.hrc" +#endif +#include <svx/dialmgr.hxx> +#include <tools/shl.hxx> +#include <svx/svdpagv.hxx> +#include <sfx2/objitem.hxx> +#include <sfx2/dispatch.hxx> +#include <comphelper/property.hxx> +#include <sfx2/frame.hxx> +#include <svx/dataaccessdescriptor.hxx> + +const long STD_WIN_POS_X = 50; +const long STD_WIN_POS_Y = 50; + +const long STD_WIN_SIZE_X = 120; +const long STD_WIN_SIZE_Y = 150; + +const long MIN_WIN_SIZE_X = 50; +const long MIN_WIN_SIZE_Y = 50; + +const long LISTBOX_BORDER = 2; + +using namespace ::com::sun::star::sdbc; +using namespace ::com::sun::star::sdb; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::datatransfer; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::form; +using namespace ::com::sun::star::container; +using namespace ::svxform; +using namespace ::svx; + +//================================================================== +// class FmFieldWinListBox +//================================================================== +DBG_NAME(FmFieldWinListBox) +//------------------------------------------------------------------------------ +FmFieldWinListBox::FmFieldWinListBox( FmFieldWin* pParent ) + :SvTreeListBox( pParent, WB_HASBUTTONS|WB_BORDER ) + ,pTabWin( pParent ) +{ + DBG_CTOR(FmFieldWinListBox,NULL); + SetHelpId( HID_FIELD_SEL ); + + SetHighlightRange( ); +} + +//------------------------------------------------------------------------------ +FmFieldWinListBox::~FmFieldWinListBox() +{ + DBG_DTOR(FmFieldWinListBox,NULL); +} + +//------------------------------------------------------------------------------ +sal_Int8 FmFieldWinListBox::AcceptDrop( const AcceptDropEvent& /*rEvt*/ ) +{ + return DND_ACTION_NONE; +} + +//------------------------------------------------------------------------------ +sal_Int8 FmFieldWinListBox::ExecuteDrop( const ExecuteDropEvent& /*rEvt*/ ) +{ + return DND_ACTION_NONE; +} + +//------------------------------------------------------------------------------ +BOOL FmFieldWinListBox::DoubleClickHdl() +{ + if ( pTabWin->createSelectionControls() ) + return sal_True; + + return SvTreeListBox::DoubleClickHdl(); +} + +//------------------------------------------------------------------------------ +void FmFieldWinListBox::StartDrag( sal_Int8 /*_nAction*/, const Point& /*_rPosPixel*/ ) +{ + SvLBoxEntry* pSelected = FirstSelected(); + if (!pSelected) + // no drag without a field + return; + + ::svx::ODataAccessDescriptor aDescriptor; + aDescriptor[ daDataSource ] <<= pTabWin->GetDatabaseName(); + aDescriptor[ daConnection ] <<= pTabWin->GetConnection().getTyped(); + aDescriptor[ daCommand ] <<= pTabWin->GetObjectName(); + aDescriptor[ daCommandType ]<<= pTabWin->GetObjectType(); + aDescriptor[ daColumnName ] <<= ::rtl::OUString( GetEntryText( pSelected ) ); + + TransferableHelper* pTransferColumn = new OColumnTransferable( + aDescriptor, CTF_FIELD_DESCRIPTOR | CTF_CONTROL_EXCHANGE | CTF_COLUMN_DESCRIPTOR + ); + Reference< XTransferable> xEnsureDelete = pTransferColumn; + if (pTransferColumn) + { + EndSelection(); + pTransferColumn->StartDrag( this, DND_ACTION_COPY ); + } +} + +//======================================================================== +// class FmFieldWinData +//======================================================================== +DBG_NAME(FmFieldWinData); +//----------------------------------------------------------------------- +FmFieldWinData::FmFieldWinData() +{ + DBG_CTOR(FmFieldWinData,NULL); +} + +//----------------------------------------------------------------------- +FmFieldWinData::~FmFieldWinData() +{ + DBG_DTOR(FmFieldWinData,NULL); +} + +//======================================================================== +// class FmFieldWin +//======================================================================== +DBG_NAME(FmFieldWin); +//----------------------------------------------------------------------- +FmFieldWin::FmFieldWin(SfxBindings* _pBindings, SfxChildWindow* _pMgr, Window* _pParent) + :SfxFloatingWindow(_pBindings, _pMgr, _pParent, WinBits(WB_STDMODELESS|WB_SIZEABLE)) + ,SfxControllerItem(SID_FM_FIELDS_CONTROL, *_pBindings) + ,::comphelper::OPropertyChangeListener(m_aMutex) + ,pData(new FmFieldWinData) + ,m_nObjectType(0) + ,m_pChangeListener(NULL) +{ + DBG_CTOR(FmFieldWin,NULL); + SetHelpId( HID_FIELD_SEL_WIN ); + + SetBackground( Wallpaper( Application::GetSettings().GetStyleSettings().GetFaceColor()) ); + pListBox = new FmFieldWinListBox( this ); + pListBox->Show(); + UpdateContent(NULL); + SetSizePixel(Size(STD_WIN_SIZE_X,STD_WIN_SIZE_Y)); +} + +//----------------------------------------------------------------------- +FmFieldWin::~FmFieldWin() +{ + if (m_pChangeListener) + { + m_pChangeListener->dispose(); + m_pChangeListener->release(); + // delete m_pChangeListener; + } + delete pListBox; + delete pData; + DBG_DTOR(FmFieldWin,NULL); +} + +//----------------------------------------------------------------------- +void FmFieldWin::GetFocus() +{ + if ( pListBox ) + pListBox->GrabFocus(); + else + SfxFloatingWindow::GetFocus(); +} + +//----------------------------------------------------------------------- +sal_Bool FmFieldWin::createSelectionControls( ) +{ + SvLBoxEntry* pSelected = pListBox->FirstSelected(); + if ( pSelected ) + { + // build a descriptor for the currently selected field + ODataAccessDescriptor aDescr; + aDescr.setDataSource(GetDatabaseName()); + + aDescr[ daConnection ] <<= GetConnection().getTyped(); + + aDescr[ daCommand ] <<= GetObjectName(); + aDescr[ daCommandType ] <<= GetObjectType(); + aDescr[ daColumnName ] <<= ::rtl::OUString( pListBox->GetEntryText( pSelected) ); + + // transfer this to the SFX world + SfxUnoAnyItem aDescriptorItem( SID_FM_DATACCESS_DESCRIPTOR, makeAny( aDescr.createPropertyValueSequence() ) ); + const SfxPoolItem* pArgs[] = + { + &aDescriptorItem, NULL + }; + + // execute the create slot + GetBindings().Execute( SID_FM_CREATE_FIELDCONTROL, pArgs ); + } + + return NULL != pSelected; +} + +//----------------------------------------------------------------------- +long FmFieldWin::PreNotify( NotifyEvent& _rNEvt ) +{ + if ( EVENT_KEYINPUT == _rNEvt.GetType() ) + { + const KeyCode& rKeyCode = _rNEvt.GetKeyEvent()->GetKeyCode(); + if ( ( 0 == rKeyCode.GetModifier() ) && ( KEY_RETURN == rKeyCode.GetCode() ) ) + { + if ( createSelectionControls() ) + return 1; + } + } + + return SfxFloatingWindow::PreNotify( _rNEvt ); +} + +//----------------------------------------------------------------------- +sal_Bool FmFieldWin::Close() +{ + return SfxFloatingWindow::Close(); +} + +//----------------------------------------------------------------------- +void FmFieldWin::_propertyChanged(const ::com::sun::star::beans::PropertyChangeEvent& evt) throw( ::com::sun::star::uno::RuntimeException ) +{ + ::com::sun::star::uno::Reference< ::com::sun::star::form::XForm > xForm(evt.Source, ::com::sun::star::uno::UNO_QUERY); + UpdateContent(xForm); +} + +//----------------------------------------------------------------------- +void FmFieldWin::StateChanged(sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState) +{ + if (!pState || SID_FM_FIELDS_CONTROL != nSID) + return; + + if (eState >= SFX_ITEM_AVAILABLE) + { + FmFormShell* pShell = PTR_CAST(FmFormShell,((SfxObjectItem*)pState)->GetShell()); + UpdateContent(pShell); + } + else + UpdateContent(NULL); +} + +//----------------------------------------------------------------------- +void FmFieldWin::UpdateContent(FmFormShell* pShell) +{ + pListBox->Clear(); + String aTitle( SVX_RES( RID_STR_FIELDSELECTION ) ); + SetText( aTitle ); + + if (!pShell || !pShell->GetImpl()) + return; + + Reference< XForm > xForm = pShell->GetImpl()->getCurrentForm(); + if ( xForm.is() ) + UpdateContent( xForm ); +} + +//----------------------------------------------------------------------- +void FmFieldWin::UpdateContent(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XForm > & xForm) +{ + try + { + // ListBox loeschen + pListBox->Clear(); + UniString aTitle(SVX_RES(RID_STR_FIELDSELECTION)); + SetText(aTitle); + + if (!xForm.is()) + return; + + Reference< XPreparedStatement > xStatement; + Reference< XPropertySet > xSet(xForm, UNO_QUERY); + + m_aObjectName = ::comphelper::getString(xSet->getPropertyValue(FM_PROP_COMMAND)); + m_aDatabaseName = ::comphelper::getString(xSet->getPropertyValue(FM_PROP_DATASOURCE)); + m_nObjectType = ::comphelper::getINT32(xSet->getPropertyValue(FM_PROP_COMMANDTYPE)); + + // get the connection of the form + OStaticDataAccessTools aTools; + m_aConnection.reset( + aTools.connectRowset( Reference< XRowSet >( xForm, UNO_QUERY ), ::comphelper::getProcessServiceFactory(), sal_True ), + SharedConnection::NoTakeOwnership + ); + // TODO: When incompatible changes (such as extending the "virtualdbtools" interface by ensureRowSetConnection) + // are allowed, again, we should change this: dbtools should consistently use SharedConnection all over + // the place, and connectRowset should be replaced with ensureRowSetConnection + + // get the fields of the object + Sequence< ::rtl::OUString> aFieldNames; + if ( m_aConnection.is() && m_aObjectName.getLength() ) + aFieldNames = getFieldNamesByCommandDescriptor( m_aConnection, m_nObjectType, m_aObjectName ); + + // put them into the list + const ::rtl::OUString* pFieldNames = aFieldNames.getConstArray(); + sal_Int32 nFieldsCount = aFieldNames.getLength(); + for ( sal_Int32 i = 0; i < nFieldsCount; ++i, ++pFieldNames) + pListBox->InsertEntry( * pFieldNames); + + // Prefix setzen + UniString aPrefix; + StringListResource aPrefixes( SVX_RES( RID_RSC_TABWIN_PREFIX ) ); + + switch (m_nObjectType) + { + case CommandType::TABLE: + aPrefix = aPrefixes[0]; + break; + case CommandType::QUERY: + aPrefix = aPrefixes[1]; + break; + default: + aPrefix = aPrefixes[2]; + break; + } + + // an dem PropertySet nach Aenderungen der ControlSource lauschen + if (m_pChangeListener) + { + m_pChangeListener->dispose(); + m_pChangeListener->release(); + } + m_pChangeListener = new ::comphelper::OPropertyChangeMultiplexer(this, xSet); + m_pChangeListener->acquire(); + m_pChangeListener->addProperty(FM_PROP_DATASOURCE); + m_pChangeListener->addProperty(FM_PROP_COMMAND); + m_pChangeListener->addProperty(FM_PROP_COMMANDTYPE); + + // Titel setzen + aTitle.AppendAscii(" "); + aTitle += aPrefix; + aTitle.AppendAscii(" "); + aTitle += m_aObjectName.getStr(); + SetText( aTitle ); + } + catch( const Exception& ) + { + DBG_ERROR( "FmTabWin::UpdateContent: caught an exception!" ); + } +} + +//----------------------------------------------------------------------- +void FmFieldWin::Resize() +{ + SfxFloatingWindow::Resize(); + + Point aPos(GetPosPixel()); + Size aOutputSize( GetOutputSizePixel() ); + + ////////////////////////////////////////////////////////////////////// + + // Groesse der ::com::sun::star::form::ListBox anpassen + Point aLBPos( LISTBOX_BORDER, LISTBOX_BORDER ); + Size aLBSize( aOutputSize ); + aLBSize.Width() -= (2*LISTBOX_BORDER); + aLBSize.Height() -= (2*LISTBOX_BORDER); + + pListBox->SetPosSizePixel( aLBPos, aLBSize ); +} + +//----------------------------------------------------------------------- +void FmFieldWin::FillInfo( SfxChildWinInfo& rInfo ) const +{ + rInfo.bVisible = sal_False; +} + +//----------------------------------------------------------------------- +SFX_IMPL_FLOATINGWINDOW(FmFieldWinMgr, SID_FM_ADD_FIELD) + +//----------------------------------------------------------------------- +FmFieldWinMgr::FmFieldWinMgr(Window* _pParent, sal_uInt16 _nId, + SfxBindings* _pBindings, SfxChildWinInfo* _pInfo) + :SfxChildWindow(_pParent, _nId) +{ + pWindow = new FmFieldWin(_pBindings, this, _pParent); + SetHideNotDelete(sal_True); + eChildAlignment = SFX_ALIGN_NOALIGNMENT; + ((SfxFloatingWindow*)pWindow)->Initialize( _pInfo ); +} + + |