| /************************************************************** |
| * |
| * 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 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the 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 "svx/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 ::com::sun::star; |
| using namespace ::svxform; |
| using namespace ::svx; |
| |
| |
| struct ColumnInfo |
| { |
| ::rtl::OUString sColumnName; |
| ::rtl::OUString sLabel; |
| bool bColumn; |
| ColumnInfo(const ::rtl::OUString& i_sColumnName,const ::rtl::OUString& i_sLabel) |
| : sColumnName(i_sColumnName) |
| , sLabel(i_sLabel) |
| , bColumn(true) |
| { |
| } |
| ColumnInfo(const ::rtl::OUString& i_sColumnName) |
| : sColumnName(i_sColumnName) |
| , bColumn(false) |
| { |
| } |
| }; |
| |
| void lcl_addToList( SvTreeListBox& _rListBox, const uno::Reference< container::XNameAccess>& i_xColumns ) |
| { |
| uno::Sequence< ::rtl::OUString > aEntries = i_xColumns->getElementNames(); |
| const ::rtl::OUString* pEntries = aEntries.getConstArray(); |
| sal_Int32 nEntries = aEntries.getLength(); |
| for ( sal_Int32 i = 0; i < nEntries; ++i, ++pEntries ) |
| { |
| uno::Reference< beans::XPropertySet> xColumn(i_xColumns->getByName(*pEntries),UNO_QUERY_THROW); |
| ::rtl::OUString sLabel; |
| if ( xColumn->getPropertySetInfo()->hasPropertyByName(FM_PROP_LABEL) ) |
| xColumn->getPropertyValue(FM_PROP_LABEL) >>= sLabel; |
| if ( sLabel.getLength() ) |
| _rListBox.InsertEntry( sLabel,NULL,sal_False,LIST_APPEND,new ColumnInfo(*pEntries,sLabel) ); |
| else |
| _rListBox.InsertEntry( *pEntries,NULL,sal_False,LIST_APPEND,new ColumnInfo(*pEntries,sLabel) ); |
| } |
| } |
| //================================================================== |
| // 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; |
| } |
| |
| //------------------------------------------------------------------------------ |
| sal_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(); |
| ColumnInfo* pInfo = static_cast<ColumnInfo*>(pSelected->GetUserData()); |
| aDescriptor[ daColumnName ] <<= pInfo->sColumnName; |
| |
| 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(); |
| ColumnInfo* pInfo = static_cast<ColumnInfo*>(pSelected->GetUserData()); |
| aDescr[ daColumnName ] <<= pInfo->sColumnName;//::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 |
| |
| if ( m_aConnection.is() && m_aObjectName.getLength() ) |
| { |
| Reference< XComponent > xKeepFieldsAlive; |
| Reference< XNameAccess > xColumns = getFieldsByCommandDescriptor( m_aConnection, m_nObjectType, m_aObjectName,xKeepFieldsAlive ); |
| if ( xColumns.is() ) |
| lcl_addToList(*pListBox,xColumns); |
| } |
| |
| // 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 ); |
| } |
| |
| |