1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "sbagrid.hrc"
21 #include "uiservices.hxx"
23 #include <sot/exchange.hxx>
24 #include <svx/svxids.hrc>
26 #include <svx/numinf.hxx>
27 #include <svx/dbaexchange.hxx>
28 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
30 #include "sbagrid.hxx"
31 #include "dlgattr.hxx"
32 #include "dlgsize.hxx"
33 #include <com/sun/star/form/XLoadable.hpp>
34 #include <com/sun/star/form/ControlFontDialog.hpp>
35 #include <com/sun/star/sdb/CommandType.hpp>
36 #include <com/sun/star/sdb/XSQLQueryComposerFactory.hpp>
37 #include <com/sun/star/sdb/XResultSetAccess.hpp>
38 #include <com/sun/star/form/XForm.hpp>
39 #include <com/sun/star/container/XIndexContainer.hpp>
40 #include <com/sun/star/util/NumberFormat.hpp>
42 #include <com/sun/star/view/XSelectionSupplier.hpp>
43 #include <com/sun/star/form/DataSelectionType.hpp>
44 #include <com/sun/star/awt/TextAlign.hpp>
45 #include <com/sun/star/awt/XTextComponent.hpp>
46 #include <com/sun/star/util/Date.hpp>
47 #include <com/sun/star/util/Time.hpp>
48 #include <com/sun/star/util/DateTime.hpp>
49 #include <com/sun/star/sdbc/XResultSetUpdate.hpp>
50 #include <tools/diagnose_ex.h>
52 #include <svl/intitem.hxx>
53 #include <svx/algitem.hxx>
54 #include <tools/multisel.hxx>
55 #include <svl/numuno.hxx>
56 #include <svl/itempool.hxx>
57 #include <svl/itemset.hxx>
58 #include <svl/rngitem.hxx>
60 #include <vcl/waitobj.hxx>
61 #include <toolkit/helper/vclunohelper.hxx>
63 #include <svl/zforlist.hxx>
64 #include <cppuhelper/queryinterface.hxx>
65 #include <connectivity/dbtools.hxx>
66 #include <connectivity/dbconversion.hxx>
67 #include <cppuhelper/typeprovider.hxx>
68 #include <comphelper/servicehelper.hxx>
69 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
70 #include <com/sun/star/sdbc/DataType.hpp>
71 #include <vcl/msgbox.hxx>
72 #include "dbu_brw.hrc"
73 #include "browserids.hxx"
74 #include "dbustrings.hrc"
75 #include "dbu_reghelper.hxx"
76 #include "dbexchange.hxx"
77 #include "TableRowExchange.hxx"
78 #include "TableRow.hxx"
79 #include "FieldDescriptions.hxx"
80 #include <svtools/stringtransfer.hxx>
81 #include <vcl/stdtext.hxx>
82 #include "UITools.hxx"
83 #include "TokenWriter.hxx"
84 #include <osl/diagnose.h>
87 using namespace ::com::sun::star::ui::dialogs
;
88 using namespace ::com::sun::star::uno
;
89 using namespace ::com::sun::star::sdb
;
90 using namespace ::com::sun::star::sdbc
;
91 using namespace ::com::sun::star::sdbcx
;
92 using namespace ::com::sun::star::beans
;
93 using namespace ::com::sun::star::container
;
94 using namespace ::com::sun::star::datatransfer
;
95 using namespace ::com::sun::star::lang
;
96 using namespace ::com::sun::star::view
;
97 using namespace ::com::sun::star::form
;
98 using namespace ::com::sun::star::frame
;
99 using namespace ::com::sun::star::util
;
100 using namespace ::dbaui
;
101 using namespace ::dbtools
;
102 using namespace ::svx
;
103 using namespace ::svt
;
105 extern "C" void SAL_CALL
createRegistryInfo_SbaXGridControl()
107 static OMultiInstanceAutoRegistration
< SbaXGridControl
> aAutoRegistration
;
110 ::comphelper::StringSequence SAL_CALL
SbaXGridControl::getSupportedServiceNames() throw(std::exception
)
112 return getSupportedServiceNames_Static();
115 Reference
< XInterface
> SAL_CALL
SbaXGridControl::Create(const Reference
<XMultiServiceFactory
>& _rxFactory
)
117 return *(new SbaXGridControl( comphelper::getComponentContext(_rxFactory
) ));
122 OUString SAL_CALL
SbaXGridControl::getImplementationName() throw(std::exception
)
124 return getImplementationName_Static();
127 OUString
SbaXGridControl::getImplementationName_Static() throw( RuntimeException
)
129 return OUString("com.sun.star.comp.dbu.SbaXGridControl");
132 Sequence
< OUString
> SbaXGridControl::getSupportedServiceNames_Static() throw( RuntimeException
)
134 Sequence
< OUString
> aSupported(3);
135 aSupported
[0] = "com.sun.star.form.control.InteractionGridControl";
136 aSupported
[1] = "com.sun.star.form.control.GridControl";
137 aSupported
[2] = "com.sun.star.awt.UnoControl";
141 SbaXGridControl::SbaXGridControl(const Reference
< XComponentContext
>& _rM
)
142 : FmXGridControl(_rM
)
146 SbaXGridControl::~SbaXGridControl()
150 FmXGridPeer
* SbaXGridControl::imp_CreatePeer(vcl::Window
* pParent
)
152 FmXGridPeer
* pReturn
= new SbaXGridPeer(m_xContext
);
154 // translate properties into WinBits
155 WinBits nStyle
= WB_TABSTOP
;
156 Reference
< XPropertySet
> xModelSet(getModel(), UNO_QUERY
);
161 if (::comphelper::getINT16(xModelSet
->getPropertyValue(PROPERTY_BORDER
)))
170 pReturn
->Create(pParent
, nStyle
);
174 Any SAL_CALL
SbaXGridControl::queryInterface(const Type
& _rType
) throw (RuntimeException
, std::exception
)
176 Any aRet
= FmXGridControl::queryInterface(_rType
);
177 return aRet
.hasValue() ? aRet
: ::cppu::queryInterface(_rType
,(::com::sun::star::frame::XDispatch
*)this);
180 Sequence
< Type
> SAL_CALL
SbaXGridControl::getTypes( ) throw (RuntimeException
, std::exception
)
182 Sequence
< Type
> aTypes
= FmXGridControl::getTypes();
184 sal_Int32 nTypes
= aTypes
.getLength();
185 aTypes
.realloc(nTypes
+ 1);
186 aTypes
[nTypes
] = cppu::UnoType
<com::sun::star::frame::XDispatch
>::get();
191 Sequence
< sal_Int8
> SAL_CALL
SbaXGridControl::getImplementationId( ) throw (RuntimeException
, std::exception
)
193 return css::uno::Sequence
<sal_Int8
>();
196 void SAL_CALL
SbaXGridControl::createPeer(const Reference
< ::com::sun::star::awt::XToolkit
> & rToolkit
, const Reference
< ::com::sun::star::awt::XWindowPeer
> & rParentPeer
) throw( RuntimeException
, std::exception
)
198 FmXGridControl::createPeer(rToolkit
, rParentPeer
);
200 OSL_ENSURE(!mbCreatingPeer
, "FmXGridControl::createPeer : recursion!");
201 // see the base class' createPeer for a comment on this
203 // TODO: why the hell this whole class does not use any mutex?
205 Reference
< ::com::sun::star::frame::XDispatch
> xDisp(getPeer(), UNO_QUERY
);
206 for ( StatusMultiplexerArray::iterator aIter
= m_aStatusMultiplexer
.begin();
207 aIter
!= m_aStatusMultiplexer
.end();
210 if ((*aIter
).second
&& (*aIter
).second
->getLength())
211 xDisp
->addStatusListener((*aIter
).second
, (*aIter
).first
);
215 void SAL_CALL
SbaXGridControl::dispatch(const ::com::sun::star::util::URL
& aURL
, const Sequence
< PropertyValue
>& aArgs
) throw( RuntimeException
, std::exception
)
217 Reference
< ::com::sun::star::frame::XDispatch
> xDisp(getPeer(), UNO_QUERY
);
219 xDisp
->dispatch(aURL
, aArgs
);
222 void SAL_CALL
SbaXGridControl::addStatusListener( const Reference
< XStatusListener
> & _rxListener
, const URL
& _rURL
) throw( RuntimeException
, std::exception
)
224 ::osl::MutexGuard
aGuard( GetMutex() );
225 if ( _rxListener
.is() )
227 SbaXStatusMultiplexer
*& pMultiplexer
= m_aStatusMultiplexer
[ _rURL
];
230 pMultiplexer
= new SbaXStatusMultiplexer( *this, GetMutex() );
231 pMultiplexer
->acquire();
234 pMultiplexer
->addInterface( _rxListener
);
235 if ( getPeer().is() )
237 if ( 1 == pMultiplexer
->getLength() )
238 { // the first external listener for this URL
239 Reference
< XDispatch
> xDisp( getPeer(), UNO_QUERY
);
240 xDisp
->addStatusListener( pMultiplexer
, _rURL
);
243 { // already have other listeners for this URL
244 _rxListener
->statusChanged( pMultiplexer
->getLastEvent() );
250 void SAL_CALL
SbaXGridControl::removeStatusListener(const Reference
< ::com::sun::star::frame::XStatusListener
> & _rxListener
, const ::com::sun::star::util::URL
& _rURL
) throw( RuntimeException
, std::exception
)
252 ::osl::MutexGuard
aGuard( GetMutex() );
254 SbaXStatusMultiplexer
*& pMultiplexer
= m_aStatusMultiplexer
[_rURL
];
257 pMultiplexer
= new SbaXStatusMultiplexer(*this,GetMutex());
258 pMultiplexer
->acquire();
261 if (getPeer().is() && pMultiplexer
->getLength() == 1)
263 Reference
< ::com::sun::star::frame::XDispatch
> xDisp(getPeer(), UNO_QUERY
);
264 xDisp
->removeStatusListener(pMultiplexer
, _rURL
);
266 pMultiplexer
->removeInterface( _rxListener
);
269 void SAL_CALL
SbaXGridControl::dispose() throw( RuntimeException
, std::exception
)
271 SolarMutexGuard aGuard
;
276 for ( StatusMultiplexerArray::iterator aIter
= m_aStatusMultiplexer
.begin();
277 aIter
!= m_aStatusMultiplexer
.end();
282 (*aIter
).second
->disposeAndClear(aEvt
);
283 (*aIter
).second
->release();
284 (*aIter
).second
= NULL
;
287 StatusMultiplexerArray().swap(m_aStatusMultiplexer
);
289 FmXGridControl::dispose();
293 SbaXGridPeer::SbaXGridPeer(const Reference
< XComponentContext
>& _rM
)
295 ,m_aStatusListeners(m_aMutex
)
299 SbaXGridPeer::~SbaXGridPeer()
303 void SAL_CALL
SbaXGridPeer::dispose() throw( RuntimeException
, std::exception
)
305 EventObject
aEvt(*this);
307 m_aStatusListeners
.disposeAndClear(aEvt
);
309 FmXGridPeer::dispose();
312 void SbaXGridPeer::NotifyStatusChanged(const ::com::sun::star::util::URL
& _rUrl
, const Reference
< ::com::sun::star::frame::XStatusListener
> & xControl
)
314 VclPtr
< SbaGridControl
> pGrid
= GetAs
< SbaGridControl
>();
318 ::com::sun::star::frame::FeatureStateEvent aEvt
;
320 aEvt
.IsEnabled
= !pGrid
->IsReadOnlyDB();
321 aEvt
.FeatureURL
= _rUrl
;
323 MapDispatchToBool::const_iterator aURLStatePos
= m_aDispatchStates
.find( classifyDispatchURL( _rUrl
) );
324 if ( m_aDispatchStates
.end() != aURLStatePos
)
325 aEvt
.State
<<= aURLStatePos
->second
;
327 aEvt
.State
<<= sal_False
;
330 xControl
->statusChanged(aEvt
);
333 ::cppu::OInterfaceContainerHelper
* pIter
= m_aStatusListeners
.getContainer(_rUrl
);
337 ::cppu::OInterfaceIteratorHelper
aListIter(*pIter
);
338 while (aListIter
.hasMoreElements())
339 static_cast< ::com::sun::star::frame::XStatusListener
*>(aListIter
.next())->statusChanged(aEvt
);
344 Any SAL_CALL
SbaXGridPeer::queryInterface(const Type
& _rType
) throw (RuntimeException
, std::exception
)
346 Any aRet
= ::cppu::queryInterface(_rType
,(::com::sun::star::frame::XDispatch
*)this);
349 return FmXGridPeer::queryInterface(_rType
);
352 Reference
< ::com::sun::star::frame::XDispatch
> SAL_CALL
SbaXGridPeer::queryDispatch(const ::com::sun::star::util::URL
& aURL
, const OUString
& aTargetFrameName
, sal_Int32 nSearchFlags
) throw( RuntimeException
, std::exception
)
354 if ( ( aURL
.Complete
== ".uno:GridSlots/BrowserAttribs" ) || ( aURL
.Complete
== ".uno:GridSlots/RowHeight" )
355 || ( aURL
.Complete
== ".uno:GridSlots/ColumnAttribs" ) || ( aURL
.Complete
== ".uno:GridSlots/ColumnWidth" )
358 return (::com::sun::star::frame::XDispatch
*)this;
361 return FmXGridPeer::queryDispatch(aURL
, aTargetFrameName
, nSearchFlags
);
364 IMPL_LINK_NOARG( SbaXGridPeer
, OnDispatchEvent
)
366 VclPtr
< SbaGridControl
> pGrid
= GetAs
< SbaGridControl
>();
367 if ( pGrid
) // if this fails, we were disposing before arriving here
369 if ( Application::GetMainThreadIdentifier() != ::osl::Thread::getCurrentIdentifier() )
371 // still not in the main thread (see SbaXGridPeer::dispatch). post an event, again
372 // without moving the special even to the back of the queue
373 pGrid
->PostUserEvent( LINK( this, SbaXGridPeer
, OnDispatchEvent
) );
377 DispatchArgs aArgs
= m_aDispatchArgs
.front();
378 m_aDispatchArgs
.pop();
380 SbaXGridPeer::dispatch( aArgs
.aURL
, aArgs
.aArgs
);
387 SbaXGridPeer::DispatchType
SbaXGridPeer::classifyDispatchURL( const URL
& _rURL
)
389 DispatchType eURLType
= dtUnknown
;
390 if ( _rURL
.Complete
== ".uno:GridSlots/BrowserAttribs" )
391 eURLType
= dtBrowserAttribs
;
392 else if ( _rURL
.Complete
== ".uno:GridSlots/RowHeight" )
393 eURLType
= dtRowHeight
;
394 else if ( _rURL
.Complete
== ".uno:GridSlots/ColumnAttribs" )
395 eURLType
= dtColumnAttribs
;
396 else if ( _rURL
.Complete
== ".uno:GridSlots/ColumnWidth" )
397 eURLType
= dtColumnWidth
;
401 void SAL_CALL
SbaXGridPeer::dispatch(const URL
& aURL
, const Sequence
< PropertyValue
>& aArgs
) throw( RuntimeException
, std::exception
)
403 VclPtr
< SbaGridControl
> pGrid
= GetAs
< SbaGridControl
>();
407 if ( Application::GetMainThreadIdentifier() != ::osl::Thread::getCurrentIdentifier() )
409 // we're not in the main thread. This is bad, as we want to raise windows here,
410 // and VCL does not like windows to be opened in non-main threads (at least on Win32).
411 // Okay, do this async. No problem with this, as XDispatch::dispatch is defined to be
415 DispatchArgs aDispatchArgs
;
416 aDispatchArgs
.aURL
= aURL
;
417 aDispatchArgs
.aArgs
= aArgs
;
418 m_aDispatchArgs
.push( aDispatchArgs
);
421 // we use the Window::PostUserEvent here, instead of the application::PostUserEvent
422 // this saves us from keeping track of these events - as soon as the window dies,
423 // the events are deleted automatically. For the application way, we would need to
425 // As we use our grid as window, and the grid dies before we dy, this should be no problem.
426 pGrid
->PostUserEvent( LINK( this, SbaXGridPeer
, OnDispatchEvent
) );
430 SolarMutexGuard aGuard
;
431 sal_Int16 nColId
= -1;
432 const PropertyValue
* pArgs
= aArgs
.getConstArray();
433 for (sal_uInt16 i
=0; i
<aArgs
.getLength(); ++i
, ++pArgs
)
435 if (pArgs
->Name
== "ColumnViewPos")
437 nColId
= pGrid
->GetColumnIdFromViewPos(::comphelper::getINT16(pArgs
->Value
));
440 if (pArgs
->Name
== "ColumnModelPos")
442 nColId
= pGrid
->GetColumnIdFromModelPos(::comphelper::getINT16(pArgs
->Value
));
445 if (pArgs
->Name
== "ColumnId")
447 nColId
= ::comphelper::getINT16(pArgs
->Value
);
452 DispatchType eURLType
= classifyDispatchURL( aURL
);
454 if ( dtUnknown
!= eURLType
)
456 // notify any status listeners that the dialog is now active (well, about to be active)
457 MapDispatchToBool::iterator aThisURLState
= m_aDispatchStates
.insert( MapDispatchToBool::value_type( eURLType
, sal_True
) ).first
;
458 NotifyStatusChanged( aURL
, NULL
);
460 // execute the dialog
463 case dtBrowserAttribs
:
464 pGrid
->SetBrowserAttrs();
468 pGrid
->SetRowHeight();
471 case dtColumnAttribs
:
473 OSL_ENSURE(nColId
!= -1, "SbaXGridPeer::dispatch : invalid parameter !");
476 pGrid
->SetColAttrs(nColId
);
482 OSL_ENSURE(nColId
!= -1, "SbaXGridPeer::dispatch : invalid parameter !");
485 pGrid
->SetColWidth(nColId
);
493 // notify any status listeners that the dialog vanished
494 m_aDispatchStates
.erase( aThisURLState
);
495 NotifyStatusChanged( aURL
, NULL
);
499 void SAL_CALL
SbaXGridPeer::addStatusListener(const Reference
< ::com::sun::star::frame::XStatusListener
> & xControl
, const ::com::sun::star::util::URL
& aURL
) throw( RuntimeException
, std::exception
)
501 ::cppu::OInterfaceContainerHelper
* pCont
= m_aStatusListeners
.getContainer(aURL
);
503 m_aStatusListeners
.addInterface(aURL
,xControl
);
505 pCont
->addInterface(xControl
);
506 NotifyStatusChanged(aURL
, xControl
);
509 void SAL_CALL
SbaXGridPeer::removeStatusListener(const Reference
< ::com::sun::star::frame::XStatusListener
> & xControl
, const ::com::sun::star::util::URL
& aURL
) throw( RuntimeException
, std::exception
)
511 ::cppu::OInterfaceContainerHelper
* pCont
= m_aStatusListeners
.getContainer(aURL
);
513 pCont
->removeInterface(xControl
);
518 class theSbaXGridPeerUnoTunnelId
: public rtl::Static
< UnoTunnelIdInit
, theSbaXGridPeerUnoTunnelId
> {};
521 const Sequence
< sal_Int8
> & SbaXGridPeer::getUnoTunnelId()
523 return theSbaXGridPeerUnoTunnelId::get().getSeq();
526 Sequence
< Type
> SAL_CALL
SbaXGridPeer::getTypes() throw (RuntimeException
, std::exception
)
528 Sequence
< Type
> aTypes
= FmXGridPeer::getTypes();
529 sal_Int32 nOldLen
= aTypes
.getLength();
530 aTypes
.realloc(nOldLen
+ 1);
531 aTypes
.getArray()[nOldLen
] = cppu::UnoType
<com::sun::star::frame::XDispatch
>::get();
536 // return implementation specific data
537 sal_Int64 SAL_CALL
SbaXGridPeer::getSomething( const Sequence
< sal_Int8
> & rId
) throw(::com::sun::star::uno::RuntimeException
, std::exception
)
539 if( rId
.getLength() == 16 && 0 == memcmp( getUnoTunnelId().getConstArray(), rId
.getConstArray(), 16 ) )
540 return reinterpret_cast< sal_Int64
>( this );
542 return FmXGridPeer::getSomething(rId
);
545 SbaXGridPeer
* SbaXGridPeer::getImplementation(const Reference
< XInterface
>& _rxIFace
)
547 Reference
< XUnoTunnel
> xTunnel(
548 _rxIFace
, UNO_QUERY
);
550 return reinterpret_cast<SbaXGridPeer
*>(xTunnel
->getSomething(getUnoTunnelId()));
554 VclPtr
<FmGridControl
> SbaXGridPeer::imp_CreateControl(vcl::Window
* pParent
, WinBits nStyle
)
556 return VclPtr
<SbaGridControl
>::Create( m_xContext
, pParent
, this, nStyle
);
561 SbaGridHeader::SbaGridHeader(BrowseBox
* pParent
, WinBits nWinBits
)
562 :FmGridHeader(pParent
, nWinBits
)
563 ,DragSourceHelper(this)
567 void SbaGridHeader::StartDrag( sal_Int8 _nAction
, const Point
& _rPosPixel
)
569 SolarMutexGuard aGuard
;
570 // in the new DnD API, the solar mutex is not locked when StartDrag get's called
572 ImplStartColumnDrag( _nAction
, _rPosPixel
);
575 void SbaGridHeader::MouseButtonDown( const MouseEvent
& _rMEvt
)
578 if (_rMEvt
.GetClicks() != 2)
580 // the base class will start a column move here, which we don't want to allow
581 // (at the moment. If we store relative positions with the columns, we can allow column moves ....)
585 FmGridHeader::MouseButtonDown(_rMEvt
);
588 bool SbaGridHeader::ImplStartColumnDrag(sal_Int8 _nAction
, const Point
& _rMousePos
)
590 sal_uInt16 nId
= GetItemId(_rMousePos
);
591 bool bResizingCol
= false;
592 if (HEADERBAR_ITEM_NOTFOUND
!= nId
)
594 Rectangle aColRect
= GetItemRect(nId
);
595 aColRect
.Left() += nId
? 3 : 0; // the handle col (nId == 0) does not have a left margin for resizing
596 aColRect
.Right() -= 3;
597 bResizingCol
= !aColRect
.IsInside(_rMousePos
);
601 // force the base class to end it's drag mode
602 EndTracking(TrackingEventFlags::Cancel
| TrackingEventFlags::End
);
604 // because we have 3d-buttons the select handler is called from MouseButtonUp, but StartDrag
605 // occurs earlier (while the mouse button is down)
606 // so for optical reasons we select the column before really starting the drag operation.
607 notifyColumnSelect(nId
);
609 static_cast<SbaGridControl
*>(GetParent())->StartDrag(_nAction
,
611 _rMousePos
.X() + GetPosPixel().X(), // we aren't left-justified with our parent, in contrast to the data window
612 _rMousePos
.Y() - GetSizePixel().Height()
621 void SbaGridHeader::PreExecuteColumnContextMenu(sal_uInt16 nColId
, PopupMenu
& rMenu
)
623 FmGridHeader::PreExecuteColumnContextMenu(nColId
, rMenu
);
625 // some items are valid only if the db isn't readonly
626 bool bDBIsReadOnly
= static_cast<SbaGridControl
*>(GetParent())->IsReadOnlyDB();
630 rMenu
.EnableItem(SID_FM_HIDECOL
, false);
631 PopupMenu
* pShowColsMenu
= rMenu
.GetPopupMenu(SID_FM_SHOWCOLS
);
634 // at most 16 items which mean "show column <name>"
635 for (sal_uInt16 i
=1; i
<16; ++i
)
636 pShowColsMenu
->EnableItem(i
, false);
637 // "show cols/more..." and "show cols/all"
638 pShowColsMenu
->EnableItem(SID_FM_SHOWCOLS_MORE
, false);
639 pShowColsMenu
->EnableItem(SID_FM_SHOWALLCOLS
, false);
643 // prepend some new items
644 bool bColAttrs
= (nColId
!= (sal_uInt16
)-1) && (nColId
!= 0);
645 if ( bColAttrs
&& !bDBIsReadOnly
)
647 PopupMenu
aNewItems(ModuleRes(RID_SBA_GRID_COLCTXMENU
));
649 sal_uInt16 nModelPos
= static_cast<SbaGridControl
*>(GetParent())->GetModelColumnPos(nColId
);
650 Reference
< XPropertySet
> xField
= static_cast<SbaGridControl
*>(GetParent())->getField(nModelPos
);
654 switch( ::comphelper::getINT32(xField
->getPropertyValue(PROPERTY_TYPE
)) )
656 case DataType::BINARY
:
657 case DataType::VARBINARY
:
658 case DataType::LONGVARBINARY
:
659 case DataType::SQLNULL
:
660 case DataType::OBJECT
:
666 rMenu
.InsertItem(ID_BROWSER_COLATTRSET
, aNewItems
.GetItemText(ID_BROWSER_COLATTRSET
), MenuItemBits::NONE
, OString(), nPos
++);
667 rMenu
.SetHelpId(ID_BROWSER_COLATTRSET
, aNewItems
.GetHelpId(ID_BROWSER_COLATTRSET
));
668 rMenu
.InsertSeparator(OString(), nPos
++);
672 rMenu
.InsertItem(ID_BROWSER_COLWIDTH
, aNewItems
.GetItemText(ID_BROWSER_COLWIDTH
), MenuItemBits::NONE
, OString(), nPos
++);
673 rMenu
.SetHelpId(ID_BROWSER_COLWIDTH
, aNewItems
.GetHelpId(ID_BROWSER_COLWIDTH
));
674 rMenu
.InsertSeparator(OString(), nPos
++);
678 void SbaGridHeader::PostExecuteColumnContextMenu(sal_uInt16 nColId
, const PopupMenu
& rMenu
, sal_uInt16 nExecutionResult
)
680 switch (nExecutionResult
)
682 case ID_BROWSER_COLWIDTH
:
683 static_cast<SbaGridControl
*>(GetParent())->SetColWidth(nColId
);
686 case ID_BROWSER_COLATTRSET
:
687 static_cast<SbaGridControl
*>(GetParent())->SetColAttrs(nColId
);
689 case ID_BROWSER_COLUMNINFO
:
691 sal_uInt16 nModelPos
= static_cast<SbaGridControl
*>(GetParent())->GetModelColumnPos(nColId
);
692 Reference
< XPropertySet
> xField
= static_cast<SbaGridControl
*>(GetParent())->getField(nModelPos
);
696 ::std::vector
< ::boost::shared_ptr
<OTableRow
> > vClipboardList
;
697 // send it to the clipboard
698 vClipboardList
.push_back(::boost::shared_ptr
<OTableRow
>(new OTableRow(xField
)));
699 OTableRowExchange
* pData
= new OTableRowExchange(vClipboardList
);
700 Reference
< ::com::sun::star::datatransfer::XTransferable
> xRef
= pData
;
701 pData
->CopyToClipboard(GetParent());
705 default: FmGridHeader::PostExecuteColumnContextMenu(nColId
, rMenu
, nExecutionResult
);
710 SbaGridControl::SbaGridControl(Reference
< XComponentContext
> _rM
,
711 vcl::Window
* pParent
, FmXGridPeer
* _pPeer
, WinBits nBits
)
712 :FmGridControl(_rM
,pParent
, _pPeer
, nBits
)
713 ,m_pMasterListener(NULL
)
714 ,m_nAsyncDropEvent(0)
715 ,m_nCurrentActionColId((sal_uInt16
)-1)
716 ,m_bActivatingForDrop(false)
720 SbaGridControl::~SbaGridControl()
725 void SbaGridControl::dispose()
727 if (m_nAsyncDropEvent
)
728 Application::RemoveUserEvent(m_nAsyncDropEvent
);
729 FmGridControl::dispose();
732 VclPtr
<BrowserHeader
> SbaGridControl::imp_CreateHeaderBar(BrowseBox
* pParent
)
734 return VclPtr
<SbaGridHeader
>::Create(pParent
);
737 CellController
* SbaGridControl::GetController(long nRow
, sal_uInt16 nCol
)
739 if ( m_bActivatingForDrop
)
742 return FmGridControl::GetController(nRow
, nCol
);
745 void SbaGridControl::PreExecuteRowContextMenu(sal_uInt16 nRow
, PopupMenu
& rMenu
)
747 FmGridControl::PreExecuteRowContextMenu(nRow
, rMenu
);
749 PopupMenu
aNewItems(ModuleRes(RID_SBA_GRID_ROWCTXMENU
));
754 rMenu
.InsertItem(ID_BROWSER_TABLEATTR
, aNewItems
.GetItemText(ID_BROWSER_TABLEATTR
), MenuItemBits::NONE
, OString(), nPos
++);
755 rMenu
.SetHelpId(ID_BROWSER_TABLEATTR
, aNewItems
.GetHelpId(ID_BROWSER_TABLEATTR
));
757 rMenu
.InsertItem(ID_BROWSER_ROWHEIGHT
, aNewItems
.GetItemText(ID_BROWSER_ROWHEIGHT
), MenuItemBits::NONE
, OString(), nPos
++);
758 rMenu
.SetHelpId(ID_BROWSER_ROWHEIGHT
, aNewItems
.GetHelpId(ID_BROWSER_ROWHEIGHT
));
759 rMenu
.InsertSeparator(OString(), nPos
++);
762 if ( GetSelectRowCount() > 0 )
764 rMenu
.InsertItem(ID_BROWSER_COPY
, aNewItems
.GetItemText(SID_COPY
), MenuItemBits::NONE
, OString(), nPos
++);
765 rMenu
.SetHelpId(ID_BROWSER_COPY
, aNewItems
.GetHelpId(SID_COPY
));
767 rMenu
.InsertSeparator(OString(), nPos
++);
771 SvNumberFormatter
* SbaGridControl::GetDatasourceFormatter()
773 Reference
< ::com::sun::star::util::XNumberFormatsSupplier
> xSupplier
= ::dbtools::getNumberFormats(::dbtools::getConnection(Reference
< XRowSet
> (getDataSource(),UNO_QUERY
)), true, getContext());
775 SvNumberFormatsSupplierObj
* pSupplierImpl
= SvNumberFormatsSupplierObj::getImplementation( xSupplier
);
776 if ( !pSupplierImpl
)
779 SvNumberFormatter
* pFormatter
= pSupplierImpl
->GetNumberFormatter();
783 void SbaGridControl::SetColWidth(sal_uInt16 nColId
)
785 // get the (UNO) column model
786 sal_uInt16 nModelPos
= GetModelColumnPos(nColId
);
787 Reference
< XIndexAccess
> xCols(GetPeer()->getColumns(), UNO_QUERY
);
788 Reference
< XPropertySet
> xAffectedCol
;
789 if (xCols
.is() && (nModelPos
!= (sal_uInt16
)-1))
790 xAffectedCol
.set(xCols
->getByIndex(nModelPos
), css::uno::UNO_QUERY
);
792 if (xAffectedCol
.is())
794 Any aWidth
= xAffectedCol
->getPropertyValue(PROPERTY_WIDTH
);
795 sal_Int32 nCurWidth
= aWidth
.hasValue() ? ::comphelper::getINT32(aWidth
) : -1;
797 ScopedVclPtrInstance
< DlgSize
> aDlgColWidth(this, nCurWidth
, false);
798 if (aDlgColWidth
->Execute())
800 sal_Int32 nValue
= aDlgColWidth
->GetValue();
804 Reference
< XPropertyState
> xPropState(xAffectedCol
, UNO_QUERY
);
807 try { aNewWidth
= xPropState
->getPropertyDefault(PROPERTY_WIDTH
); } catch(Exception
&) { } ;
811 aNewWidth
<<= nValue
;
812 try { xAffectedCol
->setPropertyValue(PROPERTY_WIDTH
, aNewWidth
); } catch(Exception
&) { } ;
817 void SbaGridControl::SetRowHeight()
819 Reference
< XPropertySet
> xCols(GetPeer()->getColumns(), UNO_QUERY
);
823 Any aHeight
= xCols
->getPropertyValue(PROPERTY_ROW_HEIGHT
);
824 sal_Int32 nCurHeight
= aHeight
.hasValue() ? ::comphelper::getINT32(aHeight
) : -1;
826 ScopedVclPtrInstance
< DlgSize
> aDlgRowHeight(this, nCurHeight
, true);
827 if (aDlgRowHeight
->Execute())
829 sal_Int32 nValue
= aDlgRowHeight
->GetValue();
831 if ((sal_Int16
)-1 == nValue
)
833 Reference
< XPropertyState
> xPropState(xCols
, UNO_QUERY
);
838 aNewHeight
= xPropState
->getPropertyDefault(PROPERTY_ROW_HEIGHT
);
845 aNewHeight
<<= nValue
;
848 xCols
->setPropertyValue(PROPERTY_ROW_HEIGHT
, aNewHeight
);
852 OSL_FAIL("setPropertyValue: PROPERTY_ROW_HEIGHT throws a exception");
857 void SbaGridControl::SetColAttrs(sal_uInt16 nColId
)
859 SvNumberFormatter
* pFormatter
= GetDatasourceFormatter();
863 sal_uInt16 nModelPos
= GetModelColumnPos(nColId
);
865 // get the (UNO) column model
866 Reference
< XIndexAccess
> xCols(GetPeer()->getColumns(), UNO_QUERY
);
867 Reference
< XPropertySet
> xAffectedCol
;
868 if (xCols
.is() && (nModelPos
!= (sal_uInt16
)-1))
869 xAffectedCol
.set(xCols
->getByIndex(nModelPos
), css::uno::UNO_QUERY
);
871 // get the field the column is bound to
872 Reference
< XPropertySet
> xField
= getField(nModelPos
);
873 ::dbaui::callColumnFormatDialog(xAffectedCol
,xField
,pFormatter
,this);//(Window::GetSettings().GetLanguage());
876 void SbaGridControl::SetBrowserAttrs()
878 Reference
< XPropertySet
> xGridModel(GetPeer()->getColumns(), UNO_QUERY
);
879 if (!xGridModel
.is())
884 Reference
< XComponentContext
> xContext
= getContext();
885 Reference
< XExecutableDialog
> xExecute
= ControlFontDialog::createWithGridModel( xContext
, xGridModel
);
888 catch( const Exception
& )
890 DBG_UNHANDLED_EXCEPTION();
894 void SbaGridControl::PostExecuteRowContextMenu(sal_uInt16 nRow
, const PopupMenu
& rMenu
, sal_uInt16 nExecutionResult
)
896 switch (nExecutionResult
)
898 case ID_BROWSER_TABLEATTR
:
901 case ID_BROWSER_ROWHEIGHT
:
904 case ID_BROWSER_COPY
:
905 CopySelectedRowsToClipboard();
909 FmGridControl::PostExecuteRowContextMenu(nRow
, rMenu
, nExecutionResult
);
914 void SbaGridControl::Select()
916 // Some selection has changed ...
917 FmGridControl::Select();
919 if (m_pMasterListener
)
920 m_pMasterListener
->SelectionChanged();
923 void SbaGridControl::CursorMoved()
925 FmGridControl::CursorMoved();
928 void SbaGridControl::ActivateCell(long nRow
, sal_uInt16 nCol
, bool bSetCellFocus
/*= sal_True*/ )
930 FmGridControl::ActivateCell(nRow
, nCol
, bSetCellFocus
);
931 if (m_pMasterListener
)
932 m_pMasterListener
->CellActivated();
935 void SbaGridControl::DeactivateCell(bool bUpdate
/*= sal_True*/)
937 FmGridControl::DeactivateCell(bUpdate
);
938 if (m_pMasterListener
)
939 m_pMasterListener
->CellDeactivated();
942 void SbaGridControl::onRowChange()
944 if ( m_pMasterListener
)
945 m_pMasterListener
->RowChanged();
948 void SbaGridControl::onColumnChange()
950 if ( m_pMasterListener
)
951 m_pMasterListener
->ColumnChanged();
954 void SbaGridControl::BeforeDrop()
956 if (m_pMasterListener
)
957 m_pMasterListener
->BeforeDrop();
960 void SbaGridControl::AfterDrop()
962 if (m_pMasterListener
)
963 m_pMasterListener
->AfterDrop();
966 Reference
< XPropertySet
> SbaGridControl::getField(sal_uInt16 nModelPos
)
968 Reference
< XPropertySet
> xEmptyReturn
;
971 // first get the name of the column
972 Reference
< XIndexAccess
> xCols(GetPeer()->getColumns(), UNO_QUERY
);
973 if ( xCols
.is() && xCols
->getCount() > nModelPos
)
975 Reference
< XPropertySet
> xCol(xCols
->getByIndex(nModelPos
),UNO_QUERY
);
977 xEmptyReturn
.set(xCol
->getPropertyValue(PROPERTY_BOUNDFIELD
),UNO_QUERY
);
980 OSL_FAIL("SbaGridControl::getField getColumns returns NULL or ModelPos is > than count!");
982 catch (const Exception
& e
)
984 SAL_WARN("dbaccess", "SbaGridControl::getField Exception occurred: " << e
.Message
);
990 bool SbaGridControl::IsReadOnlyDB() const
992 // assume yes if anything fails
993 bool bDBIsReadOnly
= true;
997 // the db is the implemented by the parent of the grid control's model ...
998 Reference
< XChild
> xColumns(GetPeer()->getColumns(), UNO_QUERY
);
1001 Reference
< XRowSet
> xDataSource(xColumns
->getParent(), UNO_QUERY
);
1002 ::dbtools::ensureRowSetConnection( xDataSource
, getContext(), false ); // NOT SURE ABOUT FALSE
1003 Reference
< XChild
> xConn(::dbtools::getConnection(xDataSource
),UNO_QUERY
);
1006 // ... and the RO-flag simply is implemented by a property
1007 Reference
< XPropertySet
> xDbProps(xConn
->getParent(), UNO_QUERY
);
1010 Reference
< XPropertySetInfo
> xInfo
= xDbProps
->getPropertySetInfo();
1011 if (xInfo
->hasPropertyByName(PROPERTY_ISREADONLY
))
1012 bDBIsReadOnly
= ::comphelper::getBOOL(xDbProps
->getPropertyValue(PROPERTY_ISREADONLY
));
1017 catch (const Exception
& e
)
1019 SAL_WARN("dbaccess", "SbaGridControl::IsReadOnlyDB Exception occurred: " << e
.Message
);
1022 return bDBIsReadOnly
;
1025 void SbaGridControl::MouseButtonDown( const BrowserMouseEvent
& rMEvt
)
1027 long nRow
= GetRowAtYPosPixel(rMEvt
.GetPosPixel().Y());
1028 sal_uInt16 nColPos
= GetColumnAtXPosPixel(rMEvt
.GetPosPixel().X());
1029 sal_uInt16 nViewPos
= (nColPos
== BROWSER_INVALIDID
) ? (sal_uInt16
)-1 : nColPos
-1;
1030 // 'the handle column' and 'no valid column' will both result in a view position of -1 !
1032 bool bHitEmptySpace
= (nRow
> GetRowCount()) || (nViewPos
== (sal_uInt16
)-1);
1034 if (bHitEmptySpace
&& (rMEvt
.GetClicks() == 2) && rMEvt
.IsMod1())
1035 Control::MouseButtonDown(rMEvt
);
1037 FmGridControl::MouseButtonDown(rMEvt
);
1040 void SbaGridControl::StartDrag( sal_Int8 _nAction
, const Point
& _rPosPixel
)
1042 SolarMutexGuard aGuard
;
1043 // in the new DnD API, the solar mutex is not locked when StartDrag get's called
1045 bool bHandled
= false;
1049 // determine if dragging is allowed
1050 // (Yes, this is controller (not view) functionality. But collecting and evaluating all the
1051 // information necessary via UNO would be quite difficult (if not impossible) so
1052 // my laziness says 'do it here' ...)
1053 long nRow
= GetRowAtYPosPixel(_rPosPixel
.Y());
1054 sal_uInt16 nColPos
= GetColumnAtXPosPixel(_rPosPixel
.X());
1055 sal_uInt16 nViewPos
= (nColPos
== BROWSER_INVALIDID
) ? (sal_uInt16
)-1 : nColPos
-1;
1056 // 'the handle column' and 'no valid column' will both result in a view position of -1 !
1058 bool bCurrentRowVirtual
= IsCurrentAppending() && IsModified();
1059 // the current row doesn't really exist : the user's appendign a new one and already has entered some data,
1060 // so the row contains data which has no counter part within the data source
1062 long nCorrectRowCount
= GetRowCount();
1063 if (GetOptions() & OPT_INSERT
)
1064 --nCorrectRowCount
; // there is a empty row for inserting records
1065 if (bCurrentRowVirtual
)
1068 if ((nColPos
== BROWSER_INVALIDID
) || (nRow
>= nCorrectRowCount
))
1071 bool bHitHandle
= (nColPos
== 0);
1073 // check which kind of dragging has to be initiated
1074 if ( bHitHandle
// the handle column
1076 && ( GetSelectRowCount() // at least one row is selected
1078 || ( (nRow
>= 0) // a row below the header
1079 && !bCurrentRowVirtual
// we aren't appending a new record
1080 && (nRow
!= GetCurrentPos()) // a row which is not the current one
1082 || ( (0 == GetSelectRowCount()) // no rows selected
1083 && (-1 == nRow
) // hit the header
1087 { // => start dragging the row
1088 if (GetDataWindow().IsMouseCaptured())
1089 GetDataWindow().ReleaseMouse();
1091 if (0 == GetSelectRowCount())
1092 // no rows selected, but here in this branch
1093 // -> the user started dragging the upper left corner, which symbolizes the whole table
1096 getMouseEvent().Clear();
1097 DoRowDrag((sal_Int16
)nRow
);
1101 else if ( (nRow
< 0) // the header
1102 && (!bHitHandle
) // non-handle column
1103 && (nViewPos
< GetViewColCount()) // valid (existing) column
1105 { // => start dragging the column
1106 if (GetDataWindow().IsMouseCaptured())
1107 GetDataWindow().ReleaseMouse();
1109 getMouseEvent().Clear();
1110 DoColumnDrag(nViewPos
);
1114 else if ( !bHitHandle
// non-handle column
1115 && (nRow
>= 0) // non-header row
1117 { // => start dragging the field content
1118 if (GetDataWindow().IsMouseCaptured())
1119 GetDataWindow().ReleaseMouse();
1121 getMouseEvent().Clear();
1122 DoFieldDrag(nViewPos
, (sal_Int16
)nRow
);
1130 FmGridControl::StartDrag(_nAction
, _rPosPixel
);
1133 void SbaGridControl::Command(const CommandEvent
& rEvt
)
1135 FmGridControl::Command(rEvt
);
1138 void SbaGridControl::DoColumnDrag(sal_uInt16 nColumnPos
)
1140 Reference
< XPropertySet
> xDataSource(getDataSource(), UNO_QUERY
);
1141 OSL_ENSURE(xDataSource
.is(), "SbaGridControl::DoColumnDrag : invalid data source !");
1143 Reference
< XPropertySet
> xAffectedCol
;
1144 Reference
< XPropertySet
> xAffectedField
;
1145 Reference
< XConnection
> xActiveConnection
;
1147 // determine the field to drag
1151 xActiveConnection
= ::dbtools::getConnection(Reference
< XRowSet
>(getDataSource(),UNO_QUERY
));
1153 sal_uInt16 nModelPos
= GetModelColumnPos(GetColumnIdFromViewPos(nColumnPos
));
1154 Reference
< XIndexContainer
> xCols(GetPeer()->getColumns(), UNO_QUERY
);
1155 xAffectedCol
.set(xCols
->getByIndex(nModelPos
),UNO_QUERY
);
1156 if (xAffectedCol
.is())
1158 xAffectedCol
->getPropertyValue(PROPERTY_CONTROLSOURCE
) >>= sField
;
1159 xAffectedField
.set(xAffectedCol
->getPropertyValue(PROPERTY_BOUNDFIELD
),UNO_QUERY
);
1164 OSL_FAIL("SbaGridControl::DoColumnDrag : something went wrong while getting the column");
1166 if (sField
.isEmpty())
1169 OColumnTransferable
* pDataTransfer
= new OColumnTransferable(xDataSource
, sField
, xAffectedField
, xActiveConnection
, ColumnTransferFormatFlags::FIELD_DESCRIPTOR
| ColumnTransferFormatFlags::COLUMN_DESCRIPTOR
);
1170 Reference
< XTransferable
> xEnsureDelete
= pDataTransfer
;
1171 pDataTransfer
->StartDrag(this, DND_ACTION_COPY
| DND_ACTION_LINK
);
1174 void SbaGridControl::CopySelectedRowsToClipboard()
1176 OSL_ENSURE( GetSelectRowCount() > 0, "SbaGridControl::CopySelectedRowsToClipboard: invalid call!" );
1177 implTransferSelectedRows( (sal_Int16
)FirstSelectedRow(), true );
1180 void SbaGridControl::DoRowDrag( sal_Int16 nRowPos
)
1182 implTransferSelectedRows( nRowPos
, false );
1185 void SbaGridControl::implTransferSelectedRows( sal_Int16 nRowPos
, bool _bTrueIfClipboardFalseIfDrag
)
1187 Reference
< XPropertySet
> xForm( getDataSource(), UNO_QUERY
);
1188 OSL_ENSURE( xForm
.is(), "SbaGridControl::implTransferSelectedRows: invalid form!" );
1190 // build the sequence of numbers of selected rows
1191 Sequence
< Any
> aSelectedRows
;
1192 bool bSelectionBookmarks
= true;
1194 // collect the affected rows
1195 if ((GetSelectRowCount() == 0) && (nRowPos
>= 0))
1197 aSelectedRows
.realloc( 1 );
1198 aSelectedRows
[0] <<= (sal_Int32
)(nRowPos
+ 1);
1199 bSelectionBookmarks
= false;
1201 else if ( !IsAllSelected() && GetSelectRowCount() )
1203 aSelectedRows
= getSelectionBookmarks();
1204 bSelectionBookmarks
= true;
1207 Reference
< XResultSet
> xRowSetClone
;
1210 ODataClipboard
* pTransfer
= new ODataClipboard( xForm
, aSelectedRows
, bSelectionBookmarks
, getContext() );
1212 Reference
< XTransferable
> xEnsureDelete
= pTransfer
;
1213 if ( _bTrueIfClipboardFalseIfDrag
)
1214 pTransfer
->CopyToClipboard( this );
1216 pTransfer
->StartDrag(this, DND_ACTION_COPY
| DND_ACTION_LINK
);
1223 void SbaGridControl::DoFieldDrag(sal_uInt16 nColumnPos
, sal_Int16 nRowPos
)
1225 // the only thing to do here is dragging the pure cell text
1226 // the old implementation copied a SBA_FIELDDATAEXCHANGE_FORMAT, too, (which was rather expensive to obtain),
1227 // but we have no client for this DnD format anymore (the mail part of SO 5.2 was the only client)
1232 Reference
< XGridFieldDataSupplier
> xFieldData(static_cast< XGridPeer
* >(GetPeer()), UNO_QUERY
);
1233 Sequence
<sal_Bool
> aSupportingText
= xFieldData
->queryFieldDataType(cppu::UnoType
<decltype(sCellText
)>::get());
1234 if (aSupportingText
.getConstArray()[nColumnPos
])
1236 Sequence
< Any
> aCellContents
= xFieldData
->queryFieldData(nRowPos
, cppu::UnoType
<decltype(sCellText
)>::get());
1237 sCellText
= ::comphelper::getString(aCellContents
.getConstArray()[nColumnPos
]);
1238 ::svt::OStringTransfer::StartStringDrag(sCellText
, this, DND_ACTION_COPY
);
1243 OSL_FAIL("SbaGridControl::DoFieldDrag : could not retrieve the cell's contents !");
1249 /// unary_function Functor object for class ZZ returntype is void
1250 struct SbaGridControlPrec
: ::std::unary_function
<DataFlavorExVector::value_type
,bool>
1253 SbaGridControlPrec(bool _bQueryDrop
)
1254 : bQueryDrop(_bQueryDrop
)
1258 inline bool operator()(const DataFlavorExVector::value_type
& _aType
)
1260 switch (_aType
.mnSotId
)
1262 case SotClipboardFormatId::DBACCESS_TABLE
: // table descriptor
1263 case SotClipboardFormatId::DBACCESS_QUERY
: // query descriptor
1264 case SotClipboardFormatId::DBACCESS_COMMAND
: // SQL command
1271 sal_Int8
SbaGridControl::AcceptDrop( const BrowserAcceptDropEvent
& rEvt
)
1273 sal_Int8 nAction
= DND_ACTION_NONE
;
1275 // we need a valid connection
1276 if (!::dbtools::getConnection(Reference
< XRowSet
> (getDataSource(),UNO_QUERY
)).is())
1279 if ( IsDropFormatSupported( SotClipboardFormatId::STRING
) ) do
1280 { // odd construction, but spares us a lot of (explicit ;) goto's
1282 if (!GetEmptyRow().Is())
1283 // without an empty row we're not in update mode
1286 long nRow
= GetRowAtYPosPixel(rEvt
.maPosPixel
.Y(), false);
1287 sal_uInt16 nCol
= GetColumnAtXPosPixel(rEvt
.maPosPixel
.X(), false);
1289 long nCorrectRowCount
= GetRowCount();
1290 if (GetOptions() & OPT_INSERT
)
1291 --nCorrectRowCount
; // there is a empty row for inserting records
1292 if (IsCurrentAppending())
1293 --nCorrectRowCount
; // the current data record doesn't really exist, we are appending a new one
1295 if ((nCol
== BROWSER_INVALIDID
) || (nRow
>= nCorrectRowCount
) || GetColumnId(nCol
) == 0 || GetColumnId(nCol
) == BROWSER_INVALIDID
)
1296 // no valid cell under the mouse cursor
1299 Rectangle aRect
= GetCellRect(nRow
, nCol
, false);
1300 if (!aRect
.IsInside(rEvt
.maPosPixel
))
1301 // not dropped within a cell (a cell isn't as wide as the column - the are small spaces)
1304 if ((IsModified() || (GetCurrentRow().Is() && GetCurrentRow()->IsModified())) && (GetCurrentPos() != nRow
))
1305 // there is a current and modified row or cell and he text is to be dropped into another one
1308 CellControllerRef xCurrentController
= Controller();
1309 if (xCurrentController
.Is() && xCurrentController
->IsModified() && ((nRow
!= GetCurRow()) || (nCol
!= GetCurColumnId())))
1310 // the current controller is modified and the user wants to drop in another cell -> no chance
1311 // (when leaving the modified cell a error may occur - this is deadly while dragging)
1314 Reference
< XPropertySet
> xField
= getField(GetModelColumnPos(nCol
));
1316 // the column is not valid bound (for instance a binary field)
1321 if (::comphelper::getBOOL(xField
->getPropertyValue(PROPERTY_ISREADONLY
)))
1324 catch (const Exception
& e
)
1326 (void)e
; // make compiler happy
1333 // assume that text can be dropped into a field if the column has a ::com::sun::star::awt::XTextComponent interface
1334 Reference
< XIndexAccess
> xColumnControls((::com::sun::star::form::XGridPeer
*)GetPeer(), UNO_QUERY
);
1335 if (xColumnControls
.is())
1337 Reference
< ::com::sun::star::awt::XTextComponent
> xColControl(
1338 xColumnControls
->getByIndex(GetViewColumnPos(nCol
)),
1339 css::uno::UNO_QUERY
);
1340 if (xColControl
.is())
1342 m_bActivatingForDrop
= true;
1343 GoToRowColumnId(nRow
, nCol
);
1344 m_bActivatingForDrop
= false;
1346 nAction
= DND_ACTION_COPY
;
1350 catch( const Exception
& )
1352 DBG_UNHANDLED_EXCEPTION();
1357 if(nAction
!= DND_ACTION_COPY
&& GetEmptyRow().Is())
1359 const DataFlavorExVector
& _rFlavors
= GetDataFlavors();
1360 if(::std::any_of(_rFlavors
.begin(),_rFlavors
.end(),SbaGridControlPrec(true)))
1361 nAction
= DND_ACTION_COPY
;
1364 return (DND_ACTION_NONE
!= nAction
) ? nAction
: FmGridControl::AcceptDrop(rEvt
);
1367 sal_Int8
SbaGridControl::ExecuteDrop( const BrowserExecuteDropEvent
& rEvt
)
1369 // we need some properties of our data source
1370 Reference
< XPropertySet
> xDataSource
= getDataSource();
1371 if (!xDataSource
.is())
1372 return DND_ACTION_NONE
;
1374 // we need a valid connection
1375 if (!::dbtools::getConnection(Reference
< XRowSet
> (xDataSource
,UNO_QUERY
)).is())
1376 return DND_ACTION_NONE
;
1378 if ( IsDropFormatSupported( SotClipboardFormatId::STRING
) )
1380 long nRow
= GetRowAtYPosPixel(rEvt
.maPosPixel
.Y(), false);
1381 sal_uInt16 nCol
= GetColumnAtXPosPixel(rEvt
.maPosPixel
.X(), false);
1383 long nCorrectRowCount
= GetRowCount();
1384 if (GetOptions() & OPT_INSERT
)
1385 --nCorrectRowCount
; // there is a empty row for inserting records
1386 if (IsCurrentAppending())
1387 --nCorrectRowCount
; // the current data record doesn't really exist, we are appending a new one
1389 OSL_ENSURE((nCol
!= BROWSER_INVALIDID
) && (nRow
< nCorrectRowCount
), "SbaGridControl::Drop : dropped on an invalid position !");
1390 // AcceptDrop should have caught this
1392 // from now we work with ids instead of positions
1393 nCol
= GetColumnId(nCol
);
1395 GoToRowColumnId(nRow
, nCol
);
1399 CellControllerRef xCurrentController
= Controller();
1400 if (!xCurrentController
.Is() || !xCurrentController
->ISA(EditCellController
))
1401 return DND_ACTION_NONE
;
1402 Edit
& rEdit
= static_cast<Edit
&>(xCurrentController
->GetWindow());
1404 // get the dropped string
1405 TransferableDataHelper
aDropped( rEvt
.maDropEvent
.Transferable
);
1407 if ( !aDropped
.GetString( SotClipboardFormatId::STRING
, sDropped
) )
1408 return DND_ACTION_NONE
;
1410 rEdit
.SetText( sDropped
);
1411 xCurrentController
->SetModified();
1413 // SetText itself doesn't call a Modify as it isn't a user interaction
1415 return DND_ACTION_COPY
;
1418 if(GetEmptyRow().Is())
1420 const DataFlavorExVector
& _rFlavors
= GetDataFlavors();
1421 if( ::std::any_of(_rFlavors
.begin(),_rFlavors
.end(),SbaGridControlPrec(true)) )
1423 TransferableDataHelper
aDropped( rEvt
.maDropEvent
.Transferable
);
1424 m_aDataDescriptor
= ODataAccessObjectTransferable::extractObjectDescriptor(aDropped
);
1425 if (m_nAsyncDropEvent
)
1426 Application::RemoveUserEvent(m_nAsyncDropEvent
);
1427 m_nAsyncDropEvent
= Application::PostUserEvent(LINK(this, SbaGridControl
, AsynchDropEvent
), NULL
, true);
1428 return DND_ACTION_COPY
;
1432 return DND_ACTION_NONE
;
1435 Reference
< XPropertySet
> SbaGridControl::getDataSource() const
1437 Reference
< XPropertySet
> xReturn
;
1439 Reference
< XChild
> xColumns(GetPeer()->getColumns(), UNO_QUERY
);
1440 Reference
< XPropertySet
> xDataSource
;
1442 xReturn
= Reference
< XPropertySet
> (xColumns
->getParent(), UNO_QUERY
);
1447 IMPL_LINK_NOARG(SbaGridControl
, AsynchDropEvent
)
1449 m_nAsyncDropEvent
= 0;
1451 Reference
< XPropertySet
> xDataSource
= getDataSource();
1452 if ( xDataSource
.is() )
1454 bool bCountFinal
= false;
1455 xDataSource
->getPropertyValue(PROPERTY_ISROWCOUNTFINAL
) >>= bCountFinal
;
1457 setDataSource(NULL
); // deattach from grid control
1458 Reference
< XResultSetUpdate
> xResultSetUpdate(xDataSource
,UNO_QUERY
);
1459 ODatabaseImportExport
* pImExport
= new ORowSetImportExport(this,xResultSetUpdate
,m_aDataDescriptor
, getContext());
1460 Reference
<XEventListener
> xHolder
= pImExport
;
1464 pImExport
->initialize(m_aDataDescriptor
);
1466 if(!pImExport
->Read())
1468 OUString sError
= OUString(ModuleRes(STR_NO_COLUMNNAME_MATCHING
));
1469 throwGenericSQLException(sError
,NULL
);
1474 catch(const SQLException
& e
)
1478 ::dbaui::showError( ::dbtools::SQLExceptionInfo(e
), this, getContext() );
1480 catch(const Exception
& )
1484 DBG_UNHANDLED_EXCEPTION();
1487 setDataSource(Reference
< XRowSet
>(xDataSource
,UNO_QUERY
));
1489 m_aDataDescriptor
.clear();
1494 OUString
SbaGridControl::GetAccessibleObjectDescription( ::svt::AccessibleBrowseBoxObjType eObjType
,sal_Int32 _nPosition
) const
1497 if ( ::svt::BBTYPE_BROWSEBOX
== eObjType
)
1499 SolarMutexGuard aGuard
;
1500 sRet
= OUString(ModuleRes(STR_DATASOURCE_GRIDCONTROL_DESC
));
1503 sRet
= FmGridControl::GetAccessibleObjectDescription( eObjType
,_nPosition
);
1507 void SbaGridControl::DeleteSelectedRows()
1509 FmGridControl::DeleteSelectedRows();
1512 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */