LibreOffice Module dbaccess (master) 1
sbagrid.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <core_resource.hxx>
21
22#include <sot/exchange.hxx>
23
24#include <svx/dbaexchange.hxx>
25#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
26
27#include <sbagrid.hxx>
28#include <dlgsize.hxx>
29#include <com/sun/star/beans/XPropertyState.hpp>
30#include <com/sun/star/form/XForm.hpp>
31#include <com/sun/star/container/XIndexContainer.hpp>
32
33#include <com/sun/star/view/XSelectionSupplier.hpp>
34#include <com/sun/star/awt/XTextComponent.hpp>
35#include <com/sun/star/sdbc/XResultSetUpdate.hpp>
37
38#include <svl/numuno.hxx>
40
41#include <vcl/svapp.hxx>
42
46#include <comphelper/types.hxx>
47#include <com/sun/star/sdbc/DataType.hpp>
48#include <com/sun/star/sdbc/SQLException.hpp>
49#include <strings.hrc>
50#include <strings.hxx>
51#include <dbexchange.hxx>
53#include <UITools.hxx>
54#include <TokenWriter.hxx>
55#include <osl/diagnose.h>
56#include <algorithm>
57
58using namespace ::com::sun::star::ui::dialogs;
59using namespace ::com::sun::star::uno;
60using namespace ::com::sun::star::sdb;
61using namespace ::com::sun::star::sdbc;
62using namespace ::com::sun::star::sdbcx;
63using namespace ::com::sun::star::beans;
64using namespace ::com::sun::star::container;
65using namespace ::com::sun::star::datatransfer;
66using namespace ::com::sun::star::lang;
67using namespace ::com::sun::star::view;
68using namespace ::com::sun::star::form;
69using namespace ::com::sun::star::frame;
70using namespace ::com::sun::star::util;
71using namespace ::dbaui;
72using namespace ::dbtools;
73using namespace ::svx;
74using namespace ::svt;
75
76extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
78 css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& )
79{
80 return cppu::acquire(new SbaXGridControl(context));
81}
82
83css::uno::Sequence<OUString> SAL_CALL SbaXGridControl::getSupportedServiceNames()
84{
85 return { "com.sun.star.form.control.InteractionGridControl", "com.sun.star.form.control.GridControl",
86 "com.sun.star.awt.UnoControl" };
87}
88
89
90// SbaXGridControl
91
92OUString SAL_CALL SbaXGridControl::getImplementationName()
93{
94 return "com.sun.star.comp.dbu.SbaXGridControl";
95}
96
97SbaXGridControl::SbaXGridControl(const Reference< XComponentContext >& _rM)
98 : FmXGridControl(_rM)
99{
100}
101
103{
104}
105
107{
109
110 // translate properties into WinBits
111 WinBits nStyle = WB_TABSTOP;
112 Reference< XPropertySet > xModelSet(getModel(), UNO_QUERY);
113 if (xModelSet.is())
114 {
115 try
116 {
117 if (::comphelper::getINT16(xModelSet->getPropertyValue(PROPERTY_BORDER)))
118 nStyle |= WB_BORDER;
119 }
120 catch(Exception&)
121 {
122 }
123
124 }
125
126 pReturn->Create(pParent, nStyle);
127 return pReturn;
128}
129
131{
133 return aRet.hasValue() ? aRet : ::cppu::queryInterface(_rType,static_cast<css::frame::XDispatch*>(this));
134}
135
137{
141}
142
144{
145 return css::uno::Sequence<sal_Int8>();
146}
147
149{
150 FmXGridControl::createPeer(rToolkit, rParentPeer);
151
152 OSL_ENSURE(!mbCreatingPeer, "FmXGridControl::createPeer : recursion!");
153 // see the base class' createPeer for a comment on this
154
155 // TODO: why the hell this whole class does not use any mutex?
156
157 Reference< css::frame::XDispatch > xDisp(getPeer(), UNO_QUERY);
158 for (auto const& elem : m_aStatusMultiplexer)
159 {
160 if (elem.second.is() && elem.second->getLength())
161 xDisp->addStatusListener(elem.second, elem.first);
162 }
163}
164
165void SAL_CALL SbaXGridControl::dispatch(const css::util::URL& aURL, const Sequence< PropertyValue >& aArgs)
166{
167 Reference< css::frame::XDispatch > xDisp(getPeer(), UNO_QUERY);
168 if (xDisp.is())
169 xDisp->dispatch(aURL, aArgs);
170}
171
172void SAL_CALL SbaXGridControl::addStatusListener( const Reference< XStatusListener > & _rxListener, const URL& _rURL )
173{
174 ::osl::MutexGuard aGuard( GetMutex() );
175 if ( !_rxListener.is() )
176 return;
177
179 if ( !xMultiplexer.is() )
180 {
181 xMultiplexer = new SbaXStatusMultiplexer( *this, GetMutex() );
182 }
183
184 xMultiplexer->addInterface( _rxListener );
185 if ( getPeer().is() )
186 {
187 if ( 1 == xMultiplexer->getLength() )
188 { // the first external listener for this URL
189 Reference< XDispatch > xDisp( getPeer(), UNO_QUERY );
190 xDisp->addStatusListener( xMultiplexer, _rURL );
191 }
192 else
193 { // already have other listeners for this URL
194 _rxListener->statusChanged( xMultiplexer->getLastEvent() );
195 }
196 }
197}
198
199void SAL_CALL SbaXGridControl::removeStatusListener(const Reference< css::frame::XStatusListener > & _rxListener, const css::util::URL& _rURL)
200{
201 ::osl::MutexGuard aGuard( GetMutex() );
202
204 if (!xMultiplexer.is())
205 {
206 xMultiplexer = new SbaXStatusMultiplexer(*this,GetMutex());
207 }
208
209 if (getPeer().is() && xMultiplexer->getLength() == 1)
210 {
211 Reference< css::frame::XDispatch > xDisp(getPeer(), UNO_QUERY);
212 xDisp->removeStatusListener(xMultiplexer, _rURL);
213 }
214 xMultiplexer->removeInterface( _rxListener );
215}
216
218{
219 SolarMutexGuard aGuard;
220
221 EventObject aEvt;
222 aEvt.Source = *this;
223
224 for (auto & elem : m_aStatusMultiplexer)
225 {
226 if (elem.second.is())
227 {
228 elem.second->disposeAndClear(aEvt);
229 elem.second.clear();
230 }
231 }
233
235}
236
237// SbaXGridPeer
239: FmXGridPeer(_rM)
240{
241}
242
244{
245}
246
248{
249 {
250 std::unique_lock g(m_aMutex);
251 EventObject aEvt(*this);
252 m_aStatusListeners.disposeAndClear(g, aEvt);
253 }
255}
256
257void SbaXGridPeer::NotifyStatusChanged(const css::util::URL& _rUrl, const Reference< css::frame::XStatusListener > & xControl)
258{
259 VclPtr< SbaGridControl > pGrid = GetAs< SbaGridControl >();
260 if (!pGrid)
261 return;
262
263 css::frame::FeatureStateEvent aEvt;
264 aEvt.Source = *this;
265 aEvt.IsEnabled = !pGrid->IsReadOnlyDB();
266 aEvt.FeatureURL = _rUrl;
267
268 MapDispatchToBool::const_iterator aURLStatePos = m_aDispatchStates.find( classifyDispatchURL( _rUrl ) );
269 if ( m_aDispatchStates.end() != aURLStatePos )
270 aEvt.State <<= aURLStatePos->second;
271 else
272 aEvt.State <<= false;
273
274 if (xControl.is())
275 xControl->statusChanged(aEvt);
276 else
277 {
278 std::unique_lock g(m_aMutex);
280 = m_aStatusListeners.getContainer(g, _rUrl);
281
282 if (pIter)
283 {
284 pIter->notifyEach( g, &XStatusListener::statusChanged, aEvt );
285 }
286 }
287}
288
289Any SAL_CALL SbaXGridPeer::queryInterface(const Type& _rType)
290{
291 Any aRet = ::cppu::queryInterface(_rType,static_cast<css::frame::XDispatch*>(this));
292 if(aRet.hasValue())
293 return aRet;
294 return FmXGridPeer::queryInterface(_rType);
295}
296
297Reference< css::frame::XDispatch > SAL_CALL SbaXGridPeer::queryDispatch(const css::util::URL& aURL, const OUString& aTargetFrameName, sal_Int32 nSearchFlags)
298{
299 if ( ( aURL.Complete == ".uno:GridSlots/BrowserAttribs" ) || ( aURL.Complete == ".uno:GridSlots/RowHeight" )
300 || ( aURL.Complete == ".uno:GridSlots/ColumnAttribs" ) || ( aURL.Complete == ".uno:GridSlots/ColumnWidth" )
301 )
302 {
303 return static_cast<css::frame::XDispatch*>(this);
304 }
305
306 return FmXGridPeer::queryDispatch(aURL, aTargetFrameName, nSearchFlags);
307}
308
309IMPL_LINK_NOARG( SbaXGridPeer, OnDispatchEvent, void*, void )
310{
311 VclPtr< SbaGridControl > pGrid = GetAs< SbaGridControl >();
312 if ( !pGrid ) // if this fails, we were disposing before arriving here
313 return;
314
316 {
317 // still not in the main thread (see SbaXGridPeer::dispatch). post an event, again
318 // without moving the special even to the back of the queue
319 pGrid->PostUserEvent( LINK( this, SbaXGridPeer, OnDispatchEvent ) );
320 }
321 else
322 {
323 DispatchArgs aArgs = m_aDispatchArgs.front();
324 m_aDispatchArgs.pop();
325
326 SbaXGridPeer::dispatch( aArgs.aURL, aArgs.aArgs );
327 }
328}
329
331{
332 DispatchType eURLType = dtUnknown;
333 if ( _rURL.Complete == ".uno:GridSlots/BrowserAttribs" )
334 eURLType = dtBrowserAttribs;
335 else if ( _rURL.Complete == ".uno:GridSlots/RowHeight" )
336 eURLType = dtRowHeight;
337 else if ( _rURL.Complete == ".uno:GridSlots/ColumnAttribs" )
338 eURLType = dtColumnAttribs;
339 else if ( _rURL.Complete == ".uno:GridSlots/ColumnWidth" )
340 eURLType = dtColumnWidth;
341 return eURLType;
342}
343
344void SAL_CALL SbaXGridPeer::dispatch(const URL& aURL, const Sequence< PropertyValue >& aArgs)
345{
346 VclPtr< SbaGridControl > pGrid = GetAs< SbaGridControl >();
347 if (!pGrid)
348 return;
349
351 {
352 // we're not in the main thread. This is bad, as we want to raise windows here,
353 // and VCL does not like windows to be opened in non-main threads (at least on Win32).
354 // Okay, do this async. No problem with this, as XDispatch::dispatch is defined to be
355 // a one-way method.
356
357 // save the args
358 DispatchArgs aDispatchArgs;
359 aDispatchArgs.aURL = aURL;
360 aDispatchArgs.aArgs = aArgs;
361 m_aDispatchArgs.push( aDispatchArgs );
362
363 // post an event
364 // we use the Window::PostUserEvent here, instead of the application::PostUserEvent
365 // this saves us from keeping track of these events - as soon as the window dies,
366 // the events are deleted automatically. For the application way, we would need to
367 // do this ourself.
368 // As we use our grid as window, and the grid dies before we die, this should be no problem.
369 pGrid->PostUserEvent( LINK( this, SbaXGridPeer, OnDispatchEvent ) );
370 return;
371 }
372
373 SolarMutexGuard aGuard;
374 sal_Int16 nColId = -1;
375 for (const PropertyValue& rArg : aArgs)
376 {
377 if (rArg.Name == "ColumnViewPos")
378 {
379 nColId = pGrid->GetColumnIdFromViewPos(::comphelper::getINT16(rArg.Value));
380 break;
381 }
382 if (rArg.Name == "ColumnModelPos")
383 {
384 nColId = pGrid->GetColumnIdFromModelPos(::comphelper::getINT16(rArg.Value));
385 break;
386 }
387 if (rArg.Name == "ColumnId")
388 {
389 nColId = ::comphelper::getINT16(rArg.Value);
390 break;
391 }
392 }
393
395
396 if ( dtUnknown == eURLType )
397 return;
398
399 // notify any status listeners that the dialog is now active (well, about to be active)
400 MapDispatchToBool::const_iterator aThisURLState = m_aDispatchStates.emplace( eURLType, true ).first;
401 NotifyStatusChanged( aURL, nullptr );
402
403 // execute the dialog
404 switch ( eURLType )
405 {
406 case dtBrowserAttribs:
407 pGrid->SetBrowserAttrs();
408 break;
409
410 case dtRowHeight:
411 pGrid->SetRowHeight();
412 break;
413
414 case dtColumnAttribs:
415 {
416 OSL_ENSURE(nColId != -1, "SbaXGridPeer::dispatch : invalid parameter !");
417 if (nColId != -1)
418 break;
419 pGrid->SetColAttrs(nColId);
420 }
421 break;
422
423 case dtColumnWidth:
424 {
425 OSL_ENSURE(nColId != -1, "SbaXGridPeer::dispatch : invalid parameter !");
426 if (nColId != -1)
427 break;
428 pGrid->SetColWidth(nColId);
429 }
430 break;
431
432 case dtUnknown:
433 break;
434 }
435
436 // notify any status listeners that the dialog vanished
437 m_aDispatchStates.erase( aThisURLState );
438 NotifyStatusChanged( aURL, nullptr );
439}
440
441void SAL_CALL SbaXGridPeer::addStatusListener(const Reference< css::frame::XStatusListener > & xControl, const css::util::URL& aURL)
442{
443 {
444 std::unique_lock g(m_aMutex);
446 = m_aStatusListeners.getContainer(g, aURL);
447 if (!pCont)
448 m_aStatusListeners.addInterface(g, aURL,xControl);
449 else
450 pCont->addInterface(g, xControl);
451 }
452 NotifyStatusChanged(aURL, xControl);
453}
454
455void SAL_CALL SbaXGridPeer::removeStatusListener(const Reference< css::frame::XStatusListener > & xControl, const css::util::URL& aURL)
456{
457 std::unique_lock g(m_aMutex);
459 if ( pCont )
460 pCont->removeInterface(g, xControl);
461}
462
464{
466 FmXGridPeer::getTypes(),
468}
469
471{
472 return VclPtr<SbaGridControl>::Create( m_xContext, pParent, this, nStyle);
473}
474
475// SbaGridHeader
476
479 ,DragSourceHelper(this)
480{
481}
482
484{
485 disposeOnce();
486}
487
489{
490 DragSourceHelper::dispose();
492}
493
494void SbaGridHeader::StartDrag( sal_Int8 _nAction, const Point& _rPosPixel )
495{
496 SolarMutexGuard aGuard;
497 // in the new DnD API, the solar mutex is not locked when StartDrag is called
498
499 ImplStartColumnDrag( _nAction, _rPosPixel );
500}
501
503{
504 if (_rMEvt.IsLeft())
505 if (_rMEvt.GetClicks() != 2)
506 {
507 // the base class will start a column move here, which we don't want to allow
508 // (at the moment. If we store relative positions with the columns, we can allow column moves...)
509
510 }
511
512 FmGridHeader::MouseButtonDown(_rMEvt);
513}
514
515void SbaGridHeader::ImplStartColumnDrag(sal_Int8 _nAction, const Point& _rMousePos)
516{
517 sal_uInt16 nId = GetItemId(_rMousePos);
518 bool bResizingCol = false;
520 {
521 tools::Rectangle aColRect = GetItemRect(nId);
522 aColRect.AdjustLeft(nId ? 3 : 0 ); // the handle col (nId == 0) does not have a left margin for resizing
523 aColRect.AdjustRight( -3 );
524 bResizingCol = !aColRect.Contains(_rMousePos);
525 }
526 if (bResizingCol)
527 return;
528
529 // force the base class to end its drag mode
530 EndTracking(TrackingEventFlags::Cancel | TrackingEventFlags::End);
531
532 // because we have 3d-buttons the select handler is called from MouseButtonUp, but StartDrag
533 // occurs earlier (while the mouse button is down)
534 // so for optical reasons we select the column before really starting the drag operation.
536
537 static_cast<SbaGridControl*>(GetParent())->StartDrag(_nAction,
538 Point(
539 _rMousePos.X() + GetPosPixel().X(), // we aren't left-justified with our parent, in contrast to the data window
540 _rMousePos.Y() - GetSizePixel().Height()
541 )
542 );
543}
544
546 weld::Menu& rInsertMenu, weld::Menu& rChangeMenu,
547 weld::Menu& rShowMenu)
548{
549 FmGridHeader::PreExecuteColumnContextMenu(nColId, rMenu, rInsertMenu, rChangeMenu, rShowMenu);
550
551 // some items are valid only if the db isn't readonly
552 bool bDBIsReadOnly = static_cast<SbaGridControl*>(GetParent())->IsReadOnlyDB();
553
554 if (bDBIsReadOnly)
555 {
556 rMenu.set_visible("hide", false);
557 rMenu.set_sensitive("hide", false);
558 rMenu.set_visible("show", false);
559 rMenu.set_sensitive("show", false);
560 }
561
562 // prepend some new items
563 bool bColAttrs = (nColId != sal_uInt16(-1)) && (nColId != 0);
564 if ( !bColAttrs || bDBIsReadOnly)
565 return;
566
567 sal_uInt16 nPos = 0;
568 sal_uInt16 nModelPos = static_cast<SbaGridControl*>(GetParent())->GetModelColumnPos(nColId);
569 Reference< XPropertySet > xField = static_cast<SbaGridControl*>(GetParent())->getField(nModelPos);
570
571 if ( xField.is() )
572 {
573 switch( ::comphelper::getINT32(xField->getPropertyValue(PROPERTY_TYPE)) )
574 {
575 case DataType::BINARY:
576 case DataType::VARBINARY:
577 case DataType::LONGVARBINARY:
578 case DataType::SQLNULL:
579 case DataType::OBJECT:
580 case DataType::BLOB:
581 case DataType::CLOB:
582 case DataType::REF:
583 break;
584 default:
585 rMenu.insert(nPos++, "colattrset", DBA_RES(RID_STR_COLUMN_FORMAT),
586 nullptr, nullptr, nullptr, TRISTATE_INDET);
587 rMenu.insert_separator(nPos++, "separator1");
588 }
589 }
590
591 rMenu.insert(nPos++, "colwidth", DBA_RES(RID_STR_COLUMN_WIDTH),
592 nullptr, nullptr, nullptr, TRISTATE_INDET);
593 rMenu.insert_separator(nPos++, "separator2");
594}
595
596void SbaGridHeader::PostExecuteColumnContextMenu(sal_uInt16 nColId, const weld::Menu& rMenu, const OUString& rExecutionResult)
597{
598 if (rExecutionResult == "colwidth")
599 static_cast<SbaGridControl*>(GetParent())->SetColWidth(nColId);
600 else if (rExecutionResult == "colattrset")
601 static_cast<SbaGridControl*>(GetParent())->SetColAttrs(nColId);
602 else
603 FmGridHeader::PostExecuteColumnContextMenu(nColId, rMenu, rExecutionResult);
604}
605
606// SbaGridControl
608 vcl::Window* pParent, FmXGridPeer* _pPeer, WinBits nBits)
609 :FmGridControl(_rM,pParent, _pPeer, nBits)
610 ,m_pMasterListener(nullptr)
611 ,m_nAsyncDropEvent(nullptr)
612 ,m_bActivatingForDrop(false)
613{
614}
615
617{
618 disposeOnce();
619}
620
622{
625 m_nAsyncDropEvent = nullptr;
627}
628
630{
631 return VclPtr<SbaGridHeader>::Create(pParent);
632}
633
634CellController* SbaGridControl::GetController(sal_Int32 nRow, sal_uInt16 nCol)
635{
637 return nullptr;
638
639 return FmGridControl::GetController(nRow, nCol);
640}
641
643{
645
646 sal_uInt16 nPos = 0;
647
648 if (!IsReadOnlyDB())
649 {
650 rMenu.insert(nPos++, "tableattr", DBA_RES(RID_STR_TABLE_FORMAT),
651 nullptr, nullptr, nullptr, TRISTATE_INDET);
652 rMenu.insert(nPos++, "rowheight", DBA_RES(RID_STR_ROW_HEIGHT),
653 nullptr, nullptr, nullptr, TRISTATE_INDET);
654 rMenu.insert_separator(nPos++, "separator1");
655 }
656
657 if ( GetSelectRowCount() > 0 )
658 {
659 rMenu.insert(nPos++, "copy", DBA_RES(RID_STR_COPY),
660 nullptr, nullptr, nullptr, TRISTATE_INDET);
661 rMenu.insert_separator(nPos++, "separator2");
662 }
663}
664
666{
667 Reference< css::util::XNumberFormatsSupplier > xSupplier = ::dbtools::getNumberFormats(::dbtools::getConnection(Reference< XRowSet > (getDataSource(),UNO_QUERY)), true, getContext());
668
669 SvNumberFormatsSupplierObj* pSupplierImpl = comphelper::getFromUnoTunnel<SvNumberFormatsSupplierObj>( xSupplier );
670 if ( !pSupplierImpl )
671 return nullptr;
672
673 SvNumberFormatter* pFormatter = pSupplierImpl->GetNumberFormatter();
674 return pFormatter;
675}
676
677void SbaGridControl::SetColWidth(sal_uInt16 nColId)
678{
679 // get the (UNO) column model
680 sal_uInt16 nModelPos = GetModelColumnPos(nColId);
682 Reference< XPropertySet > xAffectedCol;
683 if (xCols.is() && (nModelPos != sal_uInt16(-1)))
684 xAffectedCol.set(xCols->getByIndex(nModelPos), css::uno::UNO_QUERY);
685
686 if (!xAffectedCol.is())
687 return;
688
689 Any aWidth = xAffectedCol->getPropertyValue(PROPERTY_WIDTH);
690 sal_Int32 nCurWidth = aWidth.hasValue() ? ::comphelper::getINT32(aWidth) : -1;
691
692 DlgSize aDlgColWidth(GetFrameWeld(), nCurWidth, false);
693 if (aDlgColWidth.run() != RET_OK)
694 return;
695
696 sal_Int32 nValue = aDlgColWidth.GetValue();
697 Any aNewWidth;
698 if (-1 == nValue)
699 { // set to default
700 Reference< XPropertyState > xPropState(xAffectedCol, UNO_QUERY);
701 if (xPropState.is())
702 {
703 try { aNewWidth = xPropState->getPropertyDefault(PROPERTY_WIDTH); } catch(Exception&) { } ;
704 }
705 }
706 else
707 aNewWidth <<= nValue;
708 try { xAffectedCol->setPropertyValue(PROPERTY_WIDTH, aNewWidth); } catch(Exception&) { } ;
709}
710
712{
713 Reference< XPropertySet > xCols(GetPeer()->getColumns(), UNO_QUERY);
714 if (!xCols.is())
715 return;
716
717 Any aHeight = xCols->getPropertyValue(PROPERTY_ROW_HEIGHT);
718 sal_Int32 nCurHeight = aHeight.hasValue() ? ::comphelper::getINT32(aHeight) : -1;
719
720 DlgSize aDlgRowHeight(GetFrameWeld(), nCurHeight, true);
721 if (aDlgRowHeight.run() != RET_OK)
722 return;
723
724 sal_Int32 nValue = aDlgRowHeight.GetValue();
725 Any aNewHeight;
726 if (sal_Int16(-1) == nValue)
727 { // set to default
728 Reference< XPropertyState > xPropState(xCols, UNO_QUERY);
729 if (xPropState.is())
730 {
731 try
732 {
733 aNewHeight = xPropState->getPropertyDefault(PROPERTY_ROW_HEIGHT);
734 }
735 catch(Exception&)
736 { }
737 }
738 }
739 else
740 aNewHeight <<= nValue;
741 try
742 {
743 xCols->setPropertyValue(PROPERTY_ROW_HEIGHT, aNewHeight);
744 }
745 catch(Exception&)
746 {
747 TOOLS_WARN_EXCEPTION( "dbaccess", "setPropertyValue: PROPERTY_ROW_HEIGHT throws an exception");
748 }
749}
750
751void SbaGridControl::SetColAttrs(sal_uInt16 nColId)
752{
754 if (!pFormatter)
755 return;
756
757 sal_uInt16 nModelPos = GetModelColumnPos(nColId);
758
759 // get the (UNO) column model
761 Reference< XPropertySet > xAffectedCol;
762 if (xCols.is() && (nModelPos != sal_uInt16(-1)))
763 xAffectedCol.set(xCols->getByIndex(nModelPos), css::uno::UNO_QUERY);
764
765 // get the field the column is bound to
766 Reference< XPropertySet > xField = getField(nModelPos);
767 ::dbaui::callColumnFormatDialog(xAffectedCol,xField,pFormatter,GetFrameWeld());
768}
769
771{
772 Reference< XPropertySet > xGridModel(GetPeer()->getColumns(), UNO_QUERY);
773 if (!xGridModel.is())
774 return;
775
776 try
777 {
779 css::uno::Sequence<css::uno::Any> aArguments{
780 Any(comphelper::makePropertyValue("IntrospectedObject", xGridModel)),
782 };
783 Reference<XExecutableDialog> xExecute(xContext->getServiceManager()->createInstanceWithArgumentsAndContext("com.sun.star.form.ControlFontDialog",
784 aArguments, xContext), css::uno::UNO_QUERY_THROW);
785 xExecute->execute();
786 }
787 catch( const Exception& )
788 {
789 DBG_UNHANDLED_EXCEPTION("dbaccess");
790 }
791}
792
793void SbaGridControl::PostExecuteRowContextMenu(const OUString& rExecutionResult)
794{
795 if (rExecutionResult == "tableattr")
797 else if (rExecutionResult == "rowheight")
798 SetRowHeight();
799 else if (rExecutionResult == "copy")
801 else
803}
804
806{
807 // Some selection has changed ...
809
812}
813
814void SbaGridControl::ActivateCell(sal_Int32 nRow, sal_uInt16 nCol, bool bSetCellFocus /*= sal_True*/ )
815{
816 FmGridControl::ActivateCell(nRow, nCol, bSetCellFocus);
819}
820
821void SbaGridControl::DeactivateCell(bool bUpdate /*= sal_True*/)
822{
823 FmGridControl::DeactivateCell(bUpdate);
826}
827
829{
830 if ( m_pMasterListener )
832}
833
835{
836 if ( m_pMasterListener )
838}
839
841{
842 Reference< XPropertySet > xEmptyReturn;
843 try
844 {
845 // first get the name of the column
847 if ( xCols.is() && xCols->getCount() > nModelPos )
848 {
849 Reference< XPropertySet > xCol(xCols->getByIndex(nModelPos),UNO_QUERY);
850 if ( xCol.is() )
851 xEmptyReturn.set(xCol->getPropertyValue(PROPERTY_BOUNDFIELD),UNO_QUERY);
852 }
853 else
854 OSL_FAIL("SbaGridControl::getField getColumns returns NULL or ModelPos is > than count!");
855 }
856 catch (const Exception&)
857 {
858 TOOLS_WARN_EXCEPTION("dbaccess", "SbaGridControl::getField Exception occurred");
859 }
860
861 return xEmptyReturn;
862}
863
865{
866 // assume yes if anything fails
867 bool bDBIsReadOnly = true;
868
869 try
870 {
871 // the db is the implemented by the parent of the grid control's model ...
872 Reference< XChild > xColumns(GetPeer()->getColumns(), UNO_QUERY);
873 if (xColumns.is())
874 {
875 Reference< XRowSet > xDataSource(xColumns->getParent(), UNO_QUERY);
876 ::dbtools::ensureRowSetConnection( xDataSource, getContext(), nullptr );
877 Reference< XChild > xConn(::dbtools::getConnection(xDataSource),UNO_QUERY);
878 if (xConn.is())
879 {
880 // ... and the RO-flag simply is implemented by a property
881 Reference< XPropertySet > xDbProps(xConn->getParent(), UNO_QUERY);
882 if (xDbProps.is())
883 {
884 Reference< XPropertySetInfo > xInfo = xDbProps->getPropertySetInfo();
885 if (xInfo->hasPropertyByName(PROPERTY_ISREADONLY))
886 bDBIsReadOnly = ::comphelper::getBOOL(xDbProps->getPropertyValue(PROPERTY_ISREADONLY));
887 }
888 }
889 }
890 }
891 catch (const Exception&)
892 {
893 TOOLS_WARN_EXCEPTION("dbaccess", "SbaGridControl::IsReadOnlyDB Exception occurred");
894 }
895
896 return bDBIsReadOnly;
897}
898
900{
901 sal_Int32 nRow = GetRowAtYPosPixel(rMEvt.GetPosPixel().Y());
902 sal_uInt16 nColPos = GetColumnAtXPosPixel(rMEvt.GetPosPixel().X());
903 sal_uInt16 nViewPos = (nColPos == BROWSER_INVALIDID) ? sal_uInt16(-1) : nColPos-1;
904 // 'the handle column' and 'no valid column' will both result in a view position of -1 !
905
906 bool bHitEmptySpace = (nRow > GetRowCount()) || (nViewPos == sal_uInt16(-1));
907
908 if (bHitEmptySpace && (rMEvt.GetClicks() == 2) && rMEvt.IsMod1())
910 else
911 FmGridControl::MouseButtonDown(rMEvt);
912}
913
914void SbaGridControl::StartDrag( sal_Int8 _nAction, const Point& _rPosPixel )
915{
916 SolarMutexGuard aGuard;
917 // in the new DnD API, the solar mutex is not locked when StartDrag is called
918
919 bool bHandled = false;
920
921 do
922 {
923 // determine if dragging is allowed
924 // (Yes, this is controller (not view) functionality. But collecting and evaluating all the
925 // information necessary via UNO would be quite difficult (if not impossible) so
926 // my laziness says 'do it here'...)
927 sal_Int32 nRow = GetRowAtYPosPixel(_rPosPixel.Y());
928 sal_uInt16 nColPos = GetColumnAtXPosPixel(_rPosPixel.X());
929 sal_uInt16 nViewPos = (nColPos == BROWSER_INVALIDID) ? sal_uInt16(-1) : nColPos-1;
930 // 'the handle column' and 'no valid column' will both result in a view position of -1 !
931
932 bool bCurrentRowVirtual = IsCurrentAppending() && IsModified();
933 // the current row doesn't really exist: the user's appending a new one and already has entered some data,
934 // so the row contains data which has no counter part within the data source
935
936 sal_Int32 nCorrectRowCount = GetRowCount();
937 if (GetOptions() & DbGridControlOptions::Insert)
938 --nCorrectRowCount; // there is an empty row for inserting records
939 if (bCurrentRowVirtual)
940 --nCorrectRowCount;
941
942 if ((nColPos == BROWSER_INVALIDID) || (nRow >= nCorrectRowCount))
943 break;
944
945 bool bHitHandle = (nColPos == 0);
946
947 // check which kind of dragging has to be initiated
948 if ( bHitHandle // the handle column
949 // AND
950 && ( GetSelectRowCount() // at least one row is selected
951 // OR
952 || ( (nRow >= 0) // a row below the header
953 && !bCurrentRowVirtual // we aren't appending a new record
954 && (nRow != GetCurrentPos()) // a row which is not the current one
955 ) // OR
956 || ( (0 == GetSelectRowCount()) // no rows selected
957 && (-1 == nRow) // hit the header
958 )
959 )
960 )
961 { // => start dragging the row
962 if (GetDataWindow().IsMouseCaptured())
963 GetDataWindow().ReleaseMouse();
964
965 if (0 == GetSelectRowCount())
966 // no rows selected, but here in this branch
967 // -> the user started dragging the upper left corner, which symbolizes the whole table
968 SelectAll();
969
970 getMouseEvent().Clear();
971 implTransferSelectedRows(static_cast<sal_Int16>(nRow), false);
972
973 bHandled = true;
974 }
975 else if ( (nRow < 0) // the header
976 && (!bHitHandle) // non-handle column
977 && (nViewPos < GetViewColCount()) // valid (existing) column
978 )
979 { // => start dragging the column
980 if (GetDataWindow().IsMouseCaptured())
981 GetDataWindow().ReleaseMouse();
982
983 getMouseEvent().Clear();
984 DoColumnDrag(nViewPos);
985
986 bHandled = true;
987 }
988 else if ( !bHitHandle // non-handle column
989 && (nRow >= 0) // non-header row
990 )
991 { // => start dragging the field content
992 if (GetDataWindow().IsMouseCaptured())
993 GetDataWindow().ReleaseMouse();
994
995 getMouseEvent().Clear();
996 DoFieldDrag(nViewPos, static_cast<sal_Int16>(nRow));
997
998 bHandled = true;
999 }
1000 }
1001 while (false);
1002
1003 if (!bHandled)
1004 FmGridControl::StartDrag(_nAction, _rPosPixel);
1005}
1006
1007void SbaGridControl::DoColumnDrag(sal_uInt16 nColumnPos)
1008{
1010 OSL_ENSURE(xDataSource.is(), "SbaGridControl::DoColumnDrag : invalid data source !");
1011 ::dbtools::ensureRowSetConnection(Reference< XRowSet >(getDataSource(),UNO_QUERY), getContext(), nullptr);
1012
1013 Reference< XPropertySet > xAffectedCol;
1014 Reference< XPropertySet > xAffectedField;
1015 Reference< XConnection > xActiveConnection;
1016
1017 // determine the field to drag
1018 OUString sField;
1019 try
1020 {
1021 xActiveConnection = ::dbtools::getConnection(Reference< XRowSet >(getDataSource(),UNO_QUERY));
1022
1023 sal_uInt16 nModelPos = GetModelColumnPos(GetColumnIdFromViewPos(nColumnPos));
1025 xAffectedCol.set(xCols->getByIndex(nModelPos),UNO_QUERY);
1026 if (xAffectedCol.is())
1027 {
1028 xAffectedCol->getPropertyValue(PROPERTY_CONTROLSOURCE) >>= sField;
1029 xAffectedField.set(xAffectedCol->getPropertyValue(PROPERTY_BOUNDFIELD),UNO_QUERY);
1030 }
1031 }
1032 catch(Exception&)
1033 {
1034 OSL_FAIL("SbaGridControl::DoColumnDrag : something went wrong while getting the column");
1035 }
1036 if (sField.isEmpty())
1037 return;
1038
1039 rtl::Reference<OColumnTransferable> pDataTransfer = new OColumnTransferable(xDataSource, sField, xAffectedField, xActiveConnection, ColumnTransferFormatFlags::FIELD_DESCRIPTOR | ColumnTransferFormatFlags::COLUMN_DESCRIPTOR);
1040 pDataTransfer->StartDrag(this, DND_ACTION_COPY | DND_ACTION_LINK);
1041}
1042
1044{
1045 OSL_ENSURE( GetSelectRowCount() > 0, "SbaGridControl::CopySelectedRowsToClipboard: invalid call!" );
1046 implTransferSelectedRows( static_cast<sal_Int16>(FirstSelectedRow()), true );
1047}
1048
1049void SbaGridControl::implTransferSelectedRows( sal_Int16 nRowPos, bool _bTrueIfClipboardFalseIfDrag )
1050{
1052 OSL_ENSURE( xForm.is(), "SbaGridControl::implTransferSelectedRows: invalid form!" );
1053
1054 // build the sequence of numbers of selected rows
1055 Sequence< Any > aSelectedRows;
1056 bool bSelectionBookmarks = true;
1057
1058 // collect the affected rows
1059 if ((GetSelectRowCount() == 0) && (nRowPos >= 0))
1060 {
1061 aSelectedRows = { Any(static_cast<sal_Int32>(nRowPos + 1)) };
1062 bSelectionBookmarks = false;
1063 }
1064 else if ( !IsAllSelected() && GetSelectRowCount() )
1065 {
1066 aSelectedRows = getSelectionBookmarks();
1067 bSelectionBookmarks = true;
1068 }
1069
1070 try
1071 {
1072 rtl::Reference<ODataClipboard> pTransfer = new ODataClipboard( xForm, aSelectedRows, bSelectionBookmarks, getContext() );
1073
1074 if ( _bTrueIfClipboardFalseIfDrag )
1075 pTransfer->CopyToClipboard( this );
1076 else
1077 pTransfer->StartDrag(this, DND_ACTION_COPY | DND_ACTION_LINK);
1078 }
1079 catch(Exception&)
1080 {
1081 }
1082}
1083
1084void SbaGridControl::DoFieldDrag(sal_uInt16 nColumnPos, sal_Int16 nRowPos)
1085{
1086 // the only thing to do here is dragging the pure cell text
1087 // the old implementation copied a SBA_FIELDDATAEXCHANGE_FORMAT, too, (which was rather expensive to obtain),
1088 // but we have no client for this DnD format anymore (the mail part of SO 5.2 was the only client)
1089
1090 try
1091 {
1092 OUString sCellText;
1094 Sequence<sal_Bool> aSupportingText = xFieldData->queryFieldDataType(cppu::UnoType<decltype(sCellText)>::get());
1095 if (aSupportingText.getConstArray()[nColumnPos])
1096 {
1097 Sequence< Any> aCellContents = xFieldData->queryFieldData(nRowPos, cppu::UnoType<decltype(sCellText)>::get());
1098 sCellText = ::comphelper::getString(aCellContents.getConstArray()[nColumnPos]);
1100 }
1101 }
1102 catch(Exception&)
1103 {
1104 OSL_FAIL("SbaGridControl::DoFieldDrag : could not retrieve the cell's contents !");
1105 return;
1106 }
1107
1108}
1109
1110 namespace {
1111
1113 struct SbaGridControlPrec
1114 {
1115 bool operator()(const DataFlavorExVector::value_type& _aType)
1116 {
1117 switch (_aType.mnSotId)
1118 {
1119 case SotClipboardFormatId::DBACCESS_TABLE: // table descriptor
1120 case SotClipboardFormatId::DBACCESS_QUERY: // query descriptor
1121 case SotClipboardFormatId::DBACCESS_COMMAND: // SQL command
1122 return true;
1123 default: break;
1124 }
1125 return false;
1126 }
1127 };
1128
1129 }
1130
1132{
1133 sal_Int8 nAction = DND_ACTION_NONE;
1134
1135 // we need a valid connection
1136 if (!::dbtools::getConnection(Reference< XRowSet > (getDataSource(),UNO_QUERY)).is())
1137 return nAction;
1138
1139 if ( IsDropFormatSupported( SotClipboardFormatId::STRING ) )
1140 do
1141 { // odd construction, but spares us a lot of (explicit ;) goto's
1142
1143 if (!GetEmptyRow().is())
1144 // without an empty row we're not in update mode
1145 break;
1146
1147 const sal_Int32 nRow = GetRowAtYPosPixel(rEvt.maPosPixel.Y(), false);
1148 const sal_uInt16 nCol = GetColumnId(GetColumnAtXPosPixel(rEvt.maPosPixel.X()));
1149
1150 sal_Int32 nCorrectRowCount = GetRowCount();
1151 if (GetOptions() & DbGridControlOptions::Insert)
1152 --nCorrectRowCount; // there is an empty row for inserting records
1153 if (IsCurrentAppending())
1154 --nCorrectRowCount; // the current data record doesn't really exist, we are appending a new one
1155
1156 if ( (nCol == BROWSER_INVALIDID) || (nRow >= nCorrectRowCount) || (nCol == 0) )
1157 // no valid cell under the mouse cursor
1158 break;
1159
1160 tools::Rectangle aRect = GetCellRect(nRow, nCol, false);
1161 if (!aRect.Contains(rEvt.maPosPixel))
1162 // not dropped within a cell (a cell isn't as wide as the column - the are small spaces)
1163 break;
1164
1165 if ((IsModified() || (GetCurrentRow().is() && GetCurrentRow()->IsModified())) && (GetCurrentPos() != nRow))
1166 // there is a current and modified row or cell and he text is to be dropped into another one
1167 break;
1168
1169 CellControllerRef xCurrentController = Controller();
1170 if (xCurrentController.is() && xCurrentController->IsValueChangedFromSaved() && ((nRow != GetCurRow()) || (nCol != GetCurColumnId())))
1171 // the current controller is modified and the user wants to drop in another cell -> no chance
1172 // (when leaving the modified cell an error may occur - this is deadly while dragging)
1173 break;
1174
1176 if (!xField.is())
1177 // the column is not valid bound (for instance a binary field)
1178 break;
1179
1180 try
1181 {
1182 if (::comphelper::getBOOL(xField->getPropertyValue(PROPERTY_ISREADONLY)))
1183 break;
1184 }
1185 catch (const Exception& )
1186 {
1187 // assume RO
1188 break;
1189 }
1190
1191 try
1192 {
1193 // assume that text can be dropped into a field if the column has a css::awt::XTextComponent interface
1194 Reference< XIndexAccess > xColumnControls(GetPeer());
1195 if (xColumnControls.is())
1196 {
1198 xColumnControls->getByIndex(GetViewColumnPos(nCol)),
1199 css::uno::UNO_QUERY);
1200 if (xColControl.is())
1201 {
1202 m_bActivatingForDrop = true;
1203 GoToRowColumnId(nRow, nCol);
1204 m_bActivatingForDrop = false;
1205
1206 nAction = DND_ACTION_COPY;
1207 }
1208 }
1209 }
1210 catch( const Exception& )
1211 {
1212 DBG_UNHANDLED_EXCEPTION("dbaccess");
1213 }
1214
1215 } while (false);
1216
1217 if(nAction != DND_ACTION_COPY && GetEmptyRow().is())
1218 {
1219 const DataFlavorExVector& _rFlavors = GetDataFlavors();
1220 if(std::any_of(_rFlavors.begin(),_rFlavors.end(),SbaGridControlPrec()))
1221 nAction = DND_ACTION_COPY;
1222 }
1223
1224 return (DND_ACTION_NONE != nAction) ? nAction : FmGridControl::AcceptDrop(rEvt);
1225}
1226
1228{
1229 // we need some properties of our data source
1231 if (!xDataSource.is())
1232 return DND_ACTION_NONE;
1233
1234 // we need a valid connection
1235 if (!::dbtools::getConnection(Reference< XRowSet > (xDataSource,UNO_QUERY)).is())
1236 return DND_ACTION_NONE;
1237
1238 if ( IsDropFormatSupported( SotClipboardFormatId::STRING ) )
1239 {
1240 sal_Int32 nRow = GetRowAtYPosPixel(rEvt.maPosPixel.Y(), false);
1241 sal_uInt16 nCol = GetColumnAtXPosPixel(rEvt.maPosPixel.X());
1242
1243 sal_Int32 nCorrectRowCount = GetRowCount();
1244 if (GetOptions() & DbGridControlOptions::Insert)
1245 --nCorrectRowCount; // there is an empty row for inserting records
1246 if (IsCurrentAppending())
1247 --nCorrectRowCount; // the current data record doesn't really exist, we are appending a new one
1248
1249 OSL_ENSURE((nCol != BROWSER_INVALIDID) && (nRow < nCorrectRowCount), "SbaGridControl::Drop : dropped on an invalid position !");
1250 // AcceptDrop should have caught this
1251
1252 // from now we work with ids instead of positions
1253 nCol = GetColumnId(nCol);
1254
1255 GoToRowColumnId(nRow, nCol);
1256 if (!IsEditing())
1257 ActivateCell();
1258
1259 CellControllerRef xCurrentController = Controller();
1260 EditCellController* pController = dynamic_cast<EditCellController*>(xCurrentController.get());
1261 if (!pController)
1262 return DND_ACTION_NONE;
1263
1264 // get the dropped string
1265 TransferableDataHelper aDropped( rEvt.maDropEvent.Transferable );
1266 OUString sDropped;
1267 if ( !aDropped.GetString( SotClipboardFormatId::STRING, sDropped ) )
1268 return DND_ACTION_NONE;
1269
1270 IEditImplementation* pEditImplementation = pController->GetEditImplementation();
1271 pEditImplementation->SetText(sDropped);
1272 // SetText itself doesn't call a Modify as it isn't a user interaction
1273 pController->Modify();
1274
1275 return DND_ACTION_COPY;
1276 }
1277
1278 if(GetEmptyRow().is())
1279 {
1280 const DataFlavorExVector& _rFlavors = GetDataFlavors();
1281 if( std::any_of(_rFlavors.begin(),_rFlavors.end(), SbaGridControlPrec()) )
1282 {
1283 TransferableDataHelper aDropped( rEvt.maDropEvent.Transferable );
1284 m_aDataDescriptor = ODataAccessObjectTransferable::extractObjectDescriptor(aDropped);
1287 m_nAsyncDropEvent = Application::PostUserEvent(LINK(this, SbaGridControl, AsynchDropEvent), nullptr, true);
1288 return DND_ACTION_COPY;
1289 }
1290 }
1291
1292 return DND_ACTION_NONE;
1293}
1294
1296{
1298
1299 Reference< XChild > xColumns(GetPeer()->getColumns(), UNO_QUERY);
1300 if (xColumns.is())
1301 xReturn.set(xColumns->getParent(), UNO_QUERY);
1302
1303 return xReturn;
1304}
1305
1306IMPL_LINK_NOARG(SbaGridControl, AsynchDropEvent, void*, void)
1307{
1308 m_nAsyncDropEvent = nullptr;
1309
1310 Reference< XPropertySet > xDataSource = getDataSource();
1311 if ( xDataSource.is() )
1312 {
1313 bool bCountFinal = false;
1314 xDataSource->getPropertyValue(PROPERTY_ISROWCOUNTFINAL) >>= bCountFinal;
1315 if ( !bCountFinal )
1316 setDataSource(nullptr); // detach from grid control
1317 Reference< XResultSetUpdate > xResultSetUpdate(xDataSource,UNO_QUERY);
1318 rtl::Reference<ODatabaseImportExport> pImExport = new ORowSetImportExport(GetFrameWeld(),xResultSetUpdate,m_aDataDescriptor, getContext());
1319 Hide();
1320 try
1321 {
1322 pImExport->initialize(m_aDataDescriptor);
1323 if (m_pMasterListener)
1324 m_pMasterListener->BeforeDrop();
1325 if(!pImExport->Read())
1326 {
1327 OUString sError = DBA_RES(STR_NO_COLUMNNAME_MATCHING);
1328 throwGenericSQLException(sError,nullptr);
1329 }
1330 if (m_pMasterListener)
1331 m_pMasterListener->AfterDrop();
1332 Show();
1333 }
1334 catch(const SQLException& e)
1335 {
1336 if (m_pMasterListener)
1337 m_pMasterListener->AfterDrop();
1338 Show();
1339 ::dbtools::showError( ::dbtools::SQLExceptionInfo(e), VCLUnoHelper::GetInterface(this), getContext() );
1340 }
1341 catch(const Exception& )
1342 {
1343 DBG_UNHANDLED_EXCEPTION("dbaccess");
1344 if (m_pMasterListener)
1345 m_pMasterListener->AfterDrop();
1346 Show();
1347 }
1348 if ( !bCountFinal )
1349 setDataSource(Reference< XRowSet >(xDataSource,UNO_QUERY));
1350 }
1351 m_aDataDescriptor.clear();
1352}
1353
1355{
1356 OUString sRet;
1357 if ( AccessibleBrowseBoxObjType::BrowseBox == eObjType )
1358 {
1359 SolarMutexGuard aGuard;
1360 sRet = DBA_RES(STR_DATASOURCE_GRIDCONTROL_DESC);
1361 }
1362 else
1363 sRet = FmGridControl::GetAccessibleObjectDescription( eObjType,_nPosition);
1364 return sRet;
1365}
1366
1367/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
AccessibleBrowseBoxObjType
#define BROWSER_INVALIDID
static bool IsMainThread()
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
static void RemoveUserEvent(ImplSVEvent *nUserEvent)
virtual ::svt::CellController * GetController(sal_Int32 nRow, sal_uInt16 nCol) override
sal_uInt16 GetViewColumnPos(sal_uInt16 nId) const
virtual bool IsModified() const override
sal_uInt16 GetColumnIdFromViewPos(sal_uInt16 nPos) const
virtual void StartDrag(sal_Int8 nAction, const Point &rPosPixel) override
DbGridControlOptions GetOptions() const
const DbGridRowRef & GetCurrentRow() const
sal_uInt16 GetModelColumnPos(sal_uInt16 nId) const
virtual void dispose() override
const css::uno::Reference< css::uno::XComponentContext > & getContext() const
virtual void PostExecuteRowContextMenu(const OUString &rExecutionResult)
bool IsCurrentAppending() const
sal_uInt16 GetViewColCount() const
const DbGridRowRef & GetEmptyRow() const
sal_Int32 GetCurrentPos() const
virtual void PreExecuteRowContextMenu(weld::Menu &rMenu)
virtual void Select() override
css::uno::Sequence< css::uno::Any > getSelectionBookmarks()
virtual OUString GetAccessibleObjectDescription(AccessibleBrowseBoxObjType eObjType, sal_Int32 _nPosition=-1) const override
FmXGridPeer * GetPeer() const
virtual void dispose() override
sal_uInt16 GetModelColumnPos(sal_uInt16 nId) const
virtual void PostExecuteColumnContextMenu(sal_uInt16 nColId, const weld::Menu &rMenu, const OUString &rExecutionResult)
virtual void PreExecuteColumnContextMenu(sal_uInt16 nColId, weld::Menu &rMenu, weld::Menu &rInsertMenu, weld::Menu &rChangeMenu, weld::Menu &rShowMenu)
void notifyColumnSelect(sal_uInt16 nColumnId)
virtual css::uno::Any SAL_CALL queryAggregation(const css::uno::Type &_rType) override
css::uno::Reference< css::uno::XComponentContext > m_xContext
virtual void SAL_CALL dispose() override
virtual void SAL_CALL createPeer(const css::uno::Reference< css::awt::XToolkit > &_rToolkit, const css::uno::Reference< css::awt::XWindowPeer > &Parent) override
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
css::uno::Reference< css::uno::XComponentContext > m_xContext
std::mutex m_aMutex
virtual css::uno::Reference< css::frame::XDispatch > SAL_CALL queryDispatch(const css::util::URL &aURL, const OUString &aTargetFrameName, sal_Int32 nSearchFlags) override
virtual void SAL_CALL dispose() override
virtual css::uno::Reference< css::container::XIndexContainer > SAL_CALL getColumns() override
sal_uInt16 GetClicks() const
bool IsLeft() const
constexpr tools::Long Y() const
constexpr tools::Long X() const
SvNumberFormatter * GetNumberFormatter() const
bool GetString(SotClipboardFormatId nFormat, OUString &rStr) const
static css::uno::Reference< css::awt::XWindow > GetInterface(vcl::Window *pWindow)
static VclPtr< reference_type > Create(Arg &&... arg)
sal_Int32 addInterface(std::unique_lock< std::mutex > &rGuard, const css::uno::Reference< ListenerT > &rxIFace)
void notifyEach(std::unique_lock< std::mutex > &rGuard, void(SAL_CALL ListenerT::*NotificationMethod)(const EventT &), const EventT &Event) const
sal_Int32 removeInterface(std::unique_lock< std::mutex > &rGuard, const css::uno::Reference< ListenerT > &rxIFace)
css::uno::Type const & get()
sal_Int32 GetValue() const
Definition: dlgsize.cxx:59
SbaGridListener * m_pMasterListener
Definition: sbagrid.hxx:202
SvNumberFormatter * GetDatasourceFormatter()
Definition: sbagrid.cxx:665
virtual OUString GetAccessibleObjectDescription(AccessibleBrowseBoxObjType eObjType, sal_Int32 _nPosition=-1) const override
return the description of the specified object.
Definition: sbagrid.cxx:1354
virtual void onColumnChange() override
Definition: sbagrid.cxx:834
virtual sal_Int8 AcceptDrop(const BrowserAcceptDropEvent &rEvt) override
Definition: sbagrid.cxx:1131
void DoColumnDrag(sal_uInt16 nColumnPos)
Definition: sbagrid.cxx:1007
virtual void PreExecuteRowContextMenu(weld::Menu &rMenu) override
Definition: sbagrid.cxx:642
void SetColWidth(sal_uInt16 nColId)
Definition: sbagrid.cxx:677
void SetColAttrs(sal_uInt16 nColId)
Definition: sbagrid.cxx:751
bool IsAllSelected() const
Definition: sbagrid.hxx:221
virtual ::svt::CellController * GetController(sal_Int32 nRow, sal_uInt16 nCol) override
Definition: sbagrid.cxx:634
css::uno::Reference< css::beans::XPropertySet > getDataSource() const
Definition: sbagrid.cxx:1295
virtual sal_Int8 ExecuteDrop(const BrowserExecuteDropEvent &rEvt) override
Definition: sbagrid.cxx:1227
void CopySelectedRowsToClipboard()
copies the currently selected rows to the clipboard @precond at least one row is selected
Definition: sbagrid.cxx:1043
virtual void StartDrag(sal_Int8 _nAction, const Point &_rPosPixel) override
Definition: sbagrid.cxx:914
virtual void DeactivateCell(bool bUpdate=true) override
Definition: sbagrid.cxx:821
virtual void ActivateCell(sal_Int32 nRow, sal_uInt16 nCol, bool bSetCellFocus=true) override
Definition: sbagrid.cxx:814
bool IsReadOnlyDB() const
Definition: sbagrid.cxx:864
virtual void MouseButtonDown(const BrowserMouseEvent &rMEvt) override
Definition: sbagrid.cxx:899
virtual ~SbaGridControl() override
Definition: sbagrid.cxx:616
virtual void Select() override
Definition: sbagrid.cxx:805
SbaGridControl(css::uno::Reference< css::uno::XComponentContext > const &_rM, Window *pParent, FmXGridPeer *_pPeer, WinBits nBits)
Definition: sbagrid.cxx:607
virtual void PostExecuteRowContextMenu(const OUString &rExecutionResult) override
Definition: sbagrid.cxx:793
css::uno::Reference< css::beans::XPropertySet > getField(sal_uInt16 nModelPos)
Definition: sbagrid.cxx:840
void DoFieldDrag(sal_uInt16 nColumnPos, sal_Int16 nRowPos)
Definition: sbagrid.cxx:1084
virtual void dispose() override
Definition: sbagrid.cxx:621
ImplSVEvent * m_nAsyncDropEvent
Definition: sbagrid.hxx:204
virtual VclPtr< BrowserHeader > imp_CreateHeaderBar(BrowseBox *pParent) override
Definition: sbagrid.cxx:629
svx::ODataAccessDescriptor m_aDataDescriptor
Definition: sbagrid.hxx:201
virtual void onRowChange() override
Definition: sbagrid.cxx:828
void implTransferSelectedRows(sal_Int16 nRowPos, bool _bTrueIfClipboardFalseIfDrag)
Definition: sbagrid.cxx:1049
SbaGridHeader(BrowseBox *pParent)
Definition: sbagrid.cxx:477
virtual void StartDrag(sal_Int8 _nAction, const Point &_rPosPixel) override
Definition: sbagrid.cxx:494
void ImplStartColumnDrag(sal_Int8 _nAction, const Point &_rMousePos)
Definition: sbagrid.cxx:515
virtual void PreExecuteColumnContextMenu(sal_uInt16 nColId, weld::Menu &rMenu, weld::Menu &rInsertMenu, weld::Menu &rChangeMenu, weld::Menu &rShowMenu) override
Definition: sbagrid.cxx:545
virtual void dispose() override
Definition: sbagrid.cxx:488
virtual void PostExecuteColumnContextMenu(sal_uInt16 nColId, const weld::Menu &rMenu, const OUString &rExecutionResult) override
Definition: sbagrid.cxx:596
virtual void MouseButtonDown(const MouseEvent &rMEvt) override
Definition: sbagrid.cxx:502
virtual ~SbaGridHeader() override
Definition: sbagrid.cxx:483
virtual void CellActivated()=0
virtual void SelectionChanged()=0
virtual void RowChanged()=0
virtual void CellDeactivated()=0
virtual void ColumnChanged()=0
virtual void SAL_CALL createPeer(const css::uno::Reference< css::awt::XToolkit > &rToolkit, const css::uno::Reference< css::awt::XWindowPeer > &rParentPeer) override
Definition: sbagrid.cxx:148
std::map< css::util::URL, rtl::Reference< SbaXStatusMultiplexer >, SbaURLCompare > StatusMultiplexerArray
Definition: sbagrid.hxx:57
StatusMultiplexerArray m_aStatusMultiplexer
Definition: sbagrid.hxx:58
virtual ~SbaXGridControl() override
Definition: sbagrid.cxx:102
virtual void SAL_CALL removeStatusListener(const css::uno::Reference< css::frame::XStatusListener > &xControl, const css::util::URL &aURL) override
Definition: sbagrid.cxx:199
virtual rtl::Reference< FmXGridPeer > imp_CreatePeer(vcl::Window *pParent) override
Definition: sbagrid.cxx:106
virtual css::uno::Any SAL_CALL queryAggregation(const css::uno::Type &_rType) override
Definition: sbagrid.cxx:130
virtual void SAL_CALL dispatch(const css::util::URL &aURL, const css::uno::Sequence< css::beans::PropertyValue > &aArgs) override
Definition: sbagrid.cxx:165
virtual void SAL_CALL dispose() override
Definition: sbagrid.cxx:217
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
Definition: sbagrid.cxx:136
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override
Definition: sbagrid.cxx:143
virtual void SAL_CALL addStatusListener(const css::uno::Reference< css::frame::XStatusListener > &xControl, const css::util::URL &aURL) override
Definition: sbagrid.cxx:172
virtual void SAL_CALL addStatusListener(const css::uno::Reference< css::frame::XStatusListener > &xControl, const css::util::URL &aURL) override
Definition: sbagrid.cxx:441
MapDispatchToBool m_aDispatchStates
Definition: sbagrid.hxx:147
virtual css::uno::Reference< css::frame::XDispatch > SAL_CALL queryDispatch(const css::util::URL &aURL, const OUString &aTargetFrameName, sal_Int32 nSearchFlags) override
Definition: sbagrid.cxx:297
virtual VclPtr< FmGridControl > imp_CreateControl(vcl::Window *pParent, WinBits nStyle) override
Definition: sbagrid.cxx:470
SbaXGridPeer(const css::uno::Reference< css::uno::XComponentContext > &)
Definition: sbagrid.cxx:238
static DispatchType classifyDispatchURL(const css::util::URL &_rURL)
Definition: sbagrid.cxx:330
virtual void SAL_CALL dispatch(const css::util::URL &aURL, const css::uno::Sequence< css::beans::PropertyValue > &aArgs) override
Definition: sbagrid.cxx:344
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
Definition: sbagrid.cxx:463
virtual void SAL_CALL removeStatusListener(const css::uno::Reference< css::frame::XStatusListener > &xControl, const css::util::URL &aURL) override
Definition: sbagrid.cxx:455
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &_rType) override
Definition: sbagrid.cxx:289
virtual ~SbaXGridPeer() override
Definition: sbagrid.cxx:243
void NotifyStatusChanged(const css::util::URL &aUrl, const css::uno::Reference< css::frame::XStatusListener > &xControl)
Definition: sbagrid.cxx:257
virtual void SAL_CALL dispose() override
Definition: sbagrid.cxx:247
std::queue< DispatchArgs > m_aDispatchArgs
Definition: sbagrid.hxx:131
comphelper::OMultiTypeInterfaceContainerHelperVar4< css::util::URL, css::frame::XStatusListener, SbaURLCompare > m_aStatusListeners
Definition: sbagrid.hxx:97
const IEditImplementation * GetEditImplementation() const
virtual void SetText(const OUString &_rStr)=0
static SVT_DLLPUBLIC void StartStringDrag(const OUString &_rContent, vcl::Window *_pWindow, sal_Int8 _nDragSourceActions)
bool Contains(const Point &rPOINT) const
tools::Long AdjustRight(tools::Long nHorzMoveDelta)
tools::Long AdjustLeft(tools::Long nHorzMoveDelta)
T * get() const
bool is() const
virtual void MouseButtonDown(const MouseEvent &rMEvt)
virtual short run()
virtual void set_visible(const OUString &rIdent, bool bVisible)=0
virtual void insert(int pos, const OUString &rId, const OUString &rStr, const OUString *pIconName, VirtualDevice *pImageSurface, const css::uno::Reference< css::graphic::XGraphic > &rImage, TriState eCheckRadioFalse)=0
virtual void set_sensitive(const OUString &rIdent, bool bSensitive)=0
virtual void insert_separator(int pos, const OUString &rId)=0
#define DBA_RES(id)
#define TOOLS_WARN_EXCEPTION(area, stream)
#define DBG_UNHANDLED_EXCEPTION(...)
weld::Window * GetFrameWeld(const SfxFrame *pFrame)
::std::vector< DataFlavorEx > DataFlavorExVector
sal_Int16 nValue
TRISTATE_INDET
#define WB_STDHEADERBAR
#define HEADERBAR_ITEM_NOTFOUND
URL aURL
Definition: intercept.cxx:87
Sequence< PropertyValue > aArguments
Definition: intercept.cxx:88
sal_uInt16 nPos
@ Exception
css::uno::Sequence< T > concatSequences(const css::uno::Sequence< T > &rS1, const Ss &... rSn)
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
Type
const ColumnProperty * getField(guint n)
css::uno::Reference< css::uno::XInterface > getDataSource(const css::uno::Reference< css::uno::XInterface > &_rxDependentObject)
IMPL_LINK_NOARG(OApplicationController, OnClipboardChanged, TransferableDataHelper *, void)
void callColumnFormatDialog(const css::uno::Reference< css::beans::XPropertySet > &_xAffectedCol, const css::uno::Reference< css::beans::XPropertySet > &_xField, SvNumberFormatter *_pFormatter, weld::Widget *_pParent)
call the format dialog and set the selected format at the column
void throwGenericSQLException(const OUString &_rMsg, const css::uno::Reference< css::uno::XInterface > &_rxSource)
sal_Int16 nId
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_dbu_SbaXGridControl_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
Definition: sbagrid.cxx:77
constexpr OUStringLiteral PROPERTY_WIDTH(u"Width")
constexpr OUStringLiteral PROPERTY_CONTROLSOURCE(u"DataField")
constexpr OUStringLiteral PROPERTY_ISREADONLY(u"IsReadOnly")
constexpr OUStringLiteral PROPERTY_BORDER(u"Border")
constexpr OUStringLiteral PROPERTY_TYPE(u"Type")
constexpr OUStringLiteral PROPERTY_BOUNDFIELD(u"BoundField")
constexpr OUStringLiteral PROPERTY_ISROWCOUNTFINAL(u"IsRowCountFinal")
constexpr OUStringLiteral PROPERTY_ROW_HEIGHT(u"RowHeight")
css::uno::Sequence< css::beans::PropertyValue > aArgs
Definition: sbagrid.hxx:129
#define DND_ACTION_COPY
#define DND_ACTION_LINK
#define DND_ACTION_NONE
signed char sal_Int8
RET_OK
sal_Int64 WinBits
WinBits const WB_DRAG
WinBits const WB_BORDER
WinBits const WB_TABSTOP