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: sbagrid.cxx,v $
10 * $Revision: 1.83.6.3 $
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_dbaccess.hxx"
34 #ifndef DBACCESS_SBA_GRID_HRC
35 #include "sbagrid.hrc"
38 #ifndef _SVX_SVXIDS_HRC
39 #include <svx/svxids.hrc>
42 #define ITEMID_HORJUSTIFY SID_ATTR_ALIGN_HOR_JUSTIFY
43 #define ITEMID_VERJUSTIFY SID_ATTR_ALIGN_VER_JUSTIFY
44 //#define ITEMID_ORIENTATION SID_ATTR_ALIGN_ORIENTATION
45 #define ITEMID_LINEBREAK SID_ATTR_ALIGN_LINEBREAK
46 #define ITEMID_MARGIN SID_ATTR_ALIGN_MARGIN
47 #define ITEMID_NUMBERINFO SID_ATTR_NUMBERFORMAT_INFO
50 #define _ZFORLIST_DECLARE_TABLE
51 #ifndef _SVX_NUMINF_HXX
52 #include <svx/numinf.hxx>
54 #ifndef _SVX_DBAEXCHANGE_HXX_
55 #include <svx/dbaexchange.hxx>
57 #ifndef _COM_SUN_STAR_UI_DIALOGS_XEXECUTABLEDIALOG_HPP_
58 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
62 #include "sbagrid.hxx"
64 #ifndef DBAUI_SBATTRDLG_HXX
65 #include "dlgattr.hxx"
67 #ifndef _DBAUI_DLGSIZE_HXX
68 #include "dlgsize.hxx"
70 #ifndef _COM_SUN_STAR_FORM_XLOADABLE_HPP_
71 #include <com/sun/star/form/XLoadable.hpp>
73 #ifndef _COM_SUN_STAR_SDB_COMMANDTYPE_HPP_
74 #include <com/sun/star/sdb/CommandType.hpp>
76 #ifndef _COM_SUN_STAR_SDB_XSQLQUERYCOMPOSERFACTORY_HPP_
77 #include <com/sun/star/sdb/XSQLQueryComposerFactory.hpp>
79 #ifndef _COM_SUN_STAR_SDB_XRESULTSETACCESS_HPP_
80 #include <com/sun/star/sdb/XResultSetAccess.hpp>
82 #ifndef _COM_SUN_STAR_FORM_XFORM_HPP_
83 #include <com/sun/star/form/XForm.hpp>
85 #ifndef _COM_SUN_STAR_CONTAINER_XINDEXCONTAINER_HPP_
86 #include <com/sun/star/container/XIndexContainer.hpp>
88 #ifndef _COM_SUN_STAR_UTIL_NUMBERFORMAT_HPP_
89 #include <com/sun/star/util/NumberFormat.hpp>
92 #ifndef _COM_SUN_STAR_VIEW_XSELECTIONSUPPLIER_HPP_
93 #include <com/sun/star/view/XSelectionSupplier.hpp>
95 #ifndef _COM_SUN_STAR_FORM_DATASELECTIONTYPE_HPP_
96 #include <com/sun/star/form/DataSelectionType.hpp>
98 #ifndef _COM_SUN_STAR_AWT_TEXTALIGN_HPP_
99 #include <com/sun/star/awt/TextAlign.hpp>
101 #ifndef _COM_SUN_STAR_AWT_XTEXTCOMPONENT_HPP_
102 #include <com/sun/star/awt/XTextComponent.hpp>
104 #ifndef _COM_SUN_STAR_UTIL_DATE_HPP_
105 #include <com/sun/star/util/Date.hpp>
107 #ifndef _COM_SUN_STAR_UTIL_TIME_HPP_
108 #include <com/sun/star/util/Time.hpp>
110 #ifndef _COM_SUN_STAR_UTIL_DATETIME_HPP_
111 #include <com/sun/star/util/DateTime.hpp>
113 #ifndef _COM_SUN_STAR_SDBC_XRESULTSETUPDATE_HPP_
114 #include <com/sun/star/sdbc/XResultSetUpdate.hpp>
117 #include <tools/urlobj.hxx>
119 #ifndef TOOLS_DIAGNOSE_EX_H
120 #include <tools/diagnose_ex.h>
123 #ifndef _SFXINTITEM_HXX
124 #include <svtools/intitem.hxx>
127 #ifndef _SVX_ALGITEM_HXX //autogen
128 #include <svx/algitem.hxx>
131 #ifndef _SV_MULTISEL_HXX //autogen
132 #include <tools/multisel.hxx>
135 #ifndef _SVX_SVXIDS_HRC
136 #include <svx/svxids.hrc>
140 #include <svtools/numuno.hxx>
143 #ifndef _SFXITEMPOOL_HXX //autogen wg. SfxItemInfo
144 #include <svtools/itempool.hxx>
147 #ifndef _SFXITEMSET_HXX //autogen wg. SfxItemSet
148 #include <svtools/itemset.hxx>
151 #ifndef _SFXRNGITEM_HXX
152 #include <svtools/rngitem.hxx>
155 #ifndef _SV_WAITOBJ_HXX
156 #include <vcl/waitobj.hxx>
158 #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
159 #include <toolkit/helper/vclunohelper.hxx>
162 #ifndef _ZFORLIST_HXX
163 #include <svtools/zforlist.hxx>
165 #ifndef _CPPUHELPER_QUERYINTERFACE_HXX_
166 #include <cppuhelper/queryinterface.hxx>
168 #ifndef _CONNECTIVITY_DBTOOLS_HXX_
169 #include <connectivity/dbtools.hxx>
171 #ifndef _DBHELPER_DBCONVERSION_HXX_
172 #include <connectivity/dbconversion.hxx>
174 #ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
175 #include <cppuhelper/typeprovider.hxx>
178 #include <rtl/uuid.h>
180 #ifndef _RTL_MEMORY_H_
181 #include <rtl/memory.h>
183 #ifndef _COMPHELPER_EXTRACT_HXX_
184 #include <comphelper/extract.hxx>
186 #ifndef _COM_SUN_STAR_SDBCX_XTABLESSUPPLIER_HPP_
187 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
189 #ifndef _COM_SUN_STAR_SDBC_DATATYPE_HPP_
190 #include <com/sun/star/sdbc/DataType.hpp>
192 #ifndef _SV_MSGBOX_HXX
193 #include <vcl/msgbox.hxx>
195 #ifndef _SVX_DBEXCH_HRC
196 #include <svx/dbexch.hrc>
198 #ifndef _DBU_BRW_HRC_
199 #include "dbu_brw.hrc"
201 #ifndef DBACCESS_UI_BROWSER_ID_HXX
202 #include "browserids.hxx"
204 #ifndef DBACCESS_SHARED_DBUSTRINGS_HRC
205 #include "dbustrings.hrc"
207 #ifndef _DBU_REGHELPER_HXX_
208 #include "dbu_reghelper.hxx"
210 #ifndef DBAUI_DBEXCHANGE_HXX
211 #include "dbexchange.hxx"
213 #ifndef DBAUI_TABLEROW_EXCHANGE_HXX
214 #include "TableRowExchange.hxx"
216 #ifndef DBAUI_TABLEROW_HXX
217 #include "TableRow.hxx"
219 #ifndef DBAUI_FIELDDESCRIPTIONS_HXX
220 #include "FieldDescriptions.hxx"
222 #ifndef _SVTOOLS_STRINGTRANSFER_HXX_
223 #include <svtools/stringtransfer.hxx>
225 #ifndef _VCL_STDTEXT_HXX
226 #include <vcl/stdtext.hxx>
228 #ifndef DBAUI_TOOLS_HXX
229 #include "UITools.hxx"
231 #ifndef DBAUI_TOKENWRITER_HXX
232 #include "TokenWriter.hxx"
235 using namespace ::com::sun::star::ui::dialogs
;
236 using namespace ::com::sun::star::uno
;
237 using namespace ::com::sun::star::sdb
;
238 using namespace ::com::sun::star::sdbc
;
239 using namespace ::com::sun::star::sdbcx
;
240 using namespace ::com::sun::star::beans
;
241 using namespace ::com::sun::star::container
;
242 using namespace ::com::sun::star::datatransfer
;
243 using namespace ::com::sun::star::lang
;
244 using namespace ::com::sun::star::view
;
245 using namespace ::com::sun::star::form
;
246 using namespace ::com::sun::star::frame
;
247 using namespace ::com::sun::star::util
;
248 using namespace ::dbaui
;
249 using namespace ::dbtools
;
250 using namespace ::svx
;
251 using namespace ::svt
;
253 extern "C" void SAL_CALL
createRegistryInfo_SbaXGridControl()
255 static OMultiInstanceAutoRegistration
< SbaXGridControl
> aAutoRegistration
;
257 //-------------------------------------------------------------------------
258 ::comphelper::StringSequence SAL_CALL
SbaXGridControl::getSupportedServiceNames() throw()
260 return getSupportedServiceNames_Static();
262 // -------------------------------------------------------------------------
263 Reference
< XInterface
> SAL_CALL
SbaXGridControl::Create(const Reference
<XMultiServiceFactory
>& _rxFactory
)
265 return *(new SbaXGridControl(_rxFactory
));
268 //------------------------------------------------------------------
270 //------------------------------------------------------------------
271 //=======================================================================================
273 //=======================================================================================
275 //------------------------------------------------------------------------------
276 ::rtl::OUString SAL_CALL
SbaXGridControl::getImplementationName() throw()
278 return getImplementationName_Static();
281 //------------------------------------------------------------------------------
282 ::rtl::OUString
SbaXGridControl::getImplementationName_Static() throw( RuntimeException
)
284 return ::rtl::OUString::createFromAscii("com.sun.star.comp.dbu.SbaXGridControl");
287 //------------------------------------------------------------------------------
288 Sequence
< ::rtl::OUString
> SbaXGridControl::getSupportedServiceNames_Static(void) throw( RuntimeException
)
290 Sequence
< ::rtl::OUString
> aSupported(3);
291 aSupported
[0] = ::rtl::OUString::createFromAscii("com.sun.star.form.control.InteractionGridControl");
292 aSupported
[1] = ::rtl::OUString::createFromAscii("com.sun.star.form.control.GridControl");
293 aSupported
[2] = ::rtl::OUString::createFromAscii("com.sun.star.awt.UnoControl");
296 DBG_NAME(SbaXGridControl
);
297 //---------------------------------------------------------------------------------------
298 SbaXGridControl::SbaXGridControl(const Reference
< XMultiServiceFactory
>& _rM
)
299 : FmXGridControl(_rM
)
301 DBG_CTOR(SbaXGridControl
,NULL
);
304 //---------------------------------------------------------------------------------------
305 SbaXGridControl::~SbaXGridControl()
307 DBG_DTOR(SbaXGridControl
,NULL
);
310 //---------------------------------------------------------------------------------------
311 FmXGridPeer
* SbaXGridControl::imp_CreatePeer(Window
* pParent
)
313 FmXGridPeer
* pReturn
= new SbaXGridPeer(m_xServiceFactory
);
315 // translate properties into WinBits
316 WinBits nStyle
= WB_TABSTOP
;
317 Reference
< XPropertySet
> xModelSet(getModel(), UNO_QUERY
);
322 if (::comphelper::getINT16(xModelSet
->getPropertyValue(PROPERTY_BORDER
)))
331 pReturn
->Create(pParent
, nStyle
);
335 //------------------------------------------------------------------------------
336 Any SAL_CALL
SbaXGridControl::queryInterface(const Type
& _rType
) throw (RuntimeException
)
338 Any aRet
= FmXGridControl::queryInterface(_rType
);
339 return aRet
.hasValue() ? aRet
: ::cppu::queryInterface(_rType
,(::com::sun::star::frame::XDispatch
*)this);
342 //------------------------------------------------------------------------------
343 Sequence
< Type
> SAL_CALL
SbaXGridControl::getTypes( ) throw (RuntimeException
)
345 Sequence
< Type
> aTypes
= FmXGridControl::getTypes();
347 sal_Int32 nTypes
= aTypes
.getLength();
348 aTypes
.realloc(nTypes
+ 1);
349 aTypes
[nTypes
] = ::getCppuType(static_cast< Reference
< ::com::sun::star::frame::XDispatch
>* >(NULL
));
354 //------------------------------------------------------------------------------
355 Sequence
< sal_Int8
> SAL_CALL
SbaXGridControl::getImplementationId( ) throw (RuntimeException
)
357 static ::cppu::OImplementationId
* pId
= 0;
360 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
363 static ::cppu::OImplementationId aId
;
367 return pId
->getImplementationId();
370 //---------------------------------------------------------------------------------------
371 void SAL_CALL
SbaXGridControl::createPeer(const Reference
< ::com::sun::star::awt::XToolkit
> & rToolkit
, const Reference
< ::com::sun::star::awt::XWindowPeer
> & rParentPeer
) throw( RuntimeException
)
373 FmXGridControl::createPeer(rToolkit
, rParentPeer
);
375 DBG_ASSERT(/*(0 == m_nPeerCreationLevel) && */!mbCreatingPeer
, "FmXGridControl::createPeer : recursion!");
376 // see the base class' createPeer for a comment on this
377 // 14.05.2001 - 86836 - frank.schoenheit@germany.sun.com
379 // TODO: why the hell this whole class does not use any mutex?
381 // if (0 == m_nPeerCreationLevel)
383 Reference
< ::com::sun::star::frame::XDispatch
> xDisp(getPeer(), UNO_QUERY
);
384 for ( StatusMultiplexerArray::iterator aIter
= m_aStatusMultiplexer
.begin();
385 aIter
!= m_aStatusMultiplexer
.end();
388 if ((*aIter
).second
&& (*aIter
).second
->getLength())
389 xDisp
->addStatusListener((*aIter
).second
, (*aIter
).first
);
394 //---------------------------------------------------------------------------------------
395 void SAL_CALL
SbaXGridControl::dispatch(const ::com::sun::star::util::URL
& aURL
, const Sequence
< PropertyValue
>& aArgs
) throw( RuntimeException
)
397 Reference
< ::com::sun::star::frame::XDispatch
> xDisp(getPeer(), UNO_QUERY
);
399 xDisp
->dispatch(aURL
, aArgs
);
401 //---------------------------------------------------------------------------------------
402 void SAL_CALL
SbaXGridControl::addStatusListener( const Reference
< XStatusListener
> & _rxListener
, const URL
& _rURL
) throw( RuntimeException
)
404 ::osl::MutexGuard
aGuard( GetMutex() );
405 if ( _rxListener
.is() )
407 SbaXStatusMultiplexer
*& pMultiplexer
= m_aStatusMultiplexer
[ _rURL
];
410 pMultiplexer
= new SbaXStatusMultiplexer( *this, GetMutex() );
411 pMultiplexer
->acquire();
414 pMultiplexer
->addInterface( _rxListener
);
415 if ( getPeer().is() )
417 if ( 1 == pMultiplexer
->getLength() )
418 { // the first external listener for this URL
419 Reference
< XDispatch
> xDisp( getPeer(), UNO_QUERY
);
420 xDisp
->addStatusListener( pMultiplexer
, _rURL
);
423 { // already have other listeners for this URL
424 _rxListener
->statusChanged( pMultiplexer
->getLastEvent() );
430 //---------------------------------------------------------------------------------------
431 void SAL_CALL
SbaXGridControl::removeStatusListener(const Reference
< ::com::sun::star::frame::XStatusListener
> & _rxListener
, const ::com::sun::star::util::URL
& _rURL
) throw( RuntimeException
)
433 ::osl::MutexGuard
aGuard( GetMutex() );
435 SbaXStatusMultiplexer
*& pMultiplexer
= m_aStatusMultiplexer
[_rURL
];
438 pMultiplexer
= new SbaXStatusMultiplexer(*this,GetMutex());
439 pMultiplexer
->acquire();
442 if (getPeer().is() && pMultiplexer
->getLength() == 1)
444 Reference
< ::com::sun::star::frame::XDispatch
> xDisp(getPeer(), UNO_QUERY
);
445 xDisp
->removeStatusListener(pMultiplexer
, _rURL
);
447 pMultiplexer
->removeInterface( _rxListener
);
450 //---------------------------------------------------------------------------------------
451 void SAL_CALL
SbaXGridControl::dispose(void) throw( RuntimeException
)
453 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
458 for ( StatusMultiplexerArray::iterator aIter
= m_aStatusMultiplexer
.begin();
459 aIter
!= m_aStatusMultiplexer
.end();
464 (*aIter
).second
->disposeAndClear(aEvt
);
465 (*aIter
).second
->release();
466 (*aIter
).second
= NULL
;
469 StatusMultiplexerArray().swap(m_aStatusMultiplexer
);
471 FmXGridControl::dispose();
474 //=======================================================================================
476 //=======================================================================================
477 DBG_NAME(SbaXGridPeer
)
478 //---------------------------------------------------------------------------------------
479 SbaXGridPeer::SbaXGridPeer(const Reference
< XMultiServiceFactory
>& _rM
)
481 ,m_aStatusListeners(m_aMutex
)
483 DBG_CTOR(SbaXGridPeer
,NULL
);
486 //---------------------------------------------------------------------------------------
487 SbaXGridPeer::~SbaXGridPeer()
489 DBG_DTOR(SbaXGridPeer
,NULL
);
492 //---------------------------------------------------------------------------------------
493 void SAL_CALL
SbaXGridPeer::dispose(void) throw( RuntimeException
)
495 EventObject
aEvt(*this);
497 m_aStatusListeners
.disposeAndClear(aEvt
);
499 FmXGridPeer::dispose();
502 //---------------------------------------------------------------------------------------
503 void SbaXGridPeer::NotifyStatusChanged(const ::com::sun::star::util::URL
& _rUrl
, const Reference
< ::com::sun::star::frame::XStatusListener
> & xControl
)
505 SbaGridControl
* pGrid
= (SbaGridControl
*) GetWindow();
509 ::com::sun::star::frame::FeatureStateEvent aEvt
;
511 aEvt
.IsEnabled
= !pGrid
->IsReadOnlyDB();
512 aEvt
.FeatureURL
= _rUrl
;
514 ConstMapDispatchToBoolIterator aURLStatePos
= m_aDispatchStates
.find( classifyDispatchURL( _rUrl
) );
515 if ( m_aDispatchStates
.end() != aURLStatePos
)
516 aEvt
.State
<<= aURLStatePos
->second
;
518 aEvt
.State
<<= sal_False
;
521 xControl
->statusChanged(aEvt
);
524 ::cppu::OInterfaceContainerHelper
* pIter
= m_aStatusListeners
.getContainer(_rUrl
);
528 ::cppu::OInterfaceIteratorHelper
aListIter(*pIter
);
529 while (aListIter
.hasMoreElements())
530 ((::com::sun::star::frame::XStatusListener
*)aListIter
.next())->statusChanged(aEvt
);
535 //------------------------------------------------------------------------------
536 Any SAL_CALL
SbaXGridPeer::queryInterface(const Type
& _rType
) throw (RuntimeException
)
538 Any aRet
= ::cppu::queryInterface(_rType
,(::com::sun::star::frame::XDispatch
*)this);
541 return FmXGridPeer::queryInterface(_rType
);
544 //---------------------------------------------------------------------------------------
545 Reference
< ::com::sun::star::frame::XDispatch
> SAL_CALL
SbaXGridPeer::queryDispatch(const ::com::sun::star::util::URL
& aURL
, const ::rtl::OUString
& aTargetFrameName
, sal_Int32 nSearchFlags
) throw( RuntimeException
)
547 if ( (aURL
.Complete
.equals(::rtl::OUString::createFromAscii(".uno:GridSlots/BrowserAttribs")))
548 || (aURL
.Complete
.equals(::rtl::OUString::createFromAscii(".uno:GridSlots/RowHeight")))
549 || (aURL
.Complete
.equals(::rtl::OUString::createFromAscii(".uno:GridSlots/ColumnAttribs")))
550 || (aURL
.Complete
.equals(::rtl::OUString::createFromAscii(".uno:GridSlots/ColumnWidth")))
553 return (::com::sun::star::frame::XDispatch
*)this;
556 return FmXGridPeer::queryDispatch(aURL
, aTargetFrameName
, nSearchFlags
);
559 //---------------------------------------------------------------------------------------
560 IMPL_LINK( SbaXGridPeer
, OnDispatchEvent
, void*, /*NOTINTERESTEDIN*/ )
562 SbaGridControl
* pGrid
= static_cast< SbaGridControl
* >( GetWindow() );
563 if ( pGrid
) // if this fails, we were disposing before arriving here
565 if ( Application::GetMainThreadIdentifier() != ::vos::OThread::getCurrentIdentifier() )
567 // still not in the main thread (see SbaXGridPeer::dispatch). post an event, again
568 // without moving the special even to the back of the queue
569 pGrid
->PostUserEvent( LINK( this, SbaXGridPeer
, OnDispatchEvent
) );
573 DispatchArgs aArgs
= m_aDispatchArgs
.front();
574 m_aDispatchArgs
.pop();
576 SbaXGridPeer::dispatch( aArgs
.aURL
, aArgs
.aArgs
);
583 //---------------------------------------------------------------------------------------
584 SbaXGridPeer::DispatchType
SbaXGridPeer::classifyDispatchURL( const URL
& _rURL
)
586 DispatchType eURLType
= dtUnknown
;
587 if ( _rURL
.Complete
.equalsAscii( ".uno:GridSlots/BrowserAttribs" ) )
588 eURLType
= dtBrowserAttribs
;
589 else if ( _rURL
.Complete
.equalsAscii( ".uno:GridSlots/RowHeight" ) )
590 eURLType
= dtRowHeight
;
591 else if ( _rURL
.Complete
.equalsAscii( ".uno:GridSlots/ColumnAttribs" ) )
592 eURLType
= dtColumnAttribs
;
593 else if ( _rURL
.Complete
.equalsAscii( ".uno:GridSlots/ColumnWidth" ) )
594 eURLType
= dtColumnWidth
;
598 //---------------------------------------------------------------------------------------
599 void SAL_CALL
SbaXGridPeer::dispatch(const URL
& aURL
, const Sequence
< PropertyValue
>& aArgs
) throw( RuntimeException
)
601 SbaGridControl
* pGrid
= (SbaGridControl
*)GetWindow();
605 if ( Application::GetMainThreadIdentifier() != ::vos::OThread::getCurrentIdentifier() )
607 // we're not in the main thread. This is bad, as we want to raise windows here,
608 // and VCL does not like windows to be opened in non-main threads (at least on Win32).
609 // Okay, do this async. No problem with this, as XDispatch::dispatch is defined to be
613 DispatchArgs aDispatchArgs
;
614 aDispatchArgs
.aURL
= aURL
;
615 aDispatchArgs
.aArgs
= aArgs
;
616 m_aDispatchArgs
.push( aDispatchArgs
);
619 // we use the Window::PostUserEvent here, instead of the application::PostUserEvent
620 // this saves us from keeping track of these events - as soon as the window dies,
621 // the events are deleted automatically. For the application way, we would need to
623 // As we use our grid as window, and the grid dies before we dy, this should be no problem.
624 pGrid
->PostUserEvent( LINK( this, SbaXGridPeer
, OnDispatchEvent
) );
628 ::vos::OGuard
aGuard(Application::GetSolarMutex());
629 sal_Int16 nColId
= -1;
630 const PropertyValue
* pArgs
= aArgs
.getConstArray();
631 for (sal_uInt16 i
=0; i
<aArgs
.getLength(); ++i
, ++pArgs
)
633 if (pArgs
->Name
== ::rtl::OUString::createFromAscii("ColumnViewPos"))
635 nColId
= pGrid
->GetColumnIdFromViewPos(::comphelper::getINT16(pArgs
->Value
));
638 if (pArgs
->Name
== ::rtl::OUString::createFromAscii("ColumnModelPos"))
640 nColId
= pGrid
->GetColumnIdFromModelPos(::comphelper::getINT16(pArgs
->Value
));
643 if (pArgs
->Name
== ::rtl::OUString::createFromAscii("ColumnId"))
645 nColId
= ::comphelper::getINT16(pArgs
->Value
);
650 DispatchType eURLType
= classifyDispatchURL( aURL
);
652 if ( dtUnknown
!= eURLType
)
654 // notify any status listeners that the dialog is now active (well, about to be active)
655 MapDispatchToBool::iterator aThisURLState
= m_aDispatchStates
.insert( MapDispatchToBool::value_type( eURLType
, sal_True
) ).first
;
656 NotifyStatusChanged( aURL
, NULL
);
658 // execute the dialog
661 case dtBrowserAttribs
:
662 pGrid
->SetBrowserAttrs();
666 pGrid
->SetRowHeight();
669 case dtColumnAttribs
:
671 DBG_ASSERT(nColId
!= -1, "SbaXGridPeer::dispatch : invalid parameter !");
674 pGrid
->SetColAttrs(nColId
);
680 DBG_ASSERT(nColId
!= -1, "SbaXGridPeer::dispatch : invalid parameter !");
683 pGrid
->SetColWidth(nColId
);
691 // notify any status listeners that the dialog vanished
692 m_aDispatchStates
.erase( aThisURLState
);
693 NotifyStatusChanged( aURL
, NULL
);
697 //---------------------------------------------------------------------------------------
698 void SAL_CALL
SbaXGridPeer::addStatusListener(const Reference
< ::com::sun::star::frame::XStatusListener
> & xControl
, const ::com::sun::star::util::URL
& aURL
) throw( RuntimeException
)
700 ::cppu::OInterfaceContainerHelper
* pCont
= m_aStatusListeners
.getContainer(aURL
);
702 m_aStatusListeners
.addInterface(aURL
,xControl
);
704 pCont
->addInterface(xControl
);
705 NotifyStatusChanged(aURL
, xControl
);
708 //---------------------------------------------------------------------------------------
709 void SAL_CALL
SbaXGridPeer::removeStatusListener(const Reference
< ::com::sun::star::frame::XStatusListener
> & xControl
, const ::com::sun::star::util::URL
& aURL
) throw( RuntimeException
)
711 ::cppu::OInterfaceContainerHelper
* pCont
= m_aStatusListeners
.getContainer(aURL
);
713 pCont
->removeInterface(xControl
);
716 //---------------------------------------------------------------------------------------
717 const Sequence
< sal_Int8
> & SbaXGridPeer::getUnoTunnelId()
719 static Sequence
< sal_Int8
> * pSeq
= 0;
722 ::osl::Guard
< ::osl::Mutex
> aGuard( ::osl::Mutex::getGlobalMutex() );
725 static Sequence
< sal_Int8
> aSeq( 16 );
726 rtl_createUuid( (sal_uInt8
*)aSeq
.getArray(), 0,sal_True
);
733 //---------------------------------------------------------------------------------------
734 Sequence
< Type
> SAL_CALL
SbaXGridPeer::getTypes() throw (RuntimeException
)
736 Sequence
< Type
> aTypes
= FmXGridPeer::getTypes();
737 sal_Int32 nOldLen
= aTypes
.getLength();
738 aTypes
.realloc(nOldLen
+ 1);
739 aTypes
.getArray()[nOldLen
] = ::getCppuType( reinterpret_cast< Reference
< ::com::sun::star::frame::XDispatch
>* >(NULL
) );
744 // return implementation specific data
745 //------------------------------------------------------------------
746 sal_Int64 SAL_CALL
SbaXGridPeer::getSomething( const Sequence
< sal_Int8
> & rId
) throw(::com::sun::star::uno::RuntimeException
)
748 if( rId
.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), rId
.getConstArray(), 16 ) )
749 return reinterpret_cast< sal_Int64
>( this );
751 return FmXGridPeer::getSomething(rId
);
754 //---------------------------------------------------------------------------------------
755 SbaXGridPeer
* SbaXGridPeer::getImplementation(const Reference
< XInterface
>& _rxIFace
)
757 Reference
< XUnoTunnel
> xTunnel(
758 _rxIFace
, UNO_QUERY
);
760 return reinterpret_cast<SbaXGridPeer
*>(xTunnel
->getSomething(getUnoTunnelId()));
764 //---------------------------------------------------------------------------------------
765 FmGridControl
* SbaXGridPeer::imp_CreateControl(Window
* pParent
, WinBits nStyle
)
767 return new SbaGridControl(m_xServiceFactory
, pParent
, this, nStyle
);
770 //==================================================================
772 //==================================================================
774 //---------------------------------------------------------------------------------------
775 SbaGridHeader::SbaGridHeader(BrowseBox
* pParent
, WinBits nWinBits
)
776 :FmGridHeader(pParent
, nWinBits
)
777 ,DragSourceHelper(this)
781 //---------------------------------------------------------------------------------------
782 void SbaGridHeader::StartDrag( sal_Int8 _nAction
, const Point
& _rPosPixel
)
784 ::vos::OGuard
aGuard(Application::GetSolarMutex());
785 // in the new DnD API, the solar mutex is not locked when StartDrag get's called
787 ImplStartColumnDrag( _nAction
, _rPosPixel
);
790 //---------------------------------------------------------------------------------------
791 void SbaGridHeader::MouseButtonDown( const MouseEvent
& _rMEvt
)
794 if (_rMEvt
.GetClicks() != 2)
796 // the base class will start a column move here, which we don't want to allow
797 // (at the moment. If we store relative positions with the columns, we can allow column moves ....)
799 // sal_uInt16 nPos(0);
800 // sal_uInt16 nHitTest = ImplHitTest( _rMEvt.GetPosPixel(), mnMouseOff, nPos );
801 // if (!nHitTest & HEAD_HITTEST_DIVIDER)
805 FmGridHeader::MouseButtonDown(_rMEvt
);
808 //---------------------------------------------------------------------------------------
809 sal_Bool
SbaGridHeader::ImplStartColumnDrag(sal_Int8 _nAction
, const Point
& _rMousePos
)
811 sal_uInt16 nId
= GetItemId(_rMousePos
);
812 sal_Bool bResizingCol
= sal_False
;
813 if (HEADERBAR_ITEM_NOTFOUND
!= nId
)
815 Rectangle aColRect
= GetItemRect(nId
);
816 aColRect
.Left() += nId
? 3 : 0; // the handle col (nId == 0) does not have a left margin for resizing
817 aColRect
.Right() -= 3;
818 bResizingCol
= !aColRect
.IsInside(_rMousePos
);
822 // force the the base class to end it's drag mode
823 EndTracking(ENDTRACK_CANCEL
| ENDTRACK_END
);
825 // because we have 3d-buttons the select handler is called from MouseButtonUp, but StartDrag
826 // occures earlier (while the mouse button is down)
827 // so for optical reasons we select the column before really starting the drag operation.
828 notifyColumnSelect(nId
);
830 static_cast<SbaGridControl
*>(GetParent())->StartDrag(_nAction
,
832 _rMousePos
.X() + GetPosPixel().X(), // we aren't left-justified with our parent, in contrast to the data window
833 _rMousePos
.Y() - GetSizePixel().Height()
842 //---------------------------------------------------------------------------------------
843 void SbaGridHeader::PreExecuteColumnContextMenu(sal_uInt16 nColId
, PopupMenu
& rMenu
)
845 FmGridHeader::PreExecuteColumnContextMenu(nColId
, rMenu
);
847 // some items are valid only if the db isn't readonly
848 sal_Bool bDBIsReadOnly
= ((SbaGridControl
*)GetParent())->IsReadOnlyDB();
852 rMenu
.EnableItem(SID_FM_HIDECOL
, sal_False
);
853 PopupMenu
* pShowColsMenu
= rMenu
.GetPopupMenu(SID_FM_SHOWCOLS
);
856 // at most 16 items which mean "show column <name>"
857 for (sal_uInt16 i
=1; i
<16; ++i
)
858 pShowColsMenu
->EnableItem(i
, sal_False
);
859 // "show cols/more..." and "show cols/all"
860 pShowColsMenu
->EnableItem(SID_FM_SHOWCOLS_MORE
, sal_False
);
861 pShowColsMenu
->EnableItem(SID_FM_SHOWALLCOLS
, sal_False
);
865 // prepend some new items
866 sal_Bool bColAttrs
= (nColId
!= (sal_uInt16
)-1) && (nColId
!= 0);
867 if ( bColAttrs
&& !bDBIsReadOnly
)
869 PopupMenu
aNewItems(ModuleRes(RID_SBA_GRID_COLCTXMENU
));
871 sal_uInt16 nModelPos
= ((SbaGridControl
*)GetParent())->GetModelColumnPos(nColId
);
872 Reference
< XPropertySet
> xField
= ((SbaGridControl
*)GetParent())->getField(nModelPos
);
876 switch( ::comphelper::getINT32(xField
->getPropertyValue(PROPERTY_TYPE
)) )
878 case DataType::BINARY
:
879 case DataType::VARBINARY
:
880 case DataType::LONGVARBINARY
:
881 case DataType::SQLNULL
:
882 case DataType::OBJECT
:
888 rMenu
.InsertItem(ID_BROWSER_COLATTRSET
, aNewItems
.GetItemText(ID_BROWSER_COLATTRSET
), 0, nPos
++);
889 rMenu
.SetHelpId(ID_BROWSER_COLATTRSET
, aNewItems
.GetHelpId(ID_BROWSER_COLATTRSET
));
890 rMenu
.InsertSeparator(nPos
++);
894 rMenu
.InsertItem(ID_BROWSER_COLWIDTH
, aNewItems
.GetItemText(ID_BROWSER_COLWIDTH
), 0, nPos
++);
895 rMenu
.SetHelpId(ID_BROWSER_COLWIDTH
, aNewItems
.GetHelpId(ID_BROWSER_COLWIDTH
));
896 rMenu
.InsertSeparator(nPos
++);
900 //---------------------------------------------------------------------------------------
901 void SbaGridHeader::PostExecuteColumnContextMenu(sal_uInt16 nColId
, const PopupMenu
& rMenu
, sal_uInt16 nExecutionResult
)
903 switch (nExecutionResult
)
905 case ID_BROWSER_COLWIDTH
:
906 ((SbaGridControl
*)GetParent())->SetColWidth(nColId
);
909 case ID_BROWSER_COLATTRSET
:
910 ((SbaGridControl
*)GetParent())->SetColAttrs(nColId
);
912 case ID_BROWSER_COLUMNINFO
:
914 sal_uInt16 nModelPos
= ((SbaGridControl
*)GetParent())->GetModelColumnPos(nColId
);
915 Reference
< XPropertySet
> xField
= ((SbaGridControl
*)GetParent())->getField(nModelPos
);
919 ::std::vector
< ::boost::shared_ptr
<OTableRow
> > vClipboardList
;
920 // send it to the clipboard
921 vClipboardList
.push_back(::boost::shared_ptr
<OTableRow
>(new OTableRow(xField
)));
922 OTableRowExchange
* pData
= new OTableRowExchange(vClipboardList
);
923 Reference
< ::com::sun::star::datatransfer::XTransferable
> xRef
= pData
;
924 pData
->CopyToClipboard(GetParent());
928 default: FmGridHeader::PostExecuteColumnContextMenu(nColId
, rMenu
, nExecutionResult
);
932 //==================================================================
934 //==================================================================
935 DBG_NAME(SbaGridControl
);
936 //---------------------------------------------------------------------------------------
937 SbaGridControl::SbaGridControl(Reference
< XMultiServiceFactory
> _rM
,
938 Window
* pParent
, FmXGridPeer
* _pPeer
, WinBits nBits
)
939 :FmGridControl(_rM
,pParent
, _pPeer
, nBits
)
940 ,m_pMasterListener(NULL
)
941 ,m_nAsyncDropEvent(0)
942 ,m_nCurrentActionColId((USHORT
)-1)
943 ,m_bActivatingForDrop(sal_False
)
945 DBG_CTOR(SbaGridControl
,NULL
);
948 //---------------------------------------------------------------------------------------
949 SbaGridControl::~SbaGridControl()
951 DBG_DTOR(SbaGridControl
,NULL
);
952 if (m_nAsyncDropEvent
)
953 Application::RemoveUserEvent(m_nAsyncDropEvent
);
956 //---------------------------------------------------------------------------------------
957 BrowserHeader
* SbaGridControl::imp_CreateHeaderBar(BrowseBox
* pParent
)
959 return new SbaGridHeader(pParent
);
962 //---------------------------------------------------------------------------------------
963 CellController
* SbaGridControl::GetController(long nRow
, sal_uInt16 nCol
)
965 if ( m_bActivatingForDrop
)
968 return FmGridControl::GetController(nRow
, nCol
);
971 //---------------------------------------------------------------------------------------
972 void SbaGridControl::PreExecuteRowContextMenu(sal_uInt16 nRow
, PopupMenu
& rMenu
)
974 FmGridControl::PreExecuteRowContextMenu(nRow
, rMenu
);
976 PopupMenu
aNewItems(ModuleRes(RID_SBA_GRID_ROWCTXMENU
));
981 rMenu
.InsertItem(ID_BROWSER_TABLEATTR
, aNewItems
.GetItemText(ID_BROWSER_TABLEATTR
), 0, nPos
++);
982 rMenu
.SetHelpId(ID_BROWSER_TABLEATTR
, aNewItems
.GetHelpId(ID_BROWSER_TABLEATTR
));
984 rMenu
.InsertItem(ID_BROWSER_ROWHEIGHT
, aNewItems
.GetItemText(ID_BROWSER_ROWHEIGHT
), 0, nPos
++);
985 rMenu
.SetHelpId(ID_BROWSER_ROWHEIGHT
, aNewItems
.GetHelpId(ID_BROWSER_ROWHEIGHT
));
986 rMenu
.InsertSeparator(nPos
++);
987 } // if (!IsReadOnlyDB())
989 if ( GetSelectRowCount() > 0 )
991 rMenu
.InsertItem(ID_BROWSER_COPY
, aNewItems
.GetItemText(SID_COPY
), 0, nPos
++);
992 rMenu
.SetHelpId(ID_BROWSER_COPY
, aNewItems
.GetHelpId(SID_COPY
));
994 rMenu
.InsertSeparator(nPos
++);
998 //------------------------------------------------------------------------------
999 SvNumberFormatter
* SbaGridControl::GetDatasourceFormatter()
1001 Reference
< ::com::sun::star::util::XNumberFormatsSupplier
> xSupplier
= ::dbtools::getNumberFormats(::dbtools::getConnection(Reference
< XRowSet
> (getDataSource(),UNO_QUERY
)), sal_True
,getServiceManager());
1003 SvNumberFormatsSupplierObj
* pSupplierImpl
= SvNumberFormatsSupplierObj::getImplementation( xSupplier
);
1004 if ( !pSupplierImpl
)
1007 SvNumberFormatter
* pFormatter
= pSupplierImpl
->GetNumberFormatter();
1011 //------------------------------------------------------------------------------
1012 void SbaGridControl::SetColWidth(sal_uInt16 nColId
)
1014 // get the (UNO) column model
1015 sal_uInt16 nModelPos
= GetModelColumnPos(nColId
);
1016 Reference
< XIndexAccess
> xCols(GetPeer()->getColumns(), UNO_QUERY
);
1017 Reference
< XPropertySet
> xAffectedCol
;
1018 if (xCols
.is() && (nModelPos
!= (sal_uInt16
)-1))
1019 ::cppu::extractInterface(xAffectedCol
,xCols
->getByIndex(nModelPos
));
1021 if (xAffectedCol
.is())
1023 Any aWidth
= xAffectedCol
->getPropertyValue(PROPERTY_WIDTH
);
1024 sal_Int32 nCurWidth
= aWidth
.hasValue() ? ::comphelper::getINT32(aWidth
) : -1;
1026 DlgSize
aDlgColWidth(this, nCurWidth
, sal_False
);
1027 if (aDlgColWidth
.Execute())
1029 sal_Int32 nValue
= aDlgColWidth
.GetValue();
1033 Reference
< XPropertyState
> xPropState(xAffectedCol
, UNO_QUERY
);
1034 if (xPropState
.is())
1036 try { aNewWidth
= xPropState
->getPropertyDefault(PROPERTY_WIDTH
); } catch(Exception
&) { } ;
1040 aNewWidth
<<= nValue
;
1041 try { xAffectedCol
->setPropertyValue(PROPERTY_WIDTH
, aNewWidth
); } catch(Exception
&) { } ;
1046 //------------------------------------------------------------------------------
1047 void SbaGridControl::SetRowHeight()
1049 Reference
< XPropertySet
> xCols(GetPeer()->getColumns(), UNO_QUERY
);
1053 Any aHeight
= xCols
->getPropertyValue(PROPERTY_ROW_HEIGHT
);
1054 sal_Int32 nCurHeight
= aHeight
.hasValue() ? ::comphelper::getINT32(aHeight
) : -1;
1056 DlgSize
aDlgRowHeight(this, nCurHeight
, sal_True
);
1057 if (aDlgRowHeight
.Execute())
1059 sal_Int32 nValue
= aDlgRowHeight
.GetValue();
1061 if ((sal_Int16
)-1 == nValue
)
1063 Reference
< XPropertyState
> xPropState(xCols
, UNO_QUERY
);
1064 if (xPropState
.is())
1068 aNewHeight
= xPropState
->getPropertyDefault(PROPERTY_ROW_HEIGHT
);
1075 aNewHeight
<<= nValue
;
1078 xCols
->setPropertyValue(PROPERTY_ROW_HEIGHT
, aNewHeight
);
1082 OSL_ENSURE(0,"setPropertyValue: PROPERTY_ROW_HEIGHT throws a exception");
1087 //------------------------------------------------------------------------------
1088 void SbaGridControl::SetColAttrs(sal_uInt16 nColId
)
1090 SvNumberFormatter
* pFormatter
= GetDatasourceFormatter();
1094 sal_uInt16 nModelPos
= GetModelColumnPos(nColId
);
1096 // get the (UNO) column model
1097 Reference
< XIndexAccess
> xCols(GetPeer()->getColumns(), UNO_QUERY
);
1098 Reference
< XPropertySet
> xAffectedCol
;
1099 if (xCols
.is() && (nModelPos
!= (sal_uInt16
)-1))
1100 ::cppu::extractInterface(xAffectedCol
,xCols
->getByIndex(nModelPos
));
1102 // get the field the column is bound to
1103 Reference
< XPropertySet
> xField
= getField(nModelPos
);
1104 ::dbaui::callColumnFormatDialog(xAffectedCol
,xField
,pFormatter
,this);//(Window::GetSettings().GetLanguage());
1108 //------------------------------------------------------------------------------
1109 void SbaGridControl::SetBrowserAttrs()
1111 Reference
< XPropertySet
> xGridModel(GetPeer()->getColumns(), UNO_QUERY
);
1112 if (!xGridModel
.is())
1118 aArg
.Name
= ::rtl::OUString::createFromAscii("IntrospectedObject");
1119 aArg
.Value
<<= xGridModel
;
1120 Sequence
< Any
> aDialogArgs(1);
1121 aDialogArgs
[0] <<= aArg
;
1123 Reference
< XInterface
> xDialog
= getServiceManager()->createInstanceWithArguments(
1124 ::rtl::OUString::createFromAscii("com.sun.star.form.ControlFontDialog"),
1129 ShowServiceNotAvailableError(this, String::CreateFromAscii("com.sun.star.form.ControlFontDialog"), sal_True
);
1133 Reference
< XExecutableDialog
> xExecute(xDialog
, UNO_QUERY
);
1134 OSL_ENSURE(xExecute
.is(), "SbaGridControl::SetBrowserAttrs: missing an interface on the dialog!");
1136 xExecute
->execute();
1138 catch( const Exception
& )
1140 DBG_UNHANDLED_EXCEPTION();
1144 //---------------------------------------------------------------------------------------
1145 void SbaGridControl::PostExecuteRowContextMenu(sal_uInt16 nRow
, const PopupMenu
& rMenu
, sal_uInt16 nExecutionResult
)
1147 switch (nExecutionResult
)
1149 case ID_BROWSER_TABLEATTR
:
1152 case ID_BROWSER_ROWHEIGHT
:
1155 case ID_BROWSER_COPY
:
1156 CopySelectedRowsToClipboard();
1160 FmGridControl::PostExecuteRowContextMenu(nRow
, rMenu
, nExecutionResult
);
1165 //---------------------------------------------------------------------------------------
1166 void SbaGridControl::Select()
1168 // irgendeine Selektion hat sich geaendert ....
1169 FmGridControl::Select();
1171 if (m_pMasterListener
)
1172 m_pMasterListener
->SelectionChanged();
1175 //---------------------------------------------------------------------------------------
1176 void SbaGridControl::CursorMoved()
1178 FmGridControl::CursorMoved();
1181 //---------------------------------------------------------------------------------------
1182 void SbaGridControl::ActivateCell(long nRow
, sal_uInt16 nCol
, sal_Bool bSetCellFocus
/*= sal_True*/ )
1184 FmGridControl::ActivateCell(nRow
, nCol
, bSetCellFocus
);
1185 if (m_pMasterListener
)
1186 m_pMasterListener
->CellActivated();
1189 //---------------------------------------------------------------------------------------
1190 void SbaGridControl::DeactivateCell(sal_Bool bUpdate
/*= sal_True*/)
1192 FmGridControl::DeactivateCell(bUpdate
);
1193 if (m_pMasterListener
)
1194 m_pMasterListener
->CellDeactivated();
1197 //---------------------------------------------------------------------------------------
1198 void SbaGridControl::onRowChange()
1200 if ( m_pMasterListener
)
1201 m_pMasterListener
->RowChanged();
1204 //---------------------------------------------------------------------------------------
1205 void SbaGridControl::onColumnChange()
1207 if ( m_pMasterListener
)
1208 m_pMasterListener
->ColumnChanged();
1211 //---------------------------------------------------------------------------------------
1212 void SbaGridControl::BeforeDrop()
1214 if (m_pMasterListener
)
1215 m_pMasterListener
->BeforeDrop();
1217 //---------------------------------------------------------------------------------------
1218 void SbaGridControl::AfterDrop()
1220 if (m_pMasterListener
)
1221 m_pMasterListener
->AfterDrop();
1225 //------------------------------------------------------------------------------
1226 Reference
< XPropertySet
> SbaGridControl::getField(sal_uInt16 nModelPos
)
1228 Reference
< XPropertySet
> xEmptyReturn
;
1231 // first get the name of the column
1232 Reference
< XIndexAccess
> xCols(GetPeer()->getColumns(), UNO_QUERY
);
1233 if ( xCols
.is() && xCols
->getCount() > nModelPos
)
1235 Reference
< XPropertySet
> xCol(xCols
->getByIndex(nModelPos
),UNO_QUERY
);
1237 xEmptyReturn
.set(xCol
->getPropertyValue(PROPERTY_BOUNDFIELD
),UNO_QUERY
);
1240 OSL_ENSURE(0,"SbaGridControl::getField getColumns returns NULL or ModelPos is > than count!");
1244 OSL_ENSURE(0,"SbaGridControl::getField Exception occured!");
1247 return xEmptyReturn
;
1250 //---------------------------------------------------------------------------------------
1251 sal_Bool
SbaGridControl::IsReadOnlyDB() const
1253 // assume yes if anything fails
1254 sal_Bool bDBIsReadOnly
= sal_True
;
1256 // the db is the implemented by the parent of the grid control's model ...
1257 Reference
< XChild
> xColumns(GetPeer()->getColumns(), UNO_QUERY
);
1260 Reference
< XRowSet
> xDataSource(xColumns
->getParent(), UNO_QUERY
);
1261 Reference
< XChild
> xConn(::dbtools::getConnection(xDataSource
),UNO_QUERY
);
1264 // ... and the RO-flag simply is implemented by a property
1265 Reference
< XPropertySet
> xDbProps(xConn
->getParent(), UNO_QUERY
);
1268 Reference
< XPropertySetInfo
> xInfo
= xDbProps
->getPropertySetInfo();
1269 if (xInfo
->hasPropertyByName(PROPERTY_ISREADONLY
))
1270 bDBIsReadOnly
= ::comphelper::getBOOL(xDbProps
->getPropertyValue(PROPERTY_ISREADONLY
));
1274 return bDBIsReadOnly
;
1277 //---------------------------------------------------------------------------------------
1278 void SbaGridControl::MouseButtonDown( const BrowserMouseEvent
& rMEvt
)
1280 long nRow
= GetRowAtYPosPixel(rMEvt
.GetPosPixel().Y());
1281 sal_uInt16 nColPos
= GetColumnAtXPosPixel(rMEvt
.GetPosPixel().X());
1282 sal_uInt16 nViewPos
= (nColPos
== BROWSER_INVALIDID
) ? (sal_uInt16
)-1 : nColPos
-1;
1283 // 'the handle column' and 'no valid column' will both result in a view position of -1 !
1285 sal_Bool bHitEmptySpace
= (nRow
> GetRowCount()) || (nViewPos
== (sal_uInt16
)-1);
1287 if (bHitEmptySpace
&& (rMEvt
.GetClicks() == 2) && rMEvt
.IsMod1())
1288 Control::MouseButtonDown(rMEvt
);
1290 FmGridControl::MouseButtonDown(rMEvt
);
1293 //---------------------------------------------------------------------------------------
1294 void SbaGridControl::StartDrag( sal_Int8 _nAction
, const Point
& _rPosPixel
)
1296 ::vos::OGuard
aGuard(Application::GetSolarMutex());
1297 // in the new DnD API, the solar mutex is not locked when StartDrag get's called
1299 sal_Bool bHandled
= sal_False
;
1303 // determine if dragging is allowed
1304 // (Yes, this is controller (not view) functionality. But collecting and evaluating all the
1305 // informations necessary via UNO would be quite difficult (if not impossible) so
1306 // my laziness says 'do it here' ...)
1307 long nRow
= GetRowAtYPosPixel(_rPosPixel
.Y());
1308 sal_uInt16 nColPos
= GetColumnAtXPosPixel(_rPosPixel
.X());
1309 sal_uInt16 nViewPos
= (nColPos
== BROWSER_INVALIDID
) ? (sal_uInt16
)-1 : nColPos
-1;
1310 // 'the handle column' and 'no valid column' will both result in a view position of -1 !
1312 sal_Bool bCurrentRowVirtual
= IsCurrentAppending() && IsModified();
1313 // the current row doesn't really exist : the user's appendign a new one and already has entered some data,
1314 // so the row contains data which has no counter part within the data source
1316 long nCorrectRowCount
= GetRowCount();
1317 if (GetOptions() & OPT_INSERT
)
1318 --nCorrectRowCount
; // there is a empty row for inserting records
1319 if (bCurrentRowVirtual
)
1322 if ((nColPos
== BROWSER_INVALIDID
) || (nRow
>= nCorrectRowCount
))
1325 sal_Bool bHitHandle
= (nColPos
== 0);
1327 // check which kind of dragging has to be initiated
1328 if ( bHitHandle
// the handle column
1330 && ( GetSelectRowCount() // at least one row is selected
1332 || ( (nRow
>= 0) // a row below the header
1333 && !bCurrentRowVirtual
// we aren't appending a new record
1334 && (nRow
!= GetCurrentPos()) // a row which is not the current one
1336 || ( (0 == GetSelectRowCount()) // no rows selected
1337 && (-1 == nRow
) // hit the header
1341 { // => start dragging the row
1342 if (GetDataWindow().IsMouseCaptured())
1343 GetDataWindow().ReleaseMouse();
1345 if (0 == GetSelectRowCount())
1346 // no rows selected, but here in this branch
1347 // -> the user started dragging the upper left corner, which symbolizes the whole table
1350 getMouseEvent().Clear();
1351 DoRowDrag((sal_Int16
)nRow
);
1353 bHandled
= sal_True
;
1355 else if ( (nRow
< 0) // the header
1356 && (!bHitHandle
) // non-handle column
1357 && (nViewPos
< GetViewColCount()) // valid (existing) column
1359 { // => start dragging the column
1360 if (GetDataWindow().IsMouseCaptured())
1361 GetDataWindow().ReleaseMouse();
1363 getMouseEvent().Clear();
1364 DoColumnDrag(nViewPos
);
1366 bHandled
= sal_True
;
1368 else if ( !bHitHandle
// non-handle column
1369 && (nRow
>= 0) // non-header row
1371 { // => start dragging the field content
1372 if (GetDataWindow().IsMouseCaptured())
1373 GetDataWindow().ReleaseMouse();
1375 getMouseEvent().Clear();
1376 DoFieldDrag(nViewPos
, (sal_Int16
)nRow
);
1378 bHandled
= sal_True
;
1384 FmGridControl::StartDrag(_nAction
, _rPosPixel
);
1387 //------------------------------------------------------------------------------
1388 void SbaGridControl::Command(const CommandEvent
& rEvt
)
1390 FmGridControl::Command(rEvt
);
1393 // -----------------------------------------------------------------------
1394 void SbaGridControl::DoColumnDrag(sal_uInt16 nColumnPos
)
1396 Reference
< XPropertySet
> xDataSource(getDataSource(), UNO_QUERY
);
1397 DBG_ASSERT(xDataSource
.is(), "SbaGridControl::DoColumnDrag : invalid data source !");
1399 Reference
< XPropertySet
> xAffectedCol
;
1400 Reference
< XPropertySet
> xAffectedField
;
1401 Reference
< XConnection
> xActiveConnection
;
1403 // determine the field to drag
1404 ::rtl::OUString sField
;
1407 xActiveConnection
= ::dbtools::getConnection(Reference
< XRowSet
>(getDataSource(),UNO_QUERY
));
1409 sal_uInt16 nModelPos
= GetModelColumnPos(GetColumnIdFromViewPos(nColumnPos
));
1410 Reference
< XIndexContainer
> xCols(GetPeer()->getColumns(), UNO_QUERY
);
1411 xAffectedCol
.set(xCols
->getByIndex(nModelPos
),UNO_QUERY
);
1412 if (xAffectedCol
.is())
1414 xAffectedCol
->getPropertyValue(PROPERTY_CONTROLSOURCE
) >>= sField
;
1415 xAffectedField
.set(xAffectedCol
->getPropertyValue(PROPERTY_BOUNDFIELD
),UNO_QUERY
);
1420 DBG_ERROR("SbaGridControl::DoColumnDrag : something went wrong while getting the column");
1422 if (0 == sField
.getLength())
1425 OColumnTransferable
* pDataTransfer
= new OColumnTransferable(xDataSource
, sField
, xAffectedField
, xActiveConnection
, CTF_FIELD_DESCRIPTOR
| CTF_COLUMN_DESCRIPTOR
);
1426 Reference
< XTransferable
> xEnsureDelete
= pDataTransfer
;
1427 pDataTransfer
->StartDrag(this, DND_ACTION_COPY
| DND_ACTION_LINK
);
1430 // -----------------------------------------------------------------------
1431 void SbaGridControl::CopySelectedRowsToClipboard()
1433 DBG_ASSERT( GetSelectRowCount() > 0, "SbaGridControl::CopySelectedRowsToClipboard: invalid call!" );
1434 implTransferSelectedRows( (sal_Int16
)FirstSelectedRow(), true );
1437 // -----------------------------------------------------------------------
1438 void SbaGridControl::DoRowDrag( sal_Int16 nRowPos
)
1440 implTransferSelectedRows( nRowPos
, false );
1443 // -----------------------------------------------------------------------
1444 void SbaGridControl::implTransferSelectedRows( sal_Int16 nRowPos
, bool _bTrueIfClipboardFalseIfDrag
)
1446 Reference
< XPropertySet
> xDataSource(getDataSource(), UNO_QUERY
);
1447 DBG_ASSERT(xDataSource
.is(), "SbaGridControl::implTransferSelectedRows : invalid data source !");
1449 // build the sequence of numbers of selected rows
1450 Sequence
< Any
> aSelectedRows
;
1452 // collect the affected rows
1453 if ((GetSelectRowCount() == 0) && (nRowPos
>= 0))
1455 aSelectedRows
.realloc(1);
1456 aSelectedRows
[0] <<= (sal_Int32
)(nRowPos
+ 1);
1458 else if ( !IsAllSelected() && GetSelectRowCount() )
1460 aSelectedRows
.realloc(GetSelectRowCount());
1461 Any
* pSelectedRows
= aSelectedRows
.getArray();
1463 for (long nIdx
= FirstSelectedRow();
1465 nIdx
= NextSelectedRow(), ++pSelectedRows
)
1467 (*pSelectedRows
) <<= (sal_Int32
)(nIdx
+ 1);
1471 Reference
< XResultSet
> xRowSetClone
;
1474 Reference
< XResultSetAccess
> xResultSetAccess(xDataSource
,UNO_QUERY
);
1475 if ( xResultSetAccess
.is() )
1476 xRowSetClone
= xResultSetAccess
->createResultSet();
1478 ODataClipboard
* pTransfer
= new ODataClipboard(xDataSource
, aSelectedRows
,xRowSetClone
, getServiceManager());
1480 Reference
< XTransferable
> xEnsureDelete
= pTransfer
;
1481 if ( _bTrueIfClipboardFalseIfDrag
)
1482 pTransfer
->CopyToClipboard( this );
1484 pTransfer
->StartDrag(this, DND_ACTION_COPY
| DND_ACTION_LINK
);
1491 // -----------------------------------------------------------------------
1492 void SbaGridControl::DoFieldDrag(sal_uInt16 nColumnPos
, sal_Int16 nRowPos
)
1494 // the only thing to do here is dragging the pure cell text
1495 // the old implementation copied a SBA_FIELDDATAEXCHANGE_FORMAT, too, (which was rather expensive to obtain),
1496 // but we have no client for this DnD format anymore (the mail part of SO 5.2 was the only client)
1498 ::rtl::OUString sCellText
;
1501 Reference
< XGridFieldDataSupplier
> xFieldData(static_cast< XGridPeer
* >(GetPeer()), UNO_QUERY
);
1502 Sequence
<sal_Bool
> aSupportingText
= xFieldData
->queryFieldDataType(::getCppuType(&sCellText
));
1503 if (aSupportingText
.getConstArray()[nColumnPos
])
1505 Sequence
< Any
> aCellContents
= xFieldData
->queryFieldData(nRowPos
, ::getCppuType(&sCellText
));
1506 sCellText
= ::comphelper::getString(aCellContents
.getConstArray()[nColumnPos
]);
1507 ::svt::OStringTransfer::StartStringDrag(sCellText
, this, DND_ACTION_COPY
);
1512 DBG_ERROR("SbaGridControl::DoFieldDrag : could not retrieve the cell's contents !");
1517 /// unary_function Functor object for class ZZ returntype is void
1518 struct SbaGridControlPrec
: ::std::unary_function
<DataFlavorExVector::value_type
,bool>
1520 sal_Bool bQueryDrop
;
1521 SbaGridControlPrec(sal_Bool _bQueryDrop
)
1522 : bQueryDrop(_bQueryDrop
)
1526 inline bool operator()(const DataFlavorExVector::value_type
& _aType
)
1528 switch (_aType
.mnSotId
)
1530 // case SOT_FORMAT_RTF: // RTF data descriptions
1531 // case SOT_FORMATSTR_ID_HTML: // HTML data descriptions
1532 case SOT_FORMATSTR_ID_DBACCESS_TABLE
: // table descriptor
1533 case SOT_FORMATSTR_ID_DBACCESS_QUERY
: // query descriptor
1534 case SOT_FORMATSTR_ID_DBACCESS_COMMAND
: // SQL command
1540 //------------------------------------------------------------------------------
1541 sal_Int8
SbaGridControl::AcceptDrop( const BrowserAcceptDropEvent
& rEvt
)
1543 sal_Int8 nAction
= DND_ACTION_NONE
;
1545 // we need a valid connection
1546 if (!::dbtools::getConnection(Reference
< XRowSet
> (getDataSource(),UNO_QUERY
)).is())
1549 if ( IsDropFormatSupported( FORMAT_STRING
) ) do
1550 { // odd construction, but spares us a lot of (explicit ;) goto's
1552 if (!GetEmptyRow().Is())
1553 // without an empty row we're not in update mode
1556 long nRow
= GetRowAtYPosPixel(rEvt
.maPosPixel
.Y(), sal_False
);
1557 sal_uInt16 nCol
= GetColumnAtXPosPixel(rEvt
.maPosPixel
.X(), sal_False
);
1559 long nCorrectRowCount
= GetRowCount();
1560 if (GetOptions() & OPT_INSERT
)
1561 --nCorrectRowCount
; // there is a empty row for inserting records
1562 if (IsCurrentAppending())
1563 --nCorrectRowCount
; // the current data record doesn't really exist, we are appending a new one
1565 if ((nCol
== BROWSER_INVALIDID
) || (nRow
>= nCorrectRowCount
) || GetColumnId(nCol
) == 0 )
1566 // no valid cell under the mouse cursor
1569 Rectangle aRect
= GetCellRect(nRow
, nCol
, sal_False
);
1570 if (!aRect
.IsInside(rEvt
.maPosPixel
))
1571 // not dropped within a cell (a cell isn't as wide as the column - the are small spaces)
1574 if ((IsModified() || (GetCurrentRow().Is() && GetCurrentRow()->IsModified())) && (GetCurrentPos() != nRow
))
1575 // there is a current and modified row or cell and he text is to be dropped into another one
1578 CellControllerRef xCurrentController
= Controller();
1579 if (xCurrentController
.Is() && xCurrentController
->IsModified() && ((nRow
!= GetCurRow()) || (nCol
!= GetCurColumnId())))
1580 // the current controller is modified and the user wants to drop in another cell -> no chance
1581 // (when leaving the modified cell a error may occur - this is deadly while dragging)
1584 Reference
< XPropertySet
> xField
= getField(GetModelColumnPos(nCol
));
1586 // the column is not valid bound (for instance a binary field)
1591 if (::comphelper::getBOOL(xField
->getPropertyValue(PROPERTY_ISREADONLY
)))
1594 catch (const Exception
& e
)
1596 (void)e
; // make compiler happy
1603 // assume that text can be dropped into a field if the column has a ::com::sun::star::awt::XTextComponent interface
1604 Reference
< XIndexAccess
> xColumnControls((::com::sun::star::form::XGridPeer
*)GetPeer(), UNO_QUERY
);
1605 if (xColumnControls
.is())
1607 Reference
< ::com::sun::star::awt::XTextComponent
> xColControl
;
1608 ::cppu::extractInterface(xColControl
,xColumnControls
->getByIndex(GetViewColumnPos(nCol
)));
1609 if (xColControl
.is())
1611 m_bActivatingForDrop
= sal_True
;
1612 GoToRowColumnId(nRow
, nCol
);
1613 m_bActivatingForDrop
= sal_False
;
1615 nAction
= DND_ACTION_COPY
;
1619 catch( const Exception
& )
1621 DBG_UNHANDLED_EXCEPTION();
1624 } while (sal_False
);
1626 if(nAction
!= DND_ACTION_COPY
&& GetEmptyRow().Is())
1628 const DataFlavorExVector
& _rFlavors
= GetDataFlavors();
1629 if(::std::find_if(_rFlavors
.begin(),_rFlavors
.end(),SbaGridControlPrec(sal_True
)) != _rFlavors
.end())
1630 nAction
= DND_ACTION_COPY
;
1635 SvDataObjectRef xDataObj = SvDataObject::PasteDragServer( rEvt );
1639 const SvDataTypeList& rTypeList = xDataObj->GetTypeList();
1640 if ((rTypeList.Get(Exchange::RegisterFormatName(String::CreateFromAscii(SBA_DATAEXCHANGE_FORMAT)))) )
1642 bAllow = (GetOptions() & OPT_INSERT) && rEvt.GetColumnId() > 0 && rEvt.GetRow() >= 0;
1643 ((BrowserDropEvent&)rEvt).SetAction(DROP_COPY);
1647 return (DND_ACTION_NONE
!= nAction
) ? nAction
: FmGridControl::AcceptDrop(rEvt
);
1650 //------------------------------------------------------------------------------
1651 sal_Int8
SbaGridControl::ExecuteDrop( const BrowserExecuteDropEvent
& rEvt
)
1653 // we need some properties of our data source
1654 Reference
< XPropertySet
> xDataSource
= getDataSource();
1655 if (!xDataSource
.is())
1656 return DND_ACTION_NONE
;
1658 // we need a valid connection
1659 if (!::dbtools::getConnection(Reference
< XRowSet
> (xDataSource
,UNO_QUERY
)).is())
1660 return DND_ACTION_NONE
;
1662 if ( IsDropFormatSupported( FORMAT_STRING
) )
1664 long nRow
= GetRowAtYPosPixel(rEvt
.maPosPixel
.Y(), sal_False
);
1665 sal_uInt16 nCol
= GetColumnAtXPosPixel(rEvt
.maPosPixel
.X(), sal_False
);
1667 long nCorrectRowCount
= GetRowCount();
1668 if (GetOptions() & OPT_INSERT
)
1669 --nCorrectRowCount
; // there is a empty row for inserting records
1670 if (IsCurrentAppending())
1671 --nCorrectRowCount
; // the current data record doesn't really exist, we are appending a new one
1673 DBG_ASSERT((nCol
!= BROWSER_INVALIDID
) && (nRow
< nCorrectRowCount
), "SbaGridControl::Drop : dropped on an invalid position !");
1674 // AcceptDrop should have caught this
1676 // from now we work with ids instead of positions
1677 nCol
= GetColumnId(nCol
);
1679 GoToRowColumnId(nRow
, nCol
);
1683 CellControllerRef xCurrentController
= Controller();
1684 if (!xCurrentController
.Is() || !xCurrentController
->ISA(EditCellController
))
1685 return DND_ACTION_NONE
;
1686 Edit
& rEdit
= (Edit
&)xCurrentController
->GetWindow();
1688 // get the dropped string
1689 TransferableDataHelper
aDropped( rEvt
.maDropEvent
.Transferable
);
1691 if ( !aDropped
.GetString( FORMAT_STRING
, sDropped
) )
1692 return DND_ACTION_NONE
;
1694 rEdit
.SetText( sDropped
);
1695 xCurrentController
->SetModified();
1697 // SetText itself doesn't call a Modify as it isn't a user interaction
1699 return DND_ACTION_COPY
;
1702 if(GetEmptyRow().Is())
1704 const DataFlavorExVector
& _rFlavors
= GetDataFlavors();
1705 DataFlavorExVector::const_iterator aFind
= ::std::find_if(_rFlavors
.begin(),_rFlavors
.end(),SbaGridControlPrec(sal_True
));
1706 if( aFind
!= _rFlavors
.end())
1708 TransferableDataHelper
aDropped( rEvt
.maDropEvent
.Transferable
);
1709 m_aDataDescriptor
= ODataAccessObjectTransferable::extractObjectDescriptor(aDropped
);
1710 if (m_nAsyncDropEvent
)
1711 Application::RemoveUserEvent(m_nAsyncDropEvent
);
1712 m_nAsyncDropEvent
= Application::PostUserEvent(LINK(this, SbaGridControl
, AsynchDropEvent
));
1713 return DND_ACTION_COPY
;
1717 return DND_ACTION_NONE
;
1720 //------------------------------------------------------------------------------
1721 Reference
< XPropertySet
> SbaGridControl::getDataSource() const
1723 Reference
< XPropertySet
> xReturn
;
1725 Reference
< XChild
> xColumns(GetPeer()->getColumns(), UNO_QUERY
);
1726 Reference
< XPropertySet
> xDataSource
;
1728 xReturn
= Reference
< XPropertySet
> (xColumns
->getParent(), UNO_QUERY
);
1732 // -----------------------------------------------------------------------------
1733 IMPL_LINK(SbaGridControl
, AsynchDropEvent
, void*, /*EMPTY_ARG*/)
1735 m_nAsyncDropEvent
= 0;
1737 Reference
< XPropertySet
> xDataSource
= getDataSource();
1738 if ( xDataSource
.is() )
1740 sal_Bool bCountFinal
= sal_False
;
1741 xDataSource
->getPropertyValue(PROPERTY_ISROWCOUNTFINAL
) >>= bCountFinal
;
1743 setDataSource(NULL
); // deattach from grid control
1744 Reference
< XResultSetUpdate
> xResultSetUpdate(xDataSource
,UNO_QUERY
);
1745 ODatabaseImportExport
* pImExport
= new ORowSetImportExport(this,xResultSetUpdate
,m_aDataDescriptor
,getServiceManager());
1746 Reference
<XEventListener
> xHolder
= pImExport
;
1750 pImExport
->initialize(m_aDataDescriptor
);
1752 if(!pImExport
->Read())
1754 String sError
= String(ModuleRes(STR_NO_COLUMNNAME_MATCHING
));
1755 throwGenericSQLException(sError
,NULL
);
1760 catch(const SQLException
& e
)
1764 ::dbaui::showError(::dbtools::SQLExceptionInfo(e
),this,getServiceManager());
1766 catch(const Exception
& )
1770 DBG_UNHANDLED_EXCEPTION();
1773 setDataSource(Reference
< XRowSet
>(xDataSource
,UNO_QUERY
));
1775 m_aDataDescriptor
.clear();
1779 // -------------------------------------------------------------------------
1780 ::rtl::OUString
SbaGridControl::GetAccessibleObjectDescription( ::svt::AccessibleBrowseBoxObjType eObjType
,sal_Int32 _nPosition
) const
1782 ::rtl::OUString sRet
;
1783 if ( ::svt::BBTYPE_BROWSEBOX
== eObjType
)
1785 ::vos::OGuard
aGuard(Application::GetSolarMutex());
1786 sRet
= String(ModuleRes(STR_DATASOURCE_GRIDCONTROL_DESC
));
1789 sRet
= FmGridControl::GetAccessibleObjectDescription( eObjType
,_nPosition
);
1792 // -----------------------------------------------------------------------------
1793 void SbaGridControl::DeleteSelectedRows()
1795 FmGridControl::DeleteSelectedRows();