bump product version to 6.3.0.0.beta1
[LibreOffice.git] / reportdesign / source / ui / dlg / AddField.cxx
blobec3297328428786b1c1dcf64b6869afa57a13c36
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
19 #include <AddField.hxx>
20 #include <UITools.hxx>
21 #include <svx/dbaexchange.hxx>
22 #include <svx/svdpagv.hxx>
23 #include <com/sun/star/sdb/CommandType.hpp>
24 #include <com/sun/star/util/URL.hpp>
25 #include <com/sun/star/sdb/XDocumentDataSource.hpp>
26 #include <com/sun/star/i18n/XCollator.hpp>
27 #include <com/sun/star/beans/XPropertyChangeListener.hpp>
29 #include <vcl/event.hxx>
30 #include <vcl/waitobj.hxx>
31 #include <vcl/svapp.hxx>
32 #include <vcl/settings.hxx>
34 #include <tools/diagnose_ex.h>
35 #include <rptui_slotid.hrc>
37 #include <connectivity/dbtools.hxx>
38 #include <core_resource.hxx>
39 #include <helpids.h>
40 #include <strings.hrc>
41 #include <strings.hxx>
42 #include <ColumnInfo.hxx>
44 #include <comphelper/processfactory.hxx>
45 #include <comphelper/property.hxx>
46 #include <svtools/imgdef.hxx>
47 #include <vcl/treelistentry.hxx>
49 namespace rptui
51 const long STD_WIN_SIZE_X = 180;
52 const long STD_WIN_SIZE_Y = 320;
54 using namespace ::com::sun::star;
55 using namespace sdbc;
56 using namespace sdb;
57 using namespace uno;
58 using namespace datatransfer;
59 using namespace beans;
60 using namespace lang;
61 using namespace container;
62 using namespace ::svx;
64 class OAddFieldWindowListBox: public SvTreeListBox
66 VclPtr<OAddFieldWindow> m_pTabWin;
68 public:
69 explicit OAddFieldWindowListBox(Window* pParent, OAddFieldWindow* pFieldWindow);
70 virtual ~OAddFieldWindowListBox() override;
71 virtual void dispose() override;
73 sal_Int8 AcceptDrop( const AcceptDropEvent& rEvt ) override;
74 sal_Int8 ExecuteDrop( const ExecuteDropEvent& rEvt ) override;
76 uno::Sequence< beans::PropertyValue > getSelectedFieldDescriptors();
78 protected:
79 // DragSourceHelper
80 virtual void StartDrag( sal_Int8 nAction, const Point& rPosPixel ) override;
82 private:
83 using SvTreeListBox::ExecuteDrop;
86 uno::Sequence< beans::PropertyValue > OAddFieldWindowListBox::getSelectedFieldDescriptors()
88 uno::Sequence< beans::PropertyValue > aArgs(GetSelectionCount());
89 sal_Int32 i = 0;
90 SvTreeListEntry* pSelected = FirstSelected();
91 while( pSelected )
93 // build a descriptor for the currently selected field
94 svx::ODataAccessDescriptor aDescriptor;
95 m_pTabWin->fillDescriptor(pSelected,aDescriptor);
96 aArgs[i++].Value <<= aDescriptor.createPropertyValueSequence();
97 pSelected = NextSelected(pSelected);
99 return aArgs;
102 // class OAddFieldWindowListBox
105 OAddFieldWindowListBox::OAddFieldWindowListBox(Window *pParent, OAddFieldWindow* pFieldWindow)
106 : SvTreeListBox(pParent, WB_TABSTOP|WB_BORDER|WB_SORT)
107 , m_pTabWin(pFieldWindow)
109 SetHelpId( HID_RPT_FIELD_SEL );
110 SetSelectionMode(SelectionMode::Multiple);
111 SetDragDropMode( DragDropMode::ALL );
112 SetHighlightRange( );
116 OAddFieldWindowListBox::~OAddFieldWindowListBox()
118 disposeOnce();
121 void OAddFieldWindowListBox::dispose()
123 m_pTabWin.clear();
124 SvTreeListBox::dispose();
127 sal_Int8 OAddFieldWindowListBox::AcceptDrop( const AcceptDropEvent& /*rEvt*/ )
129 return DND_ACTION_NONE;
133 sal_Int8 OAddFieldWindowListBox::ExecuteDrop( const ExecuteDropEvent& /*rEvt*/ )
135 return DND_ACTION_NONE;
139 void OAddFieldWindowListBox::StartDrag( sal_Int8 /*_nAction*/, const Point& /*_rPosPixel*/ )
141 if ( GetSelectionCount() < 1 )
142 // no drag without a field
143 return;
145 rtl::Reference<OMultiColumnTransferable> pDataContainer = new OMultiColumnTransferable(getSelectedFieldDescriptors());
147 EndSelection();
148 pDataContainer->StartDrag( this, DND_ACTION_COPYMOVE | DND_ACTION_LINK );
151 OAddFieldWindow::OAddFieldWindow(vcl::Window* pParent ,const uno::Reference< beans::XPropertySet >& _xRowSet)
152 : FloatingWindow(pParent, "FloatingField", "modules/dbreport/ui/floatingfield.ui")
153 , ::comphelper::OPropertyChangeListener(m_aMutex)
154 , ::comphelper::OContainerListener(m_aMutex)
155 , m_xRowSet(_xRowSet)
156 , m_pListBox(VclPtr<OAddFieldWindowListBox>::Create(get<vcl::Window>("box"), this))
157 , m_nCommandType(0)
158 , m_bEscapeProcessing(false)
160 get(m_aActions, "toolbox");
161 m_nSortUpId = m_aActions->GetItemId(0);
162 m_nSortDownId = m_aActions->GetItemId(1);
163 m_nRemoveSortId = m_aActions->GetItemId(2);
164 m_nInsertId = m_aActions->GetItemId(4);
165 get(m_aHelpText, "helptext");
167 SetHelpId( HID_RPT_FIELD_SEL_WIN );
168 SetBackground( Wallpaper( Application::GetSettings().GetStyleSettings().GetFaceColor()) );
169 SetMinOutputSizePixel(Size(STD_WIN_SIZE_X,STD_WIN_SIZE_Y));
171 m_aActions->SetLineSpacing(true);
172 m_aActions->SetBackground( Wallpaper( Application::GetSettings().GetStyleSettings().GetFaceColor()) );
174 m_aActions->SetSelectHdl(LINK(this, OAddFieldWindow, OnSortAction));
175 setToolBox(m_aActions.get());
176 m_aActions->CheckItem(m_nSortUpId);
177 m_aActions->EnableItem(m_nInsertId, false);
179 m_pListBox->SetDoubleClickHdl(LINK( this, OAddFieldWindow, OnDoubleClickHdl ) );
180 m_pListBox->SetSelectHdl(LINK( this, OAddFieldWindow, OnSelectHdl ) );
181 m_pListBox->SetDeselectHdl(LINK( this, OAddFieldWindow, OnSelectHdl ) );
182 m_pListBox->SetDoubleClickHdl(LINK( this, OAddFieldWindow, OnDoubleClickHdl ) );
183 m_pListBox->set_expand(true);
184 m_pListBox->set_height_request(m_pListBox->GetTextHeight() * 8);
185 m_pListBox->set_width_request(m_pListBox->approximate_char_width() * 40);
186 m_pListBox->Show();
188 m_aHelpText->SetControlBackground( GetSettings().GetStyleSettings().GetFaceColor() );
190 SetSizePixel(Size(STD_WIN_SIZE_X,STD_WIN_SIZE_Y));
192 if ( m_xRowSet.is() )
196 // be notified when the settings of report definition change
197 m_pChangeListener = new ::comphelper::OPropertyChangeMultiplexer( this, m_xRowSet );
198 m_pChangeListener->addProperty( PROPERTY_COMMAND );
199 m_pChangeListener->addProperty( PROPERTY_COMMANDTYPE );
200 m_pChangeListener->addProperty( PROPERTY_ESCAPEPROCESSING );
201 m_pChangeListener->addProperty( PROPERTY_FILTER );
203 catch( const Exception& )
205 DBG_UNHANDLED_EXCEPTION("reportdesign");
210 OAddFieldWindow::~OAddFieldWindow()
212 disposeOnce();
215 void OAddFieldWindow::dispose()
217 if ( m_pListBox.get() )
219 SvTreeList* pModel = m_pListBox->GetModel();
220 sal_uLong nCount = pModel->GetEntryCount();
221 for(sal_uLong i = 0; i< nCount;++i)
223 delete static_cast<ColumnInfo*>(pModel->GetEntry(i)->GetUserData());
226 if (m_pChangeListener.is())
227 m_pChangeListener->dispose();
228 if ( m_pContainerListener.is() )
229 m_pContainerListener->dispose();
231 m_aActions.clear();
232 m_aHelpText.clear();
233 m_pListBox.disposeAndClear();
234 FloatingWindow::dispose();
237 void OAddFieldWindow::GetFocus()
239 if ( m_pListBox.get() )
240 m_pListBox->GrabFocus();
241 else
242 FloatingWindow::GetFocus();
245 uno::Sequence< beans::PropertyValue > OAddFieldWindow::getSelectedFieldDescriptors()
247 return m_pListBox->getSelectedFieldDescriptors();
251 bool OAddFieldWindow::PreNotify( NotifyEvent& _rNEvt )
253 if ( MouseNotifyEvent::KEYINPUT == _rNEvt.GetType() )
255 const vcl::KeyCode& rKeyCode = _rNEvt.GetKeyEvent()->GetKeyCode();
256 if ( ( 0 == rKeyCode.GetModifier() ) && ( KEY_RETURN == rKeyCode.GetCode() ) )
258 if ( m_aCreateLink.IsSet() )
260 m_aCreateLink.Call(*this);
261 return true;
266 return FloatingWindow::PreNotify( _rNEvt );
269 void OAddFieldWindow::_propertyChanged( const beans::PropertyChangeEvent& _evt )
271 OSL_ENSURE( _evt.Source == m_xRowSet, "OAddFieldWindow::_propertyChanged: where did this come from?" );
272 Update();
276 namespace
278 void lcl_addToList( OAddFieldWindowListBox& _rListBox, const uno::Sequence< OUString >& _rEntries )
280 const OUString* pEntries = _rEntries.getConstArray();
281 sal_Int32 nEntries = _rEntries.getLength();
282 for ( sal_Int32 i = 0; i < nEntries; ++i, ++pEntries )
283 _rListBox.InsertEntry( *pEntries,nullptr,false,TREELIST_APPEND,new ColumnInfo(*pEntries) );
285 void lcl_addToList( OAddFieldWindowListBox& _rListBox, const uno::Reference< container::XNameAccess>& i_xColumns )
287 uno::Sequence< OUString > aEntries = i_xColumns->getElementNames();
288 const OUString* pEntries = aEntries.getConstArray();
289 sal_Int32 nEntries = aEntries.getLength();
290 for ( sal_Int32 i = 0; i < nEntries; ++i, ++pEntries )
292 uno::Reference< beans::XPropertySet> xColumn(i_xColumns->getByName(*pEntries),UNO_QUERY_THROW);
293 OUString sLabel;
294 if ( xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_LABEL) )
295 xColumn->getPropertyValue(PROPERTY_LABEL) >>= sLabel;
296 if ( !sLabel.isEmpty() )
297 _rListBox.InsertEntry( sLabel,nullptr,false,TREELIST_APPEND,new ColumnInfo(*pEntries,sLabel) );
298 else
299 _rListBox.InsertEntry( *pEntries,nullptr,false,TREELIST_APPEND,new ColumnInfo(*pEntries,sLabel) );
305 void OAddFieldWindow::Update()
307 SolarMutexGuard aSolarGuard;
309 if ( m_pContainerListener.is() )
310 m_pContainerListener->dispose();
311 m_pContainerListener = nullptr;
312 m_xColumns.clear();
316 // ListBox loeschen
317 m_pListBox->Clear();
318 const ToolBox::ImplToolItems::size_type nItemCount = m_aActions->GetItemCount();
319 for (ToolBox::ImplToolItems::size_type j = 0; j< nItemCount; ++j)
321 m_aActions->EnableItem(m_aActions->GetItemId(j),false);
324 OUString aTitle(RptResId(RID_STR_FIELDSELECTION));
325 SetText(aTitle);
326 if ( m_xRowSet.is() )
328 OUString sCommand( m_aCommandName );
329 sal_Int32 nCommandType( m_nCommandType );
330 bool bEscapeProcessing( m_bEscapeProcessing );
331 OUString sFilter( m_sFilter );
333 OSL_VERIFY( m_xRowSet->getPropertyValue( PROPERTY_COMMAND ) >>= sCommand );
334 OSL_VERIFY( m_xRowSet->getPropertyValue( PROPERTY_COMMANDTYPE ) >>= nCommandType );
335 OSL_VERIFY( m_xRowSet->getPropertyValue( PROPERTY_ESCAPEPROCESSING ) >>= bEscapeProcessing );
336 OSL_VERIFY( m_xRowSet->getPropertyValue( PROPERTY_FILTER ) >>= sFilter );
338 m_aCommandName = sCommand;
339 m_nCommandType = nCommandType;
340 m_bEscapeProcessing = bEscapeProcessing;
341 m_sFilter = sFilter;
343 // add the columns to the list
344 uno::Reference< sdbc::XConnection> xCon = getConnection();
345 if ( xCon.is() && !m_aCommandName.isEmpty() )
346 m_xColumns = dbtools::getFieldsByCommandDescriptor( xCon, GetCommandType(), GetCommand(), m_xHoldAlive );
347 if ( m_xColumns.is() )
349 lcl_addToList( *m_pListBox, m_xColumns );
350 uno::Reference< container::XContainer> xContainer(m_xColumns,uno::UNO_QUERY);
351 if ( xContainer.is() )
352 m_pContainerListener = new ::comphelper::OContainerListenerAdapter(this,xContainer);
355 // add the parameter columns to the list
356 uno::Reference< css::sdbc::XRowSet > xRowSet(m_xRowSet,uno::UNO_QUERY);
357 Sequence< OUString > aParamNames( getParameterNames( xRowSet ) );
358 lcl_addToList( *m_pListBox, aParamNames );
360 // set title
361 aTitle += " " + m_aCommandName;
362 SetText( aTitle );
363 if ( !m_aCommandName.isEmpty() )
365 for (ToolBox::ImplToolItems::size_type i = 0; i < nItemCount; ++i)
367 m_aActions->EnableItem(m_aActions->GetItemId(i));
370 OnSelectHdl(nullptr);
373 catch( const Exception& )
375 DBG_UNHANDLED_EXCEPTION("reportdesign");
379 uno::Reference< sdbc::XConnection> OAddFieldWindow::getConnection() const
381 return uno::Reference< sdbc::XConnection>(m_xRowSet->getPropertyValue( PROPERTY_ACTIVECONNECTION ),uno::UNO_QUERY);
384 void OAddFieldWindow::fillDescriptor(SvTreeListEntry const * _pSelected,svx::ODataAccessDescriptor& _rDescriptor)
386 if ( _pSelected && m_xColumns.is() )
388 uno::Reference<container::XChild> xChild(getConnection(),uno::UNO_QUERY);
389 if ( xChild.is( ) )
391 uno::Reference<sdb::XDocumentDataSource> xDocument( xChild->getParent(), uno::UNO_QUERY );
392 if ( xDocument.is() )
394 uno::Reference<frame::XModel> xModel(xDocument->getDatabaseDocument(),uno::UNO_QUERY);
395 if ( xModel.is() )
396 _rDescriptor[ DataAccessDescriptorProperty::DatabaseLocation ] <<= xModel->getURL();
400 _rDescriptor[ svx::DataAccessDescriptorProperty::Command ] <<= GetCommand();
401 _rDescriptor[ svx::DataAccessDescriptorProperty::CommandType ] <<= GetCommandType();
402 _rDescriptor[ svx::DataAccessDescriptorProperty::EscapeProcessing ] <<= GetEscapeProcessing();
403 _rDescriptor[ svx::DataAccessDescriptorProperty::Connection ] <<= getConnection();
405 ColumnInfo* pInfo = static_cast<ColumnInfo*>(_pSelected->GetUserData());
406 _rDescriptor[ svx::DataAccessDescriptorProperty::ColumnName ] <<= pInfo->sColumnName;
407 if ( m_xColumns->hasByName( pInfo->sColumnName ) )
408 _rDescriptor[ svx::DataAccessDescriptorProperty::ColumnObject ] = m_xColumns->getByName(pInfo->sColumnName);
412 void OAddFieldWindow::_elementInserted( const container::ContainerEvent& _rEvent )
414 if ( m_pListBox.get() )
416 OUString sName;
417 if ( (_rEvent.Accessor >>= sName) && m_xColumns->hasByName(sName) )
419 uno::Reference< beans::XPropertySet> xColumn(m_xColumns->getByName(sName),UNO_QUERY_THROW);
420 OUString sLabel;
421 if ( xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_LABEL) )
422 xColumn->getPropertyValue(PROPERTY_LABEL) >>= sLabel;
423 if ( !sLabel.isEmpty() )
424 m_pListBox->InsertEntry( sLabel,nullptr,false,TREELIST_APPEND,new ColumnInfo(sName,sLabel) );
425 else
426 m_pListBox->InsertEntry( sName,nullptr,false,TREELIST_APPEND,new ColumnInfo(sName,sLabel) );
431 void OAddFieldWindow::_elementRemoved( const container::ContainerEvent& /*_rEvent*/ )
433 if ( m_pListBox.get() )
435 m_pListBox->Clear();
436 if ( m_xColumns.is() )
437 lcl_addToList( *m_pListBox, m_xColumns );
441 void OAddFieldWindow::_elementReplaced( const container::ContainerEvent& /*_rEvent*/ )
445 IMPL_LINK_NOARG( OAddFieldWindow, OnSelectHdl, SvTreeListBox*, void )
447 m_aActions->EnableItem(m_nInsertId, ( m_pListBox.get() && m_pListBox->GetSelectionCount() > 0 ));
450 IMPL_LINK_NOARG( OAddFieldWindow, OnDoubleClickHdl, SvTreeListBox*, bool )
452 m_aCreateLink.Call(*this);
454 return false;
457 void OAddFieldWindow::resizeControls(const Size& _rDiff)
459 // we use large images so we must change them
460 if ( _rDiff.Width() || _rDiff.Height() )
462 Invalidate();
466 IMPL_LINK_NOARG( OAddFieldWindow, OnSortAction, ToolBox*, void )
468 const sal_uInt16 nCurItem = m_aActions->GetCurItemId();
469 if (nCurItem == m_nInsertId)
470 OnDoubleClickHdl(nullptr);
471 else
473 if (nCurItem == m_nRemoveSortId || !m_aActions->IsItemChecked(nCurItem))
475 const ToolBox::ImplToolItems::size_type nItemCount = m_aActions->GetItemCount();
476 for (ToolBox::ImplToolItems::size_type j = 0; j< nItemCount; ++j)
478 const sal_uInt16 nItemId = m_aActions->GetItemId(j);
479 if ( nCurItem != nItemId )
480 m_aActions->CheckItem(nItemId,false);
482 SvSortMode eSortMode = SortNone;
483 if (nCurItem != m_nRemoveSortId)
485 m_aActions->CheckItem(nCurItem,!m_aActions->IsItemChecked(nCurItem));
486 if (m_aActions->IsItemChecked(m_nSortUpId))
487 eSortMode = SortAscending;
488 else if (m_aActions->IsItemChecked(m_nSortDownId))
489 eSortMode = SortDescending;
492 m_pListBox->GetModel()->SetSortMode(eSortMode);
493 if (nCurItem == m_nRemoveSortId)
494 Update();
496 m_pListBox->GetModel()->Resort();
502 } // namespace rptui
505 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */