merge the formfield patch from ooo-build
[ooovba.git] / svx / source / form / tabwin.cxx
blob0ad90624613e1ac557a39e110f92d2d0358e3d3d
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: tabwin.cxx,v $
10 * $Revision: 1.28 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
34 #include "tabwin.hxx"
35 #include "fmtools.hxx"
36 #include "fmservs.hxx"
37 #include "stringlistresource.hxx"
39 #include <svx/svxids.hrc>
40 #include <svx/dbaexchange.hxx>
41 #include <com/sun/star/sdb/CommandType.hpp>
42 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
43 #include <com/sun/star/sdb/XQueriesSupplier.hpp>
44 #include <com/sun/star/sdbc/XPreparedStatement.hpp>
45 #include <com/sun/star/awt/XControlContainer.hpp>
46 #include <com/sun/star/util/XLocalizedAliases.hpp>
47 #include <comphelper/processfactory.hxx>
48 #include <comphelper/stl_types.hxx>
50 #ifndef _SVX_FMHELP_HRC
51 #include "fmhelp.hrc"
52 #endif
53 #include <svx/fmshell.hxx>
54 #include "fmshimp.hxx"
55 #include "svx/dbtoolsclient.hxx"
56 #include <svx/fmpage.hxx>
58 #ifndef _SVX_FMPGEIMP_HXX
59 #include "fmpgeimp.hxx"
60 #endif
62 #ifndef _SVX_FMPROP_HRC
63 #include "fmprop.hrc"
64 #endif
66 #ifndef _SVX_FMRESIDS_HRC
67 #include "fmresids.hrc"
68 #endif
69 #include <svx/dialmgr.hxx>
70 #include <tools/shl.hxx>
71 #include <svx/svdpagv.hxx>
72 #include <sfx2/objitem.hxx>
73 #include <sfx2/dispatch.hxx>
74 #include <comphelper/property.hxx>
75 #include <sfx2/frame.hxx>
76 #include <svx/dataaccessdescriptor.hxx>
78 const long STD_WIN_POS_X = 50;
79 const long STD_WIN_POS_Y = 50;
81 const long STD_WIN_SIZE_X = 120;
82 const long STD_WIN_SIZE_Y = 150;
84 const long MIN_WIN_SIZE_X = 50;
85 const long MIN_WIN_SIZE_Y = 50;
87 const long LISTBOX_BORDER = 2;
89 using namespace ::com::sun::star::sdbc;
90 using namespace ::com::sun::star::sdb;
91 using namespace ::com::sun::star::uno;
92 using namespace ::com::sun::star::datatransfer;
93 using namespace ::com::sun::star::beans;
94 using namespace ::com::sun::star::lang;
95 using namespace ::com::sun::star::form;
96 using namespace ::com::sun::star::container;
97 using namespace ::svxform;
98 using namespace ::svx;
100 //==================================================================
101 // class FmFieldWinListBox
102 //==================================================================
103 DBG_NAME(FmFieldWinListBox)
104 //------------------------------------------------------------------------------
105 FmFieldWinListBox::FmFieldWinListBox( FmFieldWin* pParent )
106 :SvTreeListBox( pParent, WB_HASBUTTONS|WB_BORDER )
107 ,pTabWin( pParent )
109 DBG_CTOR(FmFieldWinListBox,NULL);
110 SetHelpId( HID_FIELD_SEL );
112 SetHighlightRange( );
115 //------------------------------------------------------------------------------
116 FmFieldWinListBox::~FmFieldWinListBox()
118 DBG_DTOR(FmFieldWinListBox,NULL);
121 //------------------------------------------------------------------------------
122 sal_Int8 FmFieldWinListBox::AcceptDrop( const AcceptDropEvent& /*rEvt*/ )
124 return DND_ACTION_NONE;
127 //------------------------------------------------------------------------------
128 sal_Int8 FmFieldWinListBox::ExecuteDrop( const ExecuteDropEvent& /*rEvt*/ )
130 return DND_ACTION_NONE;
133 //------------------------------------------------------------------------------
134 BOOL FmFieldWinListBox::DoubleClickHdl()
136 if ( pTabWin->createSelectionControls() )
137 return sal_True;
139 return SvTreeListBox::DoubleClickHdl();
142 //------------------------------------------------------------------------------
143 void FmFieldWinListBox::StartDrag( sal_Int8 /*_nAction*/, const Point& /*_rPosPixel*/ )
145 SvLBoxEntry* pSelected = FirstSelected();
146 if (!pSelected)
147 // no drag without a field
148 return;
150 ::svx::ODataAccessDescriptor aDescriptor;
151 aDescriptor[ daDataSource ] <<= pTabWin->GetDatabaseName();
152 aDescriptor[ daConnection ] <<= pTabWin->GetConnection().getTyped();
153 aDescriptor[ daCommand ] <<= pTabWin->GetObjectName();
154 aDescriptor[ daCommandType ]<<= pTabWin->GetObjectType();
155 aDescriptor[ daColumnName ] <<= ::rtl::OUString( GetEntryText( pSelected ) );
157 TransferableHelper* pTransferColumn = new OColumnTransferable(
158 aDescriptor, CTF_FIELD_DESCRIPTOR | CTF_CONTROL_EXCHANGE | CTF_COLUMN_DESCRIPTOR
160 Reference< XTransferable> xEnsureDelete = pTransferColumn;
161 if (pTransferColumn)
163 EndSelection();
164 pTransferColumn->StartDrag( this, DND_ACTION_COPY );
168 //========================================================================
169 // class FmFieldWinData
170 //========================================================================
171 DBG_NAME(FmFieldWinData);
172 //-----------------------------------------------------------------------
173 FmFieldWinData::FmFieldWinData()
175 DBG_CTOR(FmFieldWinData,NULL);
178 //-----------------------------------------------------------------------
179 FmFieldWinData::~FmFieldWinData()
181 DBG_DTOR(FmFieldWinData,NULL);
184 //========================================================================
185 // class FmFieldWin
186 //========================================================================
187 DBG_NAME(FmFieldWin);
188 //-----------------------------------------------------------------------
189 FmFieldWin::FmFieldWin(SfxBindings* _pBindings, SfxChildWindow* _pMgr, Window* _pParent)
190 :SfxFloatingWindow(_pBindings, _pMgr, _pParent, WinBits(WB_STDMODELESS|WB_SIZEABLE))
191 ,SfxControllerItem(SID_FM_FIELDS_CONTROL, *_pBindings)
192 ,::comphelper::OPropertyChangeListener(m_aMutex)
193 ,pData(new FmFieldWinData)
194 ,m_nObjectType(0)
195 ,m_pChangeListener(NULL)
197 DBG_CTOR(FmFieldWin,NULL);
198 SetHelpId( HID_FIELD_SEL_WIN );
200 SetBackground( Wallpaper( Application::GetSettings().GetStyleSettings().GetFaceColor()) );
201 pListBox = new FmFieldWinListBox( this );
202 pListBox->Show();
203 UpdateContent(NULL);
204 SetSizePixel(Size(STD_WIN_SIZE_X,STD_WIN_SIZE_Y));
207 //-----------------------------------------------------------------------
208 FmFieldWin::~FmFieldWin()
210 if (m_pChangeListener)
212 m_pChangeListener->dispose();
213 m_pChangeListener->release();
214 // delete m_pChangeListener;
216 delete pListBox;
217 delete pData;
218 DBG_DTOR(FmFieldWin,NULL);
221 //-----------------------------------------------------------------------
222 void FmFieldWin::GetFocus()
224 if ( pListBox )
225 pListBox->GrabFocus();
226 else
227 SfxFloatingWindow::GetFocus();
230 //-----------------------------------------------------------------------
231 sal_Bool FmFieldWin::createSelectionControls( )
233 SvLBoxEntry* pSelected = pListBox->FirstSelected();
234 if ( pSelected )
236 // build a descriptor for the currently selected field
237 ODataAccessDescriptor aDescr;
238 aDescr.setDataSource(GetDatabaseName());
240 aDescr[ daConnection ] <<= GetConnection().getTyped();
242 aDescr[ daCommand ] <<= GetObjectName();
243 aDescr[ daCommandType ] <<= GetObjectType();
244 aDescr[ daColumnName ] <<= ::rtl::OUString( pListBox->GetEntryText( pSelected) );
246 // transfer this to the SFX world
247 SfxUnoAnyItem aDescriptorItem( SID_FM_DATACCESS_DESCRIPTOR, makeAny( aDescr.createPropertyValueSequence() ) );
248 const SfxPoolItem* pArgs[] =
250 &aDescriptorItem, NULL
253 // execute the create slot
254 GetBindings().Execute( SID_FM_CREATE_FIELDCONTROL, pArgs );
257 return NULL != pSelected;
260 //-----------------------------------------------------------------------
261 long FmFieldWin::PreNotify( NotifyEvent& _rNEvt )
263 if ( EVENT_KEYINPUT == _rNEvt.GetType() )
265 const KeyCode& rKeyCode = _rNEvt.GetKeyEvent()->GetKeyCode();
266 if ( ( 0 == rKeyCode.GetModifier() ) && ( KEY_RETURN == rKeyCode.GetCode() ) )
268 if ( createSelectionControls() )
269 return 1;
273 return SfxFloatingWindow::PreNotify( _rNEvt );
276 //-----------------------------------------------------------------------
277 sal_Bool FmFieldWin::Close()
279 return SfxFloatingWindow::Close();
282 //-----------------------------------------------------------------------
283 void FmFieldWin::_propertyChanged(const ::com::sun::star::beans::PropertyChangeEvent& evt) throw( ::com::sun::star::uno::RuntimeException )
285 ::com::sun::star::uno::Reference< ::com::sun::star::form::XForm > xForm(evt.Source, ::com::sun::star::uno::UNO_QUERY);
286 UpdateContent(xForm);
289 //-----------------------------------------------------------------------
290 void FmFieldWin::StateChanged(sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState)
292 if (!pState || SID_FM_FIELDS_CONTROL != nSID)
293 return;
295 if (eState >= SFX_ITEM_AVAILABLE)
297 FmFormShell* pShell = PTR_CAST(FmFormShell,((SfxObjectItem*)pState)->GetShell());
298 UpdateContent(pShell);
300 else
301 UpdateContent(NULL);
304 //-----------------------------------------------------------------------
305 void FmFieldWin::UpdateContent(FmFormShell* pShell)
307 pListBox->Clear();
308 String aTitle( SVX_RES( RID_STR_FIELDSELECTION ) );
309 SetText( aTitle );
311 if (!pShell || !pShell->GetImpl())
312 return;
314 Reference< XForm > xForm = pShell->GetImpl()->getCurrentForm();
315 if ( xForm.is() )
316 UpdateContent( xForm );
319 //-----------------------------------------------------------------------
320 void FmFieldWin::UpdateContent(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XForm > & xForm)
324 // ListBox loeschen
325 pListBox->Clear();
326 UniString aTitle(SVX_RES(RID_STR_FIELDSELECTION));
327 SetText(aTitle);
329 if (!xForm.is())
330 return;
332 Reference< XPreparedStatement > xStatement;
333 Reference< XPropertySet > xSet(xForm, UNO_QUERY);
335 m_aObjectName = ::comphelper::getString(xSet->getPropertyValue(FM_PROP_COMMAND));
336 m_aDatabaseName = ::comphelper::getString(xSet->getPropertyValue(FM_PROP_DATASOURCE));
337 m_nObjectType = ::comphelper::getINT32(xSet->getPropertyValue(FM_PROP_COMMANDTYPE));
339 // get the connection of the form
340 OStaticDataAccessTools aTools;
341 m_aConnection.reset(
342 aTools.connectRowset( Reference< XRowSet >( xForm, UNO_QUERY ), ::comphelper::getProcessServiceFactory(), sal_True ),
343 SharedConnection::NoTakeOwnership
345 // TODO: When incompatible changes (such as extending the "virtualdbtools" interface by ensureRowSetConnection)
346 // are allowed, again, we should change this: dbtools should consistently use SharedConnection all over
347 // the place, and connectRowset should be replaced with ensureRowSetConnection
349 // get the fields of the object
350 Sequence< ::rtl::OUString> aFieldNames;
351 if ( m_aConnection.is() && m_aObjectName.getLength() )
352 aFieldNames = getFieldNamesByCommandDescriptor( m_aConnection, m_nObjectType, m_aObjectName );
354 // put them into the list
355 const ::rtl::OUString* pFieldNames = aFieldNames.getConstArray();
356 sal_Int32 nFieldsCount = aFieldNames.getLength();
357 for ( sal_Int32 i = 0; i < nFieldsCount; ++i, ++pFieldNames)
358 pListBox->InsertEntry( * pFieldNames);
360 // Prefix setzen
361 UniString aPrefix;
362 StringListResource aPrefixes( SVX_RES( RID_RSC_TABWIN_PREFIX ) );
364 switch (m_nObjectType)
366 case CommandType::TABLE:
367 aPrefix = aPrefixes[0];
368 break;
369 case CommandType::QUERY:
370 aPrefix = aPrefixes[1];
371 break;
372 default:
373 aPrefix = aPrefixes[2];
374 break;
377 // an dem PropertySet nach Aenderungen der ControlSource lauschen
378 if (m_pChangeListener)
380 m_pChangeListener->dispose();
381 m_pChangeListener->release();
383 m_pChangeListener = new ::comphelper::OPropertyChangeMultiplexer(this, xSet);
384 m_pChangeListener->acquire();
385 m_pChangeListener->addProperty(FM_PROP_DATASOURCE);
386 m_pChangeListener->addProperty(FM_PROP_COMMAND);
387 m_pChangeListener->addProperty(FM_PROP_COMMANDTYPE);
389 // Titel setzen
390 aTitle.AppendAscii(" ");
391 aTitle += aPrefix;
392 aTitle.AppendAscii(" ");
393 aTitle += m_aObjectName.getStr();
394 SetText( aTitle );
396 catch( const Exception& )
398 DBG_ERROR( "FmTabWin::UpdateContent: caught an exception!" );
402 //-----------------------------------------------------------------------
403 void FmFieldWin::Resize()
405 SfxFloatingWindow::Resize();
407 Point aPos(GetPosPixel());
408 Size aOutputSize( GetOutputSizePixel() );
410 //////////////////////////////////////////////////////////////////////
412 // Groesse der ::com::sun::star::form::ListBox anpassen
413 Point aLBPos( LISTBOX_BORDER, LISTBOX_BORDER );
414 Size aLBSize( aOutputSize );
415 aLBSize.Width() -= (2*LISTBOX_BORDER);
416 aLBSize.Height() -= (2*LISTBOX_BORDER);
418 pListBox->SetPosSizePixel( aLBPos, aLBSize );
421 //-----------------------------------------------------------------------
422 void FmFieldWin::FillInfo( SfxChildWinInfo& rInfo ) const
424 rInfo.bVisible = sal_False;
427 //-----------------------------------------------------------------------
428 SFX_IMPL_FLOATINGWINDOW(FmFieldWinMgr, SID_FM_ADD_FIELD)
430 //-----------------------------------------------------------------------
431 FmFieldWinMgr::FmFieldWinMgr(Window* _pParent, sal_uInt16 _nId,
432 SfxBindings* _pBindings, SfxChildWinInfo* _pInfo)
433 :SfxChildWindow(_pParent, _nId)
435 pWindow = new FmFieldWin(_pBindings, this, _pParent);
436 SetHideNotDelete(sal_True);
437 eChildAlignment = SFX_ALIGN_NOALIGNMENT;
438 ((SfxFloatingWindow*)pWindow)->Initialize( _pInfo );