1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: tabwin.cxx,v $
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"
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
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"
62 #ifndef _SVX_FMPROP_HRC
66 #ifndef _SVX_FMRESIDS_HRC
67 #include "fmresids.hrc"
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
)
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() )
139 return SvTreeListBox::DoubleClickHdl();
142 //------------------------------------------------------------------------------
143 void FmFieldWinListBox::StartDrag( sal_Int8
/*_nAction*/, const Point
& /*_rPosPixel*/ )
145 SvLBoxEntry
* pSelected
= FirstSelected();
147 // no drag without a field
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
;
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 //========================================================================
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
)
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 );
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;
218 DBG_DTOR(FmFieldWin
,NULL
);
221 //-----------------------------------------------------------------------
222 void FmFieldWin::GetFocus()
225 pListBox
->GrabFocus();
227 SfxFloatingWindow::GetFocus();
230 //-----------------------------------------------------------------------
231 sal_Bool
FmFieldWin::createSelectionControls( )
233 SvLBoxEntry
* pSelected
= pListBox
->FirstSelected();
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() )
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
)
295 if (eState
>= SFX_ITEM_AVAILABLE
)
297 FmFormShell
* pShell
= PTR_CAST(FmFormShell
,((SfxObjectItem
*)pState
)->GetShell());
298 UpdateContent(pShell
);
304 //-----------------------------------------------------------------------
305 void FmFieldWin::UpdateContent(FmFormShell
* pShell
)
308 String
aTitle( SVX_RES( RID_STR_FIELDSELECTION
) );
311 if (!pShell
|| !pShell
->GetImpl())
314 Reference
< XForm
> xForm
= pShell
->GetImpl()->getCurrentForm();
316 UpdateContent( xForm
);
319 //-----------------------------------------------------------------------
320 void FmFieldWin::UpdateContent(const ::com::sun::star::uno::Reference
< ::com::sun::star::form::XForm
> & xForm
)
326 UniString
aTitle(SVX_RES(RID_STR_FIELDSELECTION
));
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
;
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
);
362 StringListResource
aPrefixes( SVX_RES( RID_RSC_TABWIN_PREFIX
) );
364 switch (m_nObjectType
)
366 case CommandType::TABLE
:
367 aPrefix
= aPrefixes
[0];
369 case CommandType::QUERY
:
370 aPrefix
= aPrefixes
[1];
373 aPrefix
= aPrefixes
[2];
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
);
390 aTitle
.AppendAscii(" ");
392 aTitle
.AppendAscii(" ");
393 aTitle
+= m_aObjectName
.getStr();
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
);