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 #include <GroupsSorting.hxx>
20 #include <connectivity/dbtools.hxx>
21 #include <sot/exchange.hxx>
22 #include <svtools/editbrowsebox.hxx>
23 #include <svtools/imgdef.hxx>
24 #include <com/sun/star/beans/XPropertySet.hpp>
25 #include <com/sun/star/container/XContainerListener.hpp>
26 #include <com/sun/star/report/GroupOn.hpp>
27 #include <com/sun/star/sdbc/DataType.hpp>
28
29 #include <strings.hrc>
30 #include <rptui_slotid.hrc>
31 #include <core_resource.hxx>
32 #include <helpids.h>
33 #include "GroupExchange.hxx"
34 #include <UITools.hxx>
35 #include <UndoActions.hxx>
36 #include <strings.hxx>
37 #include <ReportController.hxx>
38 #include <ColumnInfo.hxx>
39
40 #include <cppuhelper/implbase.hxx>
41 #include <comphelper/property.hxx>
42 #include <vcl/settings.hxx>
43
44 #include <algorithm>
45
46 #include <cppuhelper/bootstrap.hxx>
47
48 #define HANDLE_ID 0
49 #define FIELD_EXPRESSION 1
50 #define GROUPS_START_LEN 5
51 #define NO_GROUP -1
52
53 namespace rptui
54 {
55 using namespace ::com::sun::star;
56 using namespace svt;
57 using namespace ::comphelper;
58
lcl_addToList_throw(ComboBoxControl & _rListBox,::std::vector<ColumnInfo> & o_aColumnList,const uno::Reference<container::XNameAccess> & i_xColumns)59 static void lcl_addToList_throw( ComboBoxControl& _rListBox, ::std::vector<ColumnInfo>& o_aColumnList,const uno::Reference< container::XNameAccess>& i_xColumns )
60 {
61 const uno::Sequence< OUString > aEntries = i_xColumns->getElementNames();
62 for ( const OUString& rEntry : aEntries )
63 {
64 uno::Reference< beans::XPropertySet> xColumn(i_xColumns->getByName(rEntry),uno::UNO_QUERY_THROW);
65 OUString sLabel;
66 if ( xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_LABEL) )
67 xColumn->getPropertyValue(PROPERTY_LABEL) >>= sLabel;
68 o_aColumnList.emplace_back(rEntry,sLabel );
69 if ( !sLabel.isEmpty() )
70 _rListBox.InsertEntry( sLabel );
71 else
72 _rListBox.InsertEntry( rEntry );
73 }
74 }
75
76 /**
77 * Separated out from OFieldExpressionControl to prevent collision of ref-counted base classes
78 */
79 class OFieldExpressionControl;
80 class OFieldExpressionControlContainerListener : public ::cppu::WeakImplHelper< container::XContainerListener >
81 {
82 VclPtr<OFieldExpressionControl> mpParent;
83 public:
OFieldExpressionControlContainerListener(OFieldExpressionControl * pParent)84 explicit OFieldExpressionControlContainerListener(OFieldExpressionControl* pParent) : mpParent(pParent) {}
85
86 // XEventListener
87 virtual void SAL_CALL disposing(const css::lang::EventObject& Source) override;
88 // XContainerListener
89 virtual void SAL_CALL elementInserted(const css::container::ContainerEvent& rEvent) override;
90 virtual void SAL_CALL elementReplaced(const css::container::ContainerEvent& rEvent) override;
91 virtual void SAL_CALL elementRemoved(const css::container::ContainerEvent& rEvent) override;
92 };
93
94 class OFieldExpressionControl : public ::svt::EditBrowseBox
95 {
96 ::osl::Mutex m_aMutex;
97 ::std::vector<sal_Int32> m_aGroupPositions;
98 ::std::vector<ColumnInfo> m_aColumnInfo;
99 VclPtr< ::svt::ComboBoxControl> m_pComboCell;
100 sal_Int32 m_nDataPos;
101 sal_Int32 m_nCurrentPos;
102 ImplSVEvent * m_nDeleteEvent;
103 VclPtr<OGroupsSortingDialog> m_pParent;
104 bool m_bIgnoreEvent;
105 rtl::Reference<OFieldExpressionControlContainerListener> aContainerListener;
106
107 public:
108 OFieldExpressionControl(OGroupsSortingDialog* _pParentDialog, vcl::Window *_pParent);
109 virtual ~OFieldExpressionControl() override;
110 virtual void dispose() override;
111
112 // XContainerListener
113 /// @throws css::uno::RuntimeException
114 void elementInserted(const css::container::ContainerEvent& rEvent);
115 /// @throws css::uno::RuntimeException
116 void elementRemoved(const css::container::ContainerEvent& rEvent);
117
118 virtual Size GetOptimalSize() const override;
119
120 void fillColumns(const uno::Reference< container::XNameAccess>& _xColumns);
121 void lateInit();
122 bool IsDeleteAllowed( ) const;
123 void DeleteRows();
124
getGroupPosition(sal_Int32 _nRow) const125 sal_Int32 getGroupPosition(sal_Int32 _nRow) const { return _nRow != BROWSER_ENDOFSELECTION ? m_aGroupPositions[_nRow] : sal_Int32(NO_GROUP); }
126
getExpressionControl() const127 ::svt::ComboBoxControl* getExpressionControl() const { return m_pComboCell; }
128
129 /** returns the sequence with the selected groups
130 */
131 uno::Sequence<uno::Any> fillSelectedGroups();
132
133 /** move groups given by _aGroups
134 */
135 void moveGroups(const uno::Sequence<uno::Any>& _aGroups,sal_Int32 _nRow,bool _bSelect = true);
136
137 virtual bool CursorMoving(long nNewRow, sal_uInt16 nNewCol) override;
138 using ::svt::EditBrowseBox::GetRowCount;
139 protected:
140 virtual bool IsTabAllowed(bool bForward) const override;
141
142 virtual void InitController( ::svt::CellControllerRef& rController, long nRow, sal_uInt16 nCol ) override;
143 virtual ::svt::CellController* GetController( long nRow, sal_uInt16 nCol ) override;
144 virtual void PaintCell( OutputDevice& rDev, const tools::Rectangle& rRect, sal_uInt16 nColId ) const override;
145 virtual bool SeekRow( long nRow ) override;
146 virtual bool SaveModified() override;
147 virtual OUString GetCellText( long nRow, sal_uInt16 nColId ) const override;
148 virtual RowStatus GetRowStatus(long nRow) const override;
149
150 virtual void KeyInput(const KeyEvent& rEvt) override;
151 virtual void Command( const CommandEvent& rEvt ) override;
152
153 // D&D
154 virtual void StartDrag( sal_Int8 nAction, const Point& rPosPixel ) override;
155 virtual sal_Int8 AcceptDrop( const BrowserAcceptDropEvent& rEvt ) override;
156 virtual sal_Int8 ExecuteDrop( const BrowserExecuteDropEvent& rEvt ) override;
157
158 using BrowseBox::AcceptDrop;
159 using BrowseBox::ExecuteDrop;
160
161 private:
162
163 DECL_LINK( CBChangeHdl, ComboBox&, void);
164
165 public:
166 DECL_LINK( DelayedDelete, void*, void );
167
168 };
169
170
disposing(const css::lang::EventObject &)171 void OFieldExpressionControlContainerListener::disposing(const css::lang::EventObject& )
172 {}
173
elementInserted(const css::container::ContainerEvent & rEvent)174 void OFieldExpressionControlContainerListener::elementInserted(const css::container::ContainerEvent& rEvent)
175 { mpParent->elementInserted(rEvent); }
176
elementReplaced(const css::container::ContainerEvent &)177 void OFieldExpressionControlContainerListener::elementReplaced(const css::container::ContainerEvent& )
178 {}
179
elementRemoved(const css::container::ContainerEvent & rEvent)180 void OFieldExpressionControlContainerListener::elementRemoved(const css::container::ContainerEvent& rEvent)
181 { mpParent->elementRemoved(rEvent); }
182
183
184 // class OFieldExpressionControl
OFieldExpressionControl(OGroupsSortingDialog * _pParentDialog,vcl::Window * _pParent)185 OFieldExpressionControl::OFieldExpressionControl(OGroupsSortingDialog* _pParentDialog, vcl::Window *_pParent)
186 :EditBrowseBox( _pParent, EditBrowseBoxFlags::NONE, WB_TABSTOP,
187 BrowserMode::COLUMNSELECTION | BrowserMode::MULTISELECTION | BrowserMode::AUTOSIZE_LASTCOL |
188 BrowserMode::KEEPHIGHLIGHT | BrowserMode::HLINES | BrowserMode::VLINES)
189 ,m_aGroupPositions(GROUPS_START_LEN,-1)
190 ,m_pComboCell(nullptr)
191 ,m_nDataPos(-1)
192 ,m_nCurrentPos(-1)
193 ,m_nDeleteEvent(nullptr)
194 ,m_pParent(_pParentDialog)
195 ,m_bIgnoreEvent(false)
196 ,aContainerListener(new OFieldExpressionControlContainerListener(this))
197 {
198 SetBorderStyle(WindowBorderStyle::MONO);
199 }
200
201
~OFieldExpressionControl()202 OFieldExpressionControl::~OFieldExpressionControl()
203 {
204 disposeOnce();
205 }
206
207
dispose()208 void OFieldExpressionControl::dispose()
209 {
210 uno::Reference< report::XGroups > xGroups = m_pParent->getGroups();
211 xGroups->removeContainerListener(aContainerListener.get());
212
213 // delete events from queue
214 if( m_nDeleteEvent )
215 Application::RemoveUserEvent( m_nDeleteEvent );
216
217 m_pComboCell.disposeAndClear();
218 m_pParent.clear();
219 ::svt::EditBrowseBox::dispose();
220 }
221
fillSelectedGroups()222 uno::Sequence<uno::Any> OFieldExpressionControl::fillSelectedGroups()
223 {
224 uno::Sequence<uno::Any> aList;
225 ::std::vector<uno::Any> vClipboardList;
226 vClipboardList.reserve(GetSelectRowCount());
227
228 uno::Reference<report::XGroups> xGroups = m_pParent->getGroups();
229 sal_Int32 nCount = xGroups->getCount();
230 if ( nCount >= 1 )
231 {
232 for( long nIndex=FirstSelectedRow(); nIndex != SFX_ENDOFSELECTION; nIndex=NextSelectedRow() )
233 {
234 try
235 {
236 if ( m_aGroupPositions[nIndex] != NO_GROUP )
237 {
238 uno::Reference< report::XGroup> xOrgGroup(xGroups->getByIndex(m_aGroupPositions[nIndex]),uno::UNO_QUERY);
239 /*uno::Reference< report::XGroup> xCopy = xGroups->createGroup();
240 ::comphelper::copyProperties(xOrgGroup.get(),xCopy.get());*/
241 vClipboardList.push_back( uno::makeAny(xOrgGroup) );
242 }
243 }
244 catch(uno::Exception&)
245 {
246 OSL_FAIL("Can not access group!");
247 }
248 }
249 if ( !vClipboardList.empty() )
250 aList = uno::Sequence< uno::Any >(vClipboardList.data(), vClipboardList.size());
251 }
252 return aList;
253 }
254
StartDrag(sal_Int8,const Point &)255 void OFieldExpressionControl::StartDrag( sal_Int8 /*_nAction*/ , const Point& /*_rPosPixel*/ )
256 {
257 if ( m_pParent && !m_pParent->isReadOnly( ) )
258 {
259 uno::Sequence<uno::Any> aClipboardList = fillSelectedGroups();
260
261 if( aClipboardList.hasElements() )
262 {
263 rtl::Reference<OGroupExchange> pData = new OGroupExchange(aClipboardList);
264 pData->StartDrag(this, DND_ACTION_MOVE );
265 }
266 }
267 }
268
AcceptDrop(const BrowserAcceptDropEvent & rEvt)269 sal_Int8 OFieldExpressionControl::AcceptDrop( const BrowserAcceptDropEvent& rEvt )
270 {
271 sal_Int8 nAction = DND_ACTION_NONE;
272 if ( IsEditing() )
273 {
274 sal_Int32 nPos = m_pComboCell->GetSelectedEntryPos();
275 if ( COMBOBOX_ENTRY_NOTFOUND != nPos || !m_pComboCell->GetText().isEmpty() )
276 SaveModified();
277 DeactivateCell();
278 }
279 if ( IsDropFormatSupported( OGroupExchange::getReportGroupId() ) && m_pParent->getGroups()->getCount() > 1 && rEvt.GetWindow() == &GetDataWindow() )
280 {
281 nAction = DND_ACTION_MOVE;
282 }
283 return nAction;
284 }
285
ExecuteDrop(const BrowserExecuteDropEvent & rEvt)286 sal_Int8 OFieldExpressionControl::ExecuteDrop( const BrowserExecuteDropEvent& rEvt )
287 {
288 sal_Int8 nAction = DND_ACTION_NONE;
289 if ( IsDropFormatSupported( OGroupExchange::getReportGroupId() ) )
290 {
291 sal_Int32 nRow = GetRowAtYPosPixel(rEvt.maPosPixel.Y(), false);
292 SetNoSelection();
293
294 TransferableDataHelper aDropped( rEvt.maDropEvent.Transferable );
295 uno::Any aDrop = aDropped.GetAny(OGroupExchange::getReportGroupId(), OUString());
296 uno::Sequence< uno::Any > aGroups;
297 aDrop >>= aGroups;
298 if ( aGroups.hasElements() )
299 {
300 moveGroups(aGroups,nRow);
301 nAction = DND_ACTION_MOVE;
302 }
303 }
304 return nAction;
305 }
306
moveGroups(const uno::Sequence<uno::Any> & _aGroups,sal_Int32 _nRow,bool _bSelect)307 void OFieldExpressionControl::moveGroups(const uno::Sequence<uno::Any>& _aGroups,sal_Int32 _nRow,bool _bSelect)
308 {
309 if ( _aGroups.hasElements() )
310 {
311 m_bIgnoreEvent = true;
312 {
313 sal_Int32 nRow = _nRow;
314 const OUString sUndoAction(RptResId(RID_STR_UNDO_MOVE_GROUP));
315 const UndoContext aUndoContext( m_pParent->m_pController->getUndoManager(), sUndoAction );
316
317 uno::Reference< report::XGroups> xGroups = m_pParent->getGroups();
318 for(const uno::Any& rGroup : _aGroups)
319 {
320 uno::Reference< report::XGroup> xGroup(rGroup,uno::UNO_QUERY);
321 if ( xGroup.is() )
322 {
323 uno::Sequence< beans::PropertyValue > aArgs(1);
324 aArgs[0].Name = PROPERTY_GROUP;
325 aArgs[0].Value <<= xGroup;
326 // we use this way to create undo actions
327 m_pParent->m_pController->executeChecked(SID_GROUP_REMOVE,aArgs);
328 aArgs.realloc(2);
329 if ( nRow > xGroups->getCount() )
330 nRow = xGroups->getCount();
331 if ( _bSelect )
332 SelectRow(nRow);
333 aArgs[1].Name = PROPERTY_POSITIONY;
334 aArgs[1].Value <<= nRow;
335 m_pParent->m_pController->executeChecked(SID_GROUP_APPEND,aArgs);
336 ++nRow;
337 }
338 }
339 }
340 m_bIgnoreEvent = false;
341 Invalidate();
342 }
343 }
344
fillColumns(const uno::Reference<container::XNameAccess> & _xColumns)345 void OFieldExpressionControl::fillColumns(const uno::Reference< container::XNameAccess>& _xColumns)
346 {
347 m_pComboCell->Clear();
348 if ( _xColumns.is() )
349 lcl_addToList_throw(*m_pComboCell,m_aColumnInfo,_xColumns);
350 }
351
lateInit()352 void OFieldExpressionControl::lateInit()
353 {
354 uno::Reference< report::XGroups > xGroups = m_pParent->getGroups();
355 sal_Int32 nGroupsCount = xGroups->getCount();
356 m_aGroupPositions.resize(::std::max<sal_Int32>(nGroupsCount,sal_Int32(GROUPS_START_LEN)),NO_GROUP);
357 ::std::vector<sal_Int32>::iterator aIter = m_aGroupPositions.begin();
358 for (sal_Int32 i = 0; i < nGroupsCount; ++i,++aIter)
359 *aIter = i;
360
361 if ( ColCount() == 0 )
362 {
363 vcl::Font aFont( GetDataWindow().GetFont() );
364 aFont.SetWeight( WEIGHT_NORMAL );
365 GetDataWindow().SetFont( aFont );
366
367 // Set font of the headline to light
368 aFont = GetFont();
369 aFont.SetWeight( WEIGHT_LIGHT );
370 SetFont(aFont);
371
372 InsertHandleColumn(static_cast<sal_uInt16>(GetTextWidth(OUString('0')) * 4)/*, sal_True */);
373 InsertDataColumn( FIELD_EXPRESSION, RptResId(STR_RPT_EXPRESSION), 100);
374
375 m_pComboCell = VclPtr<ComboBoxControl>::Create( &GetDataWindow() );
376 m_pComboCell->SetSelectHdl(LINK(this,OFieldExpressionControl,CBChangeHdl));
377 m_pComboCell->SetHelpId(HID_RPT_FIELDEXPRESSION);
378
379 m_pComboCell->SetGetFocusHdl(LINK(m_pParent, OGroupsSortingDialog, OnControlFocusGot));
380 m_pComboCell->SetLoseFocusHdl(LINK(m_pParent, OGroupsSortingDialog, OnControlFocusLost));
381
382
383 // set browse mode
384 BrowserMode nMode(BrowserMode::COLUMNSELECTION | BrowserMode::MULTISELECTION | BrowserMode::KEEPHIGHLIGHT |
385 BrowserMode::HLINES | BrowserMode::VLINES | BrowserMode::AUTOSIZE_LASTCOL | BrowserMode::AUTO_VSCROLL | BrowserMode::AUTO_HSCROLL);
386 if( m_pParent->isReadOnly() )
387 nMode |= BrowserMode::HIDECURSOR;
388 SetMode(nMode);
389 xGroups->addContainerListener(aContainerListener.get());
390 }
391 else
392 // not the first call
393 RowRemoved(0, GetRowCount());
394
395 RowInserted(0, m_aGroupPositions.size());
396 }
397
398
IMPL_LINK_NOARG(OFieldExpressionControl,CBChangeHdl,ComboBox &,void)399 IMPL_LINK_NOARG( OFieldExpressionControl, CBChangeHdl, ComboBox&, void )
400 {
401
402 SaveModified();
403 }
404
405
IsTabAllowed(bool) const406 bool OFieldExpressionControl::IsTabAllowed(bool /*bForward*/) const
407 {
408 return false;
409 }
410
411
SaveModified()412 bool OFieldExpressionControl::SaveModified()
413 {
414 sal_Int32 nRow = GetCurRow();
415 if ( nRow != BROWSER_ENDOFSELECTION )
416 {
417 try
418 {
419 bool bAppend = false;
420 uno::Reference< report::XGroup> xGroup;
421 if ( m_aGroupPositions[nRow] == NO_GROUP )
422 {
423 bAppend = true;
424 OUString sUndoAction(RptResId(RID_STR_UNDO_APPEND_GROUP));
425 m_pParent->m_pController->getUndoManager().EnterListAction( sUndoAction, OUString(), 0, ViewShellId(-1) );
426 xGroup = m_pParent->getGroups()->createGroup();
427 xGroup->setHeaderOn(true);
428
429 uno::Sequence< beans::PropertyValue > aArgs(2);
430 aArgs[0].Name = PROPERTY_GROUP;
431 aArgs[0].Value <<= xGroup;
432 // find position where to insert the new group
433 sal_Int32 nGroupPos = 0;
434 ::std::vector<sal_Int32>::iterator aIter = m_aGroupPositions.begin();
435 ::std::vector<sal_Int32>::const_iterator aEnd = m_aGroupPositions.begin() + nRow;
436 for(;aIter != aEnd;++aIter)
437 if ( *aIter != NO_GROUP )
438 nGroupPos = *aIter + 1;
439 aArgs[1].Name = PROPERTY_POSITIONY;
440 aArgs[1].Value <<= nGroupPos;
441 m_bIgnoreEvent = true;
442 m_pParent->m_pController->executeChecked(SID_GROUP_APPEND,aArgs);
443 m_bIgnoreEvent = false;
444 OSL_ENSURE(*aIter == NO_GROUP ,"Illegal iterator!");
445 *aIter++ = nGroupPos;
446
447 aEnd = m_aGroupPositions.end();
448 for(;aIter != aEnd;++aIter)
449 if ( *aIter != NO_GROUP )
450 ++*aIter;
451 }
452 else
453 xGroup = m_pParent->getGroup(m_aGroupPositions[nRow]);
454 if ( xGroup.is() )
455 {
456 sal_Int32 nPos = m_pComboCell->GetSelectedEntryPos();
457 OUString sExpression;
458 if ( COMBOBOX_ENTRY_NOTFOUND == nPos )
459 sExpression = m_pComboCell->GetText();
460 else
461 {
462 sExpression = m_aColumnInfo[nPos].sColumnName;
463 }
464 xGroup->setExpression( sExpression );
465
466 ::rptui::adjustSectionName(xGroup,nPos);
467
468 if ( bAppend )
469 m_pParent->m_pController->getUndoManager().LeaveListAction();
470 }
471
472 if ( Controller().is() )
473 Controller()->ClearModified();
474 if ( GetRowCount() == m_pParent->getGroups()->getCount() )
475 {
476 RowInserted( GetRowCount()-1);
477 m_aGroupPositions.push_back(NO_GROUP);
478 }
479
480 GoToRow(nRow);
481 m_pParent->DisplayData(nRow);
482 }
483 catch(uno::Exception&)
484 {
485 OSL_FAIL("OFieldExpressionControl::SaveModified: Exception caught!");
486 }
487 }
488
489 return true;
490 }
491
GetCellText(long nRow,sal_uInt16) const492 OUString OFieldExpressionControl::GetCellText( long nRow, sal_uInt16 /*nColId*/ ) const
493 {
494 OUString sText;
495 if ( nRow != BROWSER_ENDOFSELECTION && m_aGroupPositions[nRow] != NO_GROUP )
496 {
497 try
498 {
499 uno::Reference< report::XGroup> xGroup = m_pParent->getGroup(m_aGroupPositions[nRow]);
500 OUString sExpression = xGroup->getExpression();
501
502 auto aIter = std::find_if(m_aColumnInfo.begin(), m_aColumnInfo.end(),
503 [&sExpression](const ColumnInfo& rColumnInfo) { return rColumnInfo.sColumnName == sExpression; });
504 if (aIter != m_aColumnInfo.end() && !aIter->sLabel.isEmpty())
505 sExpression = aIter->sLabel;
506 sText = sExpression;
507 }
508 catch (const uno::Exception&)
509 {
510 OSL_FAIL("Exception caught while getting expression value from the group");
511 }
512 }
513 return sText;
514 }
515
516
InitController(CellControllerRef &,long nRow,sal_uInt16 nColumnId)517 void OFieldExpressionControl::InitController( CellControllerRef& /*rController*/, long nRow, sal_uInt16 nColumnId )
518 {
519
520 m_pComboCell->SetText( GetCellText( nRow, nColumnId ) );
521 }
522
CursorMoving(long nNewRow,sal_uInt16 nNewCol)523 bool OFieldExpressionControl::CursorMoving(long nNewRow, sal_uInt16 nNewCol)
524 {
525
526 if (!EditBrowseBox::CursorMoving(nNewRow, nNewCol))
527 return false;
528 m_nDataPos = nNewRow;
529 long nOldDataPos = GetCurRow();
530 InvalidateStatusCell( m_nDataPos );
531 InvalidateStatusCell( nOldDataPos );
532
533 m_pParent->SaveData( nOldDataPos );
534 m_pParent->DisplayData( m_nDataPos );
535 return true;
536 }
537
GetController(long,sal_uInt16)538 CellController* OFieldExpressionControl::GetController( long /*nRow*/, sal_uInt16 /*nColumnId*/ )
539 {
540 ComboBoxCellController* pCellController = new ComboBoxCellController( m_pComboCell );
541 pCellController->GetComboBox().SetReadOnly(!m_pParent->m_pController->isEditable());
542 return pCellController;
543 }
544
545
SeekRow(long _nRow)546 bool OFieldExpressionControl::SeekRow( long _nRow )
547 {
548 // the basis class needs the call, because that's how the class knows which line will be painted
549 EditBrowseBox::SeekRow(_nRow);
550 m_nCurrentPos = _nRow;
551 return true;
552 }
553
554
PaintCell(OutputDevice & rDev,const tools::Rectangle & rRect,sal_uInt16 nColumnId) const555 void OFieldExpressionControl::PaintCell( OutputDevice& rDev, const tools::Rectangle& rRect, sal_uInt16 nColumnId ) const
556 {
557 OUString aText =GetCellText( m_nCurrentPos, nColumnId );
558
559 Point aPos( rRect.TopLeft() );
560 Size aTextSize( GetDataWindow().GetTextWidth( aText ), GetDataWindow().GetTextHeight() );
561
562 if( aPos.X() < rRect.Left() || aPos.X() + aTextSize.Width() > rRect.Right() ||
563 aPos.Y() < rRect.Top() || aPos.Y() + aTextSize.Height() > rRect.Bottom() )
564 rDev.SetClipRegion(vcl::Region(rRect));
565
566 rDev.DrawText( aPos, aText );
567
568 if( rDev.IsClipRegion() )
569 rDev.SetClipRegion();
570 }
571
GetRowStatus(long nRow) const572 EditBrowseBox::RowStatus OFieldExpressionControl::GetRowStatus(long nRow) const
573 {
574 if (nRow >= 0 && nRow == m_nDataPos)
575 return EditBrowseBox::CURRENT;
576 if ( nRow != BROWSER_ENDOFSELECTION && nRow < static_cast<long>(m_aGroupPositions.size()) && m_aGroupPositions[nRow] != NO_GROUP )
577 {
578 try
579 {
580 uno::Reference< report::XGroup> xGroup = m_pParent->getGroup(m_aGroupPositions[nRow]);
581 return (xGroup->getHeaderOn() || xGroup->getFooterOn())? EditBrowseBox::HEADERFOOTER : EditBrowseBox::CLEAN;
582 }
583 catch(uno::Exception&)
584 {
585 OSL_FAIL("Exception caught while try to get a group!");
586 }
587 }
588 return EditBrowseBox::CLEAN;
589 }
590
591 // XContainerListener
592
elementInserted(const container::ContainerEvent & evt)593 void OFieldExpressionControl::elementInserted(const container::ContainerEvent& evt)
594 {
595 if ( m_bIgnoreEvent )
596 return;
597 SolarMutexGuard aSolarGuard;
598 ::osl::MutexGuard aGuard( m_aMutex );
599 sal_Int32 nGroupPos = 0;
600 if ( evt.Accessor >>= nGroupPos )
601 {
602 if ( nGroupPos >= GetRowCount() )
603 {
604 sal_Int32 nAddedRows = nGroupPos - GetRowCount();
605 RowInserted(nAddedRows);
606 for (sal_Int32 i = 0; i < nAddedRows; ++i)
607 m_aGroupPositions.push_back(NO_GROUP);
608 m_aGroupPositions[nGroupPos] = nGroupPos;
609 }
610 else
611 {
612 ::std::vector<sal_Int32>::iterator aFind = m_aGroupPositions.begin()+ nGroupPos;
613 if ( aFind == m_aGroupPositions.end() )
614 aFind = ::std::find(m_aGroupPositions.begin(),m_aGroupPositions.end(),NO_GROUP);
615
616 if ( aFind != m_aGroupPositions.end() )
617 {
618 if ( *aFind != NO_GROUP )
619 aFind = m_aGroupPositions.insert(aFind,nGroupPos);
620 else
621 *aFind = nGroupPos;
622
623 ::std::vector<sal_Int32>::const_iterator aEnd = m_aGroupPositions.end();
624 for(++aFind;aFind != aEnd;++aFind)
625 if ( *aFind != NO_GROUP )
626 ++*aFind;
627 }
628 }
629 Invalidate();
630 }
631 }
632
elementRemoved(const container::ContainerEvent & evt)633 void OFieldExpressionControl::elementRemoved(const container::ContainerEvent& evt)
634 {
635 SolarMutexGuard aSolarGuard;
636 ::osl::MutexGuard aGuard( m_aMutex );
637
638 if ( m_bIgnoreEvent )
639 return;
640
641 sal_Int32 nGroupPos = 0;
642 if ( evt.Accessor >>= nGroupPos )
643 {
644 std::vector<sal_Int32>::iterator aEnd = m_aGroupPositions.end();
645 std::vector<sal_Int32>::iterator aFind = std::find(m_aGroupPositions.begin(), aEnd, nGroupPos);
646 if (aFind != aEnd)
647 {
648 *aFind = NO_GROUP;
649 for(++aFind;aFind != aEnd;++aFind)
650 if ( *aFind != NO_GROUP )
651 --*aFind;
652 Invalidate();
653 }
654 }
655 }
656
IsDeleteAllowed() const657 bool OFieldExpressionControl::IsDeleteAllowed( ) const
658 {
659 return !m_pParent->isReadOnly() && GetSelectRowCount() > 0;
660 }
661
KeyInput(const KeyEvent & rEvt)662 void OFieldExpressionControl::KeyInput( const KeyEvent& rEvt )
663 {
664 if (IsDeleteAllowed())
665 {
666 if (rEvt.GetKeyCode().GetCode() == KEY_DELETE && // Delete rows
667 !rEvt.GetKeyCode().IsShift() &&
668 !rEvt.GetKeyCode().IsMod1())
669 {
670 DeleteRows();
671 return;
672 }
673 }
674 EditBrowseBox::KeyInput(rEvt);
675 }
676
Command(const CommandEvent & rEvt)677 void OFieldExpressionControl::Command(const CommandEvent& rEvt)
678 {
679 switch (rEvt.GetCommand())
680 {
681 case CommandEventId::ContextMenu:
682 {
683 if (!rEvt.IsMouseEvent())
684 {
685 EditBrowseBox::Command(rEvt);
686 return;
687 }
688
689 sal_uInt16 nColId = GetColumnId(GetColumnAtXPosPixel(rEvt.GetMousePosPixel().X()));
690
691 if ( nColId == HANDLE_ID )
692 {
693 bool bEnable = false;
694 long nIndex = FirstSelectedRow();
695 while( nIndex != SFX_ENDOFSELECTION && !bEnable )
696 {
697 if ( m_aGroupPositions[nIndex] != NO_GROUP )
698 bEnable = true;
699 nIndex = NextSelectedRow();
700 }
701 VclBuilder aBuilder(nullptr, VclBuilderContainer::getUIRootDir(), "modules/dbreport/ui/groupsortmenu.ui", "");
702 VclPtr<PopupMenu> aContextMenu(aBuilder.get_menu("menu"));
703 aContextMenu->EnableItem(aContextMenu->GetItemId("delete"), IsDeleteAllowed() && bEnable);
704 if (aContextMenu->Execute(this, rEvt.GetMousePosPixel()))
705 {
706 if( m_nDeleteEvent )
707 Application::RemoveUserEvent( m_nDeleteEvent );
708 m_nDeleteEvent = Application::PostUserEvent( LINK(this, OFieldExpressionControl, DelayedDelete), nullptr, true );
709 }
710 }
711 [[fallthrough]];
712 }
713 default:
714 EditBrowseBox::Command(rEvt);
715 }
716
717 }
718
DeleteRows()719 void OFieldExpressionControl::DeleteRows()
720 {
721
722 bool bIsEditing = IsEditing();
723 if (bIsEditing)
724 {
725 DeactivateCell();
726 }
727 long nIndex = FirstSelectedRow();
728 if (nIndex == SFX_ENDOFSELECTION)
729 {
730 nIndex = GetCurRow();
731 }
732 bool bFirstTime = true;
733
734 long nOldDataPos = nIndex;
735 uno::Sequence< beans::PropertyValue > aArgs(1);
736 aArgs[0].Name = PROPERTY_GROUP;
737 m_bIgnoreEvent = true;
738 while( nIndex >= 0 )
739 {
740 if ( m_aGroupPositions[nIndex] != NO_GROUP )
741 {
742 if ( bFirstTime )
743 {
744 bFirstTime = false;
745 OUString sUndoAction(RptResId(RID_STR_UNDO_REMOVE_SELECTION));
746 m_pParent->m_pController->getUndoManager().EnterListAction( sUndoAction, OUString(), 0, ViewShellId(-1) );
747 }
748
749 sal_Int32 nGroupPos = m_aGroupPositions[nIndex];
750 uno::Reference< report::XGroup> xGroup = m_pParent->getGroup(nGroupPos);
751 aArgs[0].Value <<= xGroup;
752 // we use this way to create undo actions
753 m_pParent->m_pController->executeChecked(SID_GROUP_REMOVE,aArgs);
754
755 std::vector<sal_Int32>::iterator aEnd = m_aGroupPositions.end();
756 std::vector<sal_Int32>::iterator aFind = std::find(m_aGroupPositions.begin(), aEnd, nGroupPos);
757 if (aFind != aEnd)
758 {
759 *aFind = NO_GROUP;
760 for(++aFind;aFind != aEnd;++aFind)
761 if ( *aFind != NO_GROUP )
762 --*aFind;
763 }
764 }
765 nIndex = NextSelectedRow();
766 }
767
768 if ( !bFirstTime )
769 m_pParent->m_pController->getUndoManager().LeaveListAction();
770
771 m_nDataPos = GetCurRow();
772 InvalidateStatusCell( nOldDataPos );
773 InvalidateStatusCell( m_nDataPos );
774 ActivateCell();
775 m_pParent->DisplayData( m_nDataPos );
776 m_bIgnoreEvent = false;
777 Invalidate();
778 }
779
IMPL_LINK_NOARG(OFieldExpressionControl,DelayedDelete,void *,void)780 IMPL_LINK_NOARG( OFieldExpressionControl, DelayedDelete, void*, void )
781 {
782 m_nDeleteEvent = nullptr;
783 DeleteRows();
784 }
785
GetOptimalSize() const786 Size OFieldExpressionControl::GetOptimalSize() const
787 {
788 return LogicToPixel(Size(106, 75), MapMode(MapUnit::MapAppFont));
789 }
790
791 // class OGroupsSortingDialog
OGroupsSortingDialog(vcl::Window * _pParent,bool _bReadOnly,OReportController * _pController)792 OGroupsSortingDialog::OGroupsSortingDialog(vcl::Window* _pParent, bool _bReadOnly,
793 OReportController* _pController)
794 : FloatingWindow(_pParent, "FloatingSort", "modules/dbreport/ui/floatingsort.ui")
795 , OPropertyChangeListener(m_aMutex)
796 , m_pController(_pController)
797 , m_xGroups(m_pController->getReportDefinition()->getGroups())
798 , m_bReadOnly(_bReadOnly)
799 {
800 get(m_pToolBox, "toolbox");
801 m_nMoveUpId = m_pToolBox->GetItemId(0);
802 m_nMoveDownId = m_pToolBox->GetItemId(1);
803 m_nDeleteId = m_pToolBox->GetItemId(2);
804 get(m_pOrderLst, "sorting");
805 get(m_pHeaderLst, "header");
806 get(m_pFooterLst, "footer");
807 get(m_pGroupOnLst, "group");
808 get(m_pGroupIntervalEd, "interval");
809 get(m_pKeepTogetherLst, "keep");
810 get(m_pHelpWindow, "helptext");
811 m_pHelpWindow->set_height_request(GetTextHeight() * 4);
812 get(m_pProperties, "properties");
813 m_pFieldExpression = VclPtr<OFieldExpressionControl>::Create(this, get<vcl::Window>("box"));
814 m_pFieldExpression->set_hexpand(true);
815 m_pFieldExpression->set_vexpand(true);
816
817 Control* pControlsLst[] = { m_pHeaderLst, m_pFooterLst, m_pGroupOnLst, m_pKeepTogetherLst, m_pOrderLst, m_pGroupIntervalEd};
818 for (Control* i : pControlsLst)
819 {
820 i->SetGetFocusHdl(LINK(this, OGroupsSortingDialog, OnControlFocusGot));
821 i->SetLoseFocusHdl(LINK(this, OGroupsSortingDialog, OnControlFocusLost));
822 i->Show();
823 }
824
825 for (size_t i = 0; i < SAL_N_ELEMENTS(pControlsLst) - 1; ++i)
826 static_cast<ListBox*>(pControlsLst[i])->SetSelectHdl(LINK(this,OGroupsSortingDialog,LBChangeHdl));
827
828 m_pReportListener = new OPropertyChangeMultiplexer(this,m_pController->getReportDefinition().get());
829 m_pReportListener->addProperty(PROPERTY_COMMAND);
830 m_pReportListener->addProperty(PROPERTY_COMMANDTYPE);
831
832 m_pFieldExpression->lateInit();
833 fillColumns();
834 m_pFieldExpression->Show();
835
836 m_pHelpWindow->SetControlBackground( GetSettings().GetStyleSettings().GetFaceColor() );
837
838 m_pToolBox->SetLineSpacing(true);
839 m_pToolBox->SetSelectHdl(LINK(this, OGroupsSortingDialog, OnFormatAction));
840
841 checkButtons(0);
842
843 Show();
844 }
845
~OGroupsSortingDialog()846 OGroupsSortingDialog::~OGroupsSortingDialog()
847 {
848 disposeOnce();
849 }
850
dispose()851 void OGroupsSortingDialog::dispose()
852 {
853 m_xColumns.clear();
854 m_pReportListener->dispose();
855 if ( m_pCurrentGroupListener.is() )
856 m_pCurrentGroupListener->dispose();
857 m_pToolBox.clear();
858 m_pProperties.clear();
859 m_pOrderLst.clear();
860 m_pHeaderLst.clear();
861 m_pFooterLst.clear();
862 m_pGroupOnLst.clear();
863 m_pGroupIntervalEd.clear();
864 m_pKeepTogetherLst.clear();
865 m_pHelpWindow.clear();
866 m_pFieldExpression.disposeAndClear();
867 FloatingWindow::dispose();
868 }
869
UpdateData()870 void OGroupsSortingDialog::UpdateData( )
871 {
872 m_pFieldExpression->Invalidate();
873 long nCurRow = m_pFieldExpression->GetCurRow();
874 m_pFieldExpression->DeactivateCell();
875 m_pFieldExpression->ActivateCell(nCurRow, m_pFieldExpression->GetCurColumnId());
876 DisplayData(nCurRow);
877 }
878
DisplayData(sal_Int32 _nRow)879 void OGroupsSortingDialog::DisplayData( sal_Int32 _nRow )
880 {
881 const sal_Int32 nGroupPos = m_pFieldExpression->getGroupPosition(_nRow);
882 const bool bEmpty = nGroupPos == NO_GROUP;
883 m_pProperties->Enable(!bEmpty);
884
885 checkButtons(_nRow);
886
887 if ( m_pCurrentGroupListener.is() )
888 m_pCurrentGroupListener->dispose();
889 m_pCurrentGroupListener = nullptr;
890 if (!bEmpty)
891 {
892 uno::Reference< report::XGroup> xGroup = getGroup(nGroupPos);
893
894 m_pCurrentGroupListener = new OPropertyChangeMultiplexer(this,xGroup.get());
895 m_pCurrentGroupListener->addProperty(PROPERTY_HEADERON);
896 m_pCurrentGroupListener->addProperty(PROPERTY_FOOTERON);
897
898 displayGroup(xGroup);
899 }
900 }
901
SaveData(sal_Int32 _nRow)902 void OGroupsSortingDialog::SaveData( sal_Int32 _nRow)
903 {
904 sal_Int32 nGroupPos = m_pFieldExpression->getGroupPosition(_nRow);
905 if ( nGroupPos == NO_GROUP )
906 return;
907
908 uno::Reference< report::XGroup> xGroup = getGroup(nGroupPos);
909 if ( m_pHeaderLst->IsValueChangedFromSaved() )
910 xGroup->setHeaderOn( m_pHeaderLst->GetSelectedEntryPos() == 0 );
911 if ( m_pFooterLst->IsValueChangedFromSaved() )
912 xGroup->setFooterOn( m_pFooterLst->GetSelectedEntryPos() == 0 );
913 if ( m_pKeepTogetherLst->IsValueChangedFromSaved() )
914 xGroup->setKeepTogether( m_pKeepTogetherLst->GetSelectedEntryPos() );
915 if ( m_pGroupOnLst->IsValueChangedFromSaved() )
916 {
917 sal_Int16 nGroupOn = static_cast<sal_Int16>(reinterpret_cast<sal_IntPtr>(m_pGroupOnLst->GetSelectedEntryData()));
918 xGroup->setGroupOn( nGroupOn );
919 }
920 if ( m_pGroupIntervalEd->IsValueChangedFromSaved() )
921 {
922 xGroup->setGroupInterval( static_cast<sal_Int32>(m_pGroupIntervalEd->GetValue()) );
923 m_pGroupIntervalEd->SaveValue();
924 }
925 if ( m_pOrderLst->IsValueChangedFromSaved() )
926 xGroup->setSortAscending( m_pOrderLst->GetSelectedEntryPos() == 0 );
927
928 ListBox* pControls[] = { m_pHeaderLst, m_pFooterLst, m_pGroupOnLst, m_pKeepTogetherLst, m_pOrderLst};
929 for (ListBox* pControl : pControls)
930 pControl->SaveValue();
931 }
932
933
getColumnDataType(const OUString & _sColumnName)934 sal_Int32 OGroupsSortingDialog::getColumnDataType(const OUString& _sColumnName)
935 {
936 sal_Int32 nDataType = sdbc::DataType::VARCHAR;
937 try
938 {
939 if ( !m_xColumns.is() )
940 fillColumns();
941 if ( m_xColumns.is() && m_xColumns->hasByName(_sColumnName) )
942 {
943 uno::Reference< beans::XPropertySet> xColumn(m_xColumns->getByName(_sColumnName),uno::UNO_QUERY);
944 if ( xColumn.is() )
945 xColumn->getPropertyValue(PROPERTY_TYPE) >>= nDataType;
946 }
947 }
948 catch(uno::Exception&)
949 {
950 OSL_FAIL("Exception caught while getting the type of a column");
951 }
952
953 return nDataType;
954 }
955
IMPL_LINK(OGroupsSortingDialog,OnControlFocusGot,Control &,rControl,void)956 IMPL_LINK(OGroupsSortingDialog, OnControlFocusGot, Control&, rControl, void )
957 {
958 if ( m_pFieldExpression && m_pFieldExpression->getExpressionControl() )
959 {
960 const std::pair<Control*, const char*> pControls[] = {
961 { m_pFieldExpression->getExpressionControl(), STR_RPT_HELP_FIELD },
962 { m_pHeaderLst, STR_RPT_HELP_HEADER },
963 { m_pFooterLst, STR_RPT_HELP_FOOTER },
964 { m_pGroupOnLst, STR_RPT_HELP_GROUPON },
965 { m_pGroupIntervalEd, STR_RPT_HELP_INTERVAL },
966 { m_pKeepTogetherLst, STR_RPT_HELP_KEEP },
967 { m_pOrderLst, STR_RPT_HELP_SORT }
968 };
969 for (size_t i = 0; i < SAL_N_ELEMENTS(pControls); ++i)
970 {
971 if (&rControl == pControls[i].first)
972 {
973 ListBox* pListBox = dynamic_cast< ListBox* >( &rControl );
974 if ( pListBox )
975 pListBox->SaveValue();
976 NumericField* pNumericField = dynamic_cast< NumericField* >( &rControl );
977 if ( pNumericField )
978 pNumericField->SaveValue();
979 //shows the text given by the id in the multiline edit
980 m_pHelpWindow->SetText(RptResId(pControls[i].second));
981 break;
982 }
983 }
984 }
985 }
986
IMPL_LINK(OGroupsSortingDialog,OnControlFocusLost,Control &,rControl,void)987 IMPL_LINK(OGroupsSortingDialog, OnControlFocusLost, Control&, rControl, void )
988 {
989 if (m_pFieldExpression && &rControl == m_pGroupIntervalEd)
990 {
991 if ( m_pGroupIntervalEd->IsModified() )
992 SaveData(m_pFieldExpression->GetCurRow());
993 }
994 }
995
IMPL_LINK_NOARG(OGroupsSortingDialog,OnFormatAction,ToolBox *,void)996 IMPL_LINK_NOARG( OGroupsSortingDialog, OnFormatAction, ToolBox*, void )
997 {
998
999 sal_uInt16 nCommand = m_pToolBox->GetCurItemId();
1000
1001 if ( m_pFieldExpression )
1002 {
1003 long nIndex = m_pFieldExpression->GetCurrRow();
1004 sal_Int32 nGroupPos = m_pFieldExpression->getGroupPosition(nIndex);
1005 uno::Sequence<uno::Any> aClipboardList;
1006 if ( nIndex >= 0 && nGroupPos != NO_GROUP )
1007 {
1008 aClipboardList.realloc(1);
1009 aClipboardList[0] = m_xGroups->getByIndex(nGroupPos);
1010 }
1011 if ( nCommand == m_nMoveUpId )
1012 {
1013 --nIndex;
1014 }
1015 if ( nCommand == m_nMoveDownId )
1016 {
1017 ++nIndex;
1018 }
1019 if ( nCommand == m_nDeleteId )
1020 {
1021 Application::PostUserEvent( LINK(m_pFieldExpression, OFieldExpressionControl, DelayedDelete), nullptr, true );
1022 }
1023 else
1024 {
1025 if ( nIndex >= 0 && aClipboardList.hasElements() )
1026 {
1027 m_pFieldExpression->SetNoSelection();
1028 m_pFieldExpression->moveGroups(aClipboardList,nIndex,false);
1029 m_pFieldExpression->DeactivateCell();
1030 m_pFieldExpression->GoToRow(nIndex);
1031 m_pFieldExpression->ActivateCell(nIndex, m_pFieldExpression->GetCurColumnId());
1032 DisplayData(nIndex);
1033 }
1034 }
1035 }
1036 }
1037
IMPL_LINK(OGroupsSortingDialog,LBChangeHdl,ListBox &,rListBox,void)1038 IMPL_LINK( OGroupsSortingDialog, LBChangeHdl, ListBox&, rListBox, void )
1039 {
1040 if ( rListBox.IsValueChangedFromSaved() )
1041 {
1042 sal_Int32 nRow = m_pFieldExpression->GetCurRow();
1043 sal_Int32 nGroupPos = m_pFieldExpression->getGroupPosition(nRow);
1044 if (&rListBox != m_pHeaderLst && &rListBox != m_pFooterLst)
1045 {
1046 if ( rListBox.IsValueChangedFromSaved() )
1047 SaveData(nRow);
1048 if ( &rListBox == m_pGroupOnLst )
1049 m_pGroupIntervalEd->Enable( rListBox.GetSelectedEntryPos() != 0 );
1050 }
1051 else if ( nGroupPos != NO_GROUP )
1052 {
1053 uno::Reference< report::XGroup> xGroup = getGroup(nGroupPos);
1054 uno::Sequence< beans::PropertyValue > aArgs(2);
1055 aArgs[1].Name = PROPERTY_GROUP;
1056 aArgs[1].Value <<= xGroup;
1057
1058 if ( m_pHeaderLst == &rListBox )
1059 aArgs[0].Name = PROPERTY_HEADERON;
1060 else
1061 aArgs[0].Name = PROPERTY_FOOTERON;
1062
1063 aArgs[0].Value <<= rListBox.GetSelectedEntryPos() == 0;
1064 m_pController->executeChecked(m_pHeaderLst == &rListBox ? SID_GROUPHEADER : SID_GROUPFOOTER, aArgs);
1065 m_pFieldExpression->InvalidateHandleColumn();
1066 }
1067 }
1068 }
1069
_propertyChanged(const beans::PropertyChangeEvent & _rEvent)1070 void OGroupsSortingDialog::_propertyChanged(const beans::PropertyChangeEvent& _rEvent)
1071 {
1072 uno::Reference< report::XGroup > xGroup(_rEvent.Source,uno::UNO_QUERY);
1073 if ( xGroup.is() )
1074 displayGroup(xGroup);
1075 else
1076 fillColumns();
1077 }
1078
fillColumns()1079 void OGroupsSortingDialog::fillColumns()
1080 {
1081 m_xColumns = m_pController->getColumns();
1082 m_pFieldExpression->fillColumns(m_xColumns);
1083 }
1084
displayGroup(const uno::Reference<report::XGroup> & _xGroup)1085 void OGroupsSortingDialog::displayGroup(const uno::Reference<report::XGroup>& _xGroup)
1086 {
1087 m_pHeaderLst->SelectEntryPos(_xGroup->getHeaderOn() ? 0 : 1 );
1088 m_pFooterLst->SelectEntryPos(_xGroup->getFooterOn() ? 0 : 1 );
1089 sal_Int32 nDataType = getColumnDataType(_xGroup->getExpression());
1090
1091 // first clear whole group on list
1092 while(m_pGroupOnLst->GetEntryCount() > 1 )
1093 {
1094 m_pGroupOnLst->RemoveEntry(1);
1095 }
1096
1097 switch(nDataType)
1098 {
1099 case sdbc::DataType::LONGVARCHAR:
1100 case sdbc::DataType::VARCHAR:
1101 case sdbc::DataType::CHAR:
1102 m_pGroupOnLst->InsertEntry(RptResId(STR_RPT_PREFIXCHARS));
1103 m_pGroupOnLst->SetEntryData(1,reinterpret_cast<void*>(report::GroupOn::PREFIX_CHARACTERS));
1104 break;
1105 case sdbc::DataType::DATE:
1106 case sdbc::DataType::TIME:
1107 case sdbc::DataType::TIMESTAMP:
1108 {
1109 const char* aIds[] = { STR_RPT_YEAR, STR_RPT_QUARTER,STR_RPT_MONTH,STR_RPT_WEEK,STR_RPT_DAY,STR_RPT_HOUR,STR_RPT_MINUTE };
1110 for (size_t i = 0; i < SAL_N_ELEMENTS(aIds); ++i)
1111 {
1112 m_pGroupOnLst->InsertEntry(RptResId(aIds[i]));
1113 m_pGroupOnLst->SetEntryData(i+1,reinterpret_cast<void*>(i+2));
1114 }
1115 }
1116 break;
1117 default:
1118 m_pGroupOnLst->InsertEntry(RptResId(STR_RPT_INTERVAL));
1119 m_pGroupOnLst->SetEntryData(1,reinterpret_cast<void*>(report::GroupOn::INTERVAL));
1120 break;
1121 }
1122 sal_Int32 nPos = 0;
1123 switch(_xGroup->getGroupOn())
1124 {
1125 case report::GroupOn::DEFAULT:
1126 nPos = 0;
1127 break;
1128 case report::GroupOn::PREFIX_CHARACTERS:
1129 nPos = 1;
1130 break;
1131 case report::GroupOn::YEAR:
1132 nPos = 1;
1133 break;
1134 case report::GroupOn::QUARTAL:
1135 nPos = 2;
1136 break;
1137 case report::GroupOn::MONTH:
1138 nPos = 3;
1139 break;
1140 case report::GroupOn::WEEK:
1141 nPos = 4;
1142 break;
1143 case report::GroupOn::DAY:
1144 nPos = 5;
1145 break;
1146 case report::GroupOn::HOUR:
1147 nPos = 6;
1148 break;
1149 case report::GroupOn::MINUTE:
1150 nPos = 7;
1151 break;
1152 case report::GroupOn::INTERVAL:
1153 nPos = 1;
1154 break;
1155 default:
1156 nPos = 0;
1157 }
1158 m_pGroupOnLst->SelectEntryPos(nPos);
1159 m_pGroupIntervalEd->SetText(OUString::number(_xGroup->getGroupInterval()));
1160 m_pGroupIntervalEd->SaveValue();
1161 m_pGroupIntervalEd->Enable( nPos != 0 );
1162 m_pKeepTogetherLst->SelectEntryPos(_xGroup->getKeepTogether());
1163 m_pOrderLst->SelectEntryPos(_xGroup->getSortAscending() ? 0 : 1);
1164
1165 ListBox* pControls[] = { m_pHeaderLst, m_pFooterLst, m_pGroupOnLst, m_pKeepTogetherLst, m_pOrderLst};
1166 for (ListBox* pControl : pControls)
1167 pControl->SaveValue();
1168
1169 ListBox* pControlsLst2[] = { m_pHeaderLst, m_pFooterLst, m_pGroupOnLst, m_pKeepTogetherLst, m_pOrderLst};
1170 bool bReadOnly = !m_pController->isEditable();
1171 for (ListBox* i : pControlsLst2)
1172 i->SetReadOnly(bReadOnly);
1173 m_pGroupIntervalEd->SetReadOnly(bReadOnly);
1174 }
1175
checkButtons(sal_Int32 _nRow)1176 void OGroupsSortingDialog::checkButtons(sal_Int32 _nRow)
1177 {
1178 sal_Int32 nGroupCount = m_xGroups->getCount();
1179 sal_Int32 nRowCount = m_pFieldExpression->GetRowCount();
1180 bool bEnabled = nGroupCount > 1;
1181
1182 if (bEnabled && _nRow > 0 )
1183 {
1184 m_pToolBox->EnableItem(m_nMoveUpId);
1185 }
1186 else
1187 {
1188 m_pToolBox->EnableItem(m_nMoveUpId, false);
1189 }
1190 if (bEnabled && _nRow < (nRowCount - 1) )
1191 {
1192 m_pToolBox->EnableItem(m_nMoveDownId);
1193 }
1194 else
1195 {
1196 m_pToolBox->EnableItem(m_nMoveDownId, false);
1197 }
1198
1199 sal_Int32 nGroupPos = m_pFieldExpression->getGroupPosition(_nRow);
1200 if ( nGroupPos != NO_GROUP )
1201 {
1202 bool bEnableDelete = nGroupCount > 0;
1203 m_pToolBox->EnableItem(m_nDeleteId, bEnableDelete);
1204 }
1205 else
1206 {
1207 m_pToolBox->EnableItem(m_nDeleteId, false);
1208 }
1209 }
1210
1211 } // rptui
1212
1213 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1214