LibreOffice Module reportdesign (master)  1
GroupsSorting.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 #include <GroupsSorting.hxx>
22 #include <com/sun/star/beans/XPropertySet.hpp>
23 #include <com/sun/star/container/XContainerListener.hpp>
24 #include <com/sun/star/report/GroupOn.hpp>
25 #include <com/sun/star/sdbc/DataType.hpp>
26 
27 #include <strings.hrc>
28 #include <rptui_slotid.hrc>
29 #include <core_resource.hxx>
30 #include <helpids.h>
31 #include "GroupExchange.hxx"
32 #include <UITools.hxx>
33 #include <UndoActions.hxx>
34 #include <strings.hxx>
35 #include <ReportController.hxx>
36 #include <ColumnInfo.hxx>
37 
38 #include <cppuhelper/implbase.hxx>
39 #include <vcl/commandevent.hxx>
40 #include <vcl/svapp.hxx>
41 #include <tools/diagnose_ex.h>
42 
43 #include <algorithm>
44 
45 #define HANDLE_ID 0
46 #define FIELD_EXPRESSION 1
47 #define GROUPS_START_LEN 5
48 #define NO_GROUP -1
49 
50 namespace rptui
51 {
52 using namespace ::com::sun::star;
53 using namespace svt;
54 using namespace ::comphelper;
55 
56  static void lcl_addToList_throw( weld::ComboBox& _rListBox, ::std::vector<ColumnInfo>& o_aColumnList,const uno::Reference< container::XNameAccess>& i_xColumns )
57  {
58  const uno::Sequence< OUString > aEntries = i_xColumns->getElementNames();
59  for ( const OUString& rEntry : aEntries )
60  {
61  uno::Reference< beans::XPropertySet> xColumn(i_xColumns->getByName(rEntry),uno::UNO_QUERY_THROW);
62  OUString sLabel;
63  if ( xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_LABEL) )
64  xColumn->getPropertyValue(PROPERTY_LABEL) >>= sLabel;
65  o_aColumnList.emplace_back(rEntry,sLabel );
66  if ( !sLabel.isEmpty() )
67  _rListBox.append_text( sLabel );
68  else
69  _rListBox.append_text( rEntry );
70  }
71  }
72 
76 class OFieldExpressionControl;
77 
78 namespace {
79 
80 class OFieldExpressionControlContainerListener : public ::cppu::WeakImplHelper< container::XContainerListener >
81 {
83 public:
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 }
95 
97 {
98  ::osl::Mutex m_aMutex;
99  ::std::vector<sal_Int32> m_aGroupPositions;
100  ::std::vector<ColumnInfo> m_aColumnInfo;
102  sal_Int32 m_nDataPos;
103  sal_Int32 m_nCurrentPos;
108 
109 public:
110  OFieldExpressionControl(OGroupsSortingDialog* pParentDialog, const css::uno::Reference<css::awt::XWindow> &rParent);
111  virtual ~OFieldExpressionControl() override;
112  virtual void dispose() override;
113 
114  // XContainerListener
116  void elementInserted(const css::container::ContainerEvent& rEvent);
118  void elementRemoved(const css::container::ContainerEvent& rEvent);
119 
120  virtual Size GetOptimalSize() const override;
121 
122  void fillColumns(const uno::Reference< container::XNameAccess>& _xColumns);
123  void lateInit();
124  bool IsDeleteAllowed( ) const;
125  void DeleteRows();
126 
127  sal_Int32 getGroupPosition(sal_Int32 _nRow) const { return _nRow != BROWSER_ENDOFSELECTION ? m_aGroupPositions[_nRow] : sal_Int32(NO_GROUP); }
128 
131  uno::Sequence<uno::Any> fillSelectedGroups();
132 
135  void moveGroups(const uno::Sequence<uno::Any>& _aGroups,sal_Int32 _nRow,bool _bSelect = true);
136 
137  virtual bool CursorMoving(sal_Int32 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, sal_Int32 nRow, sal_uInt16 nCol ) override;
143  virtual ::svt::CellController* GetController( sal_Int32 nRow, sal_uInt16 nCol ) override;
144  virtual void PaintCell( OutputDevice& rDev, const tools::Rectangle& rRect, sal_uInt16 nColId ) const override;
145  virtual bool SeekRow( sal_Int32 nRow ) override;
146  virtual bool SaveModified() override;
147  virtual OUString GetCellText( sal_Int32 nRow, sal_uInt16 nColId ) const override;
148  virtual RowStatus GetRowStatus(sal_Int32 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;
160 
161 private:
162 
163  DECL_LINK( CBChangeHdl, weld::ComboBox&, void);
164 
165 public:
166  DECL_LINK( DelayedDelete, void*, void );
167 
168 };
169 
170 
171 void OFieldExpressionControlContainerListener::disposing(const css::lang::EventObject& )
172 {}
173 
174 void OFieldExpressionControlContainerListener::elementInserted(const css::container::ContainerEvent& rEvent)
175 { mpParent->elementInserted(rEvent); }
176 
177 void OFieldExpressionControlContainerListener::elementReplaced(const css::container::ContainerEvent& )
178 {}
179 
180 void OFieldExpressionControlContainerListener::elementRemoved(const css::container::ContainerEvent& rEvent)
181 { mpParent->elementRemoved(rEvent); }
182 
183 OFieldExpressionControl::OFieldExpressionControl(OGroupsSortingDialog* pParentDialog, const css::uno::Reference<css::awt::XWindow> &rParent)
187  ,m_aGroupPositions(GROUPS_START_LEN,-1)
188  ,m_pComboCell(nullptr)
189  ,m_nDataPos(-1)
190  ,m_nCurrentPos(-1)
191  ,m_nDeleteEvent(nullptr)
192  ,m_pParent(pParentDialog)
193  ,m_bIgnoreEvent(false)
194  ,aContainerListener(new OFieldExpressionControlContainerListener(this))
195 {
196  SetBorderStyle(WindowBorderStyle::MONO);
197 }
198 
200 {
201  disposeOnce();
202 }
203 
205 {
206  uno::Reference< report::XGroups > xGroups = m_pParent->getGroups();
207  xGroups->removeContainerListener(aContainerListener);
208 
209  // delete events from queue
210  if( m_nDeleteEvent )
212 
214  m_pParent = nullptr;
216 }
217 
219 {
220  uno::Sequence<uno::Any> aList;
221  ::std::vector<uno::Any> vClipboardList;
222  vClipboardList.reserve(GetSelectRowCount());
223 
224  uno::Reference<report::XGroups> xGroups = m_pParent->getGroups();
225  sal_Int32 nCount = xGroups->getCount();
226  if ( nCount >= 1 )
227  {
229  {
230  try
231  {
233  {
234  uno::Reference< report::XGroup> xOrgGroup(xGroups->getByIndex(m_aGroupPositions[nIndex]),uno::UNO_QUERY);
235  /*uno::Reference< report::XGroup> xCopy = xGroups->createGroup();
236  ::comphelper::copyProperties(xOrgGroup.get(),xCopy.get());*/
237  vClipboardList.push_back( uno::makeAny(xOrgGroup) );
238  }
239  }
240  catch(uno::Exception&)
241  {
242  OSL_FAIL("Can not access group!");
243  }
244  }
245  if ( !vClipboardList.empty() )
246  aList = uno::Sequence< uno::Any >(vClipboardList.data(), vClipboardList.size());
247  }
248  return aList;
249 }
250 
251 void OFieldExpressionControl::StartDrag( sal_Int8 /*_nAction*/ , const Point& /*_rPosPixel*/ )
252 {
253  if ( m_pParent && !m_pParent->isReadOnly( ) )
254  {
255  uno::Sequence<uno::Any> aClipboardList = fillSelectedGroups();
256 
257  if( aClipboardList.hasElements() )
258  {
260  pData->StartDrag(this, DND_ACTION_MOVE );
261  }
262  }
263 }
264 
266 {
267  sal_Int8 nAction = DND_ACTION_NONE;
268  if ( IsEditing() )
269  {
270  weld::ComboBox& rComboBox = m_pComboCell->get_widget();
271  sal_Int32 nPos = rComboBox.get_active();
272  if (nPos != -1 || !rComboBox.get_active_text().isEmpty())
273  SaveModified();
274  DeactivateCell();
275  }
276  if ( IsDropFormatSupported( OGroupExchange::getReportGroupId() ) && m_pParent->getGroups()->getCount() > 1 && rEvt.GetWindow() == &GetDataWindow() )
277  {
278  nAction = DND_ACTION_MOVE;
279  }
280  return nAction;
281 }
282 
284 {
285  sal_Int8 nAction = DND_ACTION_NONE;
287  {
288  sal_Int32 nRow = GetRowAtYPosPixel(rEvt.maPosPixel.Y(), false);
289  SetNoSelection();
290 
291  TransferableDataHelper aDropped( rEvt.maDropEvent.Transferable );
292  uno::Any aDrop = aDropped.GetAny(OGroupExchange::getReportGroupId(), OUString());
293  uno::Sequence< uno::Any > aGroups;
294  aDrop >>= aGroups;
295  if ( aGroups.hasElements() )
296  {
297  moveGroups(aGroups,nRow);
298  nAction = DND_ACTION_MOVE;
299  }
300  }
301  return nAction;
302 }
303 
304 void OFieldExpressionControl::moveGroups(const uno::Sequence<uno::Any>& _aGroups,sal_Int32 _nRow,bool _bSelect)
305 {
306  if ( !_aGroups.hasElements() )
307  return;
308 
309  m_bIgnoreEvent = true;
310  {
311  sal_Int32 nRow = _nRow;
312  const OUString sUndoAction(RptResId(RID_STR_UNDO_MOVE_GROUP));
313  const UndoContext aUndoContext( m_pParent->m_pController->getUndoManager(), sUndoAction );
314 
315  uno::Reference< report::XGroups> xGroups = m_pParent->getGroups();
316  for(const uno::Any& rGroup : _aGroups)
317  {
318  uno::Reference< report::XGroup> xGroup(rGroup,uno::UNO_QUERY);
319  if ( xGroup.is() )
320  {
321  uno::Sequence< beans::PropertyValue > aArgs(1);
322  aArgs[0].Name = PROPERTY_GROUP;
323  aArgs[0].Value <<= xGroup;
324  // we use this way to create undo actions
325  m_pParent->m_pController->executeChecked(SID_GROUP_REMOVE,aArgs);
326  aArgs.realloc(2);
327  if ( nRow > xGroups->getCount() )
328  nRow = xGroups->getCount();
329  if ( _bSelect )
330  SelectRow(nRow);
331  aArgs[1].Name = PROPERTY_POSITIONY;
332  aArgs[1].Value <<= nRow;
333  m_pParent->m_pController->executeChecked(SID_GROUP_APPEND,aArgs);
334  ++nRow;
335  }
336  }
337  }
338  m_bIgnoreEvent = false;
339  Invalidate();
340 }
341 
342 void OFieldExpressionControl::fillColumns(const uno::Reference< container::XNameAccess>& _xColumns)
343 {
344  weld::ComboBox& rComboBox = m_pComboCell->get_widget();
345  rComboBox.clear();
346  if ( _xColumns.is() )
347  lcl_addToList_throw(rComboBox, m_aColumnInfo, _xColumns);
348 }
349 
351 {
352  uno::Reference< report::XGroups > xGroups = m_pParent->getGroups();
353  sal_Int32 nGroupsCount = xGroups->getCount();
354  m_aGroupPositions.resize(::std::max<sal_Int32>(nGroupsCount,sal_Int32(GROUPS_START_LEN)),NO_GROUP);
355  ::std::vector<sal_Int32>::iterator aIter = m_aGroupPositions.begin();
356  for (sal_Int32 i = 0; i < nGroupsCount; ++i,++aIter)
357  *aIter = i;
358 
359  if ( ColCount() == 0 )
360  {
361  vcl::Font aFont( GetDataWindow().GetFont() );
362  aFont.SetWeight( WEIGHT_NORMAL );
363  GetDataWindow().SetFont( aFont );
364 
365  // Set font of the headline to light
366  aFont = GetFont();
367  aFont.SetWeight( WEIGHT_LIGHT );
368  SetFont(aFont);
369 
370  InsertHandleColumn(static_cast<sal_uInt16>(GetTextWidth(OUString('0')) * 4)/*, sal_True */);
371  InsertDataColumn( FIELD_EXPRESSION, RptResId(STR_RPT_EXPRESSION), 100);
372 
374  weld::ComboBox& rComboBox = m_pComboCell->get_widget();
375  rComboBox.connect_changed(LINK(this,OFieldExpressionControl,CBChangeHdl));
377 
379 
380 
381  // set browse mode
382  BrowserMode nMode(BrowserMode::COLUMNSELECTION | BrowserMode::MULTISELECTION | BrowserMode::KEEPHIGHLIGHT |
383  BrowserMode::HLINES | BrowserMode::VLINES | BrowserMode::AUTOSIZE_LASTCOL | BrowserMode::AUTO_VSCROLL | BrowserMode::AUTO_HSCROLL);
384  if( m_pParent->isReadOnly() )
385  nMode |= BrowserMode::HIDECURSOR;
386  SetMode(nMode);
387  xGroups->addContainerListener(aContainerListener);
388  }
389  else
390  // not the first call
391  RowRemoved(0, GetRowCount());
392 
393  RowInserted(0, m_aGroupPositions.size());
394 }
395 
397 {
398  SaveModified();
399 }
400 
401 bool OFieldExpressionControl::IsTabAllowed(bool /*bForward*/) const
402 {
403  return false;
404 }
405 
407 {
408  sal_Int32 nRow = GetCurRow();
409  if ( nRow != BROWSER_ENDOFSELECTION )
410  {
411  try
412  {
413  bool bAppend = false;
414  uno::Reference< report::XGroup> xGroup;
415  if ( m_aGroupPositions[nRow] == NO_GROUP )
416  {
417  bAppend = true;
418  OUString sUndoAction(RptResId(RID_STR_UNDO_APPEND_GROUP));
419  m_pParent->m_pController->getUndoManager().EnterListAction( sUndoAction, OUString(), 0, ViewShellId(-1) );
420  xGroup = m_pParent->getGroups()->createGroup();
421  xGroup->setHeaderOn(true);
422 
423  uno::Sequence< beans::PropertyValue > aArgs(2);
424  aArgs[0].Name = PROPERTY_GROUP;
425  aArgs[0].Value <<= xGroup;
426  // find position where to insert the new group
427  sal_Int32 nGroupPos = 0;
428  ::std::vector<sal_Int32>::iterator aIter = m_aGroupPositions.begin();
429  ::std::vector<sal_Int32>::const_iterator aEnd = m_aGroupPositions.begin() + nRow;
430  for(;aIter != aEnd;++aIter)
431  if ( *aIter != NO_GROUP )
432  nGroupPos = *aIter + 1;
433  aArgs[1].Name = PROPERTY_POSITIONY;
434  aArgs[1].Value <<= nGroupPos;
435  m_bIgnoreEvent = true;
436  m_pParent->m_pController->executeChecked(SID_GROUP_APPEND,aArgs);
437  m_bIgnoreEvent = false;
438  OSL_ENSURE(*aIter == NO_GROUP ,"Illegal iterator!");
439  *aIter++ = nGroupPos;
440 
441  aEnd = m_aGroupPositions.end();
442  for(;aIter != aEnd;++aIter)
443  if ( *aIter != NO_GROUP )
444  ++*aIter;
445  }
446  else
447  xGroup = m_pParent->getGroup(m_aGroupPositions[nRow]);
448  if ( xGroup.is() )
449  {
450  weld::ComboBox& rComboBox = m_pComboCell->get_widget();
451  sal_Int32 nPos = rComboBox.get_active();
452  OUString sExpression;
453  if (nPos == -1)
454  sExpression = rComboBox.get_active_text();
455  else
456  {
457  sExpression = m_aColumnInfo[nPos].sColumnName;
458  }
459  xGroup->setExpression( sExpression );
460 
461  ::rptui::adjustSectionName(xGroup,nPos);
462 
463  if ( bAppend )
465  }
466 
467  if (Controller().is())
468  Controller()->SaveValue();
469  if ( GetRowCount() == m_pParent->getGroups()->getCount() )
470  {
471  RowInserted( GetRowCount()-1);
472  m_aGroupPositions.push_back(NO_GROUP);
473  }
474 
475  GoToRow(nRow);
476  m_pParent->DisplayData(nRow);
477  }
478  catch(uno::Exception&)
479  {
480  TOOLS_WARN_EXCEPTION( "reportdesign", "OFieldExpressionControl::SaveModified");
481  }
482  }
483 
484  return true;
485 }
486 
487 OUString OFieldExpressionControl::GetCellText( sal_Int32 nRow, sal_uInt16 /*nColId*/ ) const
488 {
489  OUString sText;
490  if ( nRow != BROWSER_ENDOFSELECTION && m_aGroupPositions[nRow] != NO_GROUP )
491  {
492  try
493  {
494  uno::Reference< report::XGroup> xGroup = m_pParent->getGroup(m_aGroupPositions[nRow]);
495  OUString sExpression = xGroup->getExpression();
496 
497  auto aIter = std::find_if(m_aColumnInfo.begin(), m_aColumnInfo.end(),
498  [&sExpression](const ColumnInfo& rColumnInfo) { return rColumnInfo.sColumnName == sExpression; });
499  if (aIter != m_aColumnInfo.end() && !aIter->sLabel.isEmpty())
500  sExpression = aIter->sLabel;
501  sText = sExpression;
502  }
503  catch (const uno::Exception&)
504  {
505  TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while getting expression value from the group");
506  }
507  }
508  return sText;
509 }
510 
511 void OFieldExpressionControl::InitController( CellControllerRef& /*rController*/, sal_Int32 nRow, sal_uInt16 nColumnId )
512 {
513  weld::ComboBox& rComboBox = m_pComboCell->get_widget();
514  rComboBox.set_entry_text(GetCellText(nRow, nColumnId));
515 }
516 
517 bool OFieldExpressionControl::CursorMoving(sal_Int32 nNewRow, sal_uInt16 nNewCol)
518 {
519 
520  if (!EditBrowseBox::CursorMoving(nNewRow, nNewCol))
521  return false;
522  m_nDataPos = nNewRow;
523  tools::Long nOldDataPos = GetCurRow();
525  InvalidateStatusCell( nOldDataPos );
526 
527  m_pParent->SaveData( nOldDataPos );
529  return true;
530 }
531 
532 CellController* OFieldExpressionControl::GetController( sal_Int32 /*nRow*/, sal_uInt16 /*nColumnId*/ )
533 {
536  return pCellController;
537 }
538 
539 bool OFieldExpressionControl::SeekRow( sal_Int32 _nRow )
540 {
541  // the basis class needs the call, because that's how the class knows which line will be painted
542  EditBrowseBox::SeekRow(_nRow);
543  m_nCurrentPos = _nRow;
544  return true;
545 }
546 
547 void OFieldExpressionControl::PaintCell( OutputDevice& rDev, const tools::Rectangle& rRect, sal_uInt16 nColumnId ) const
548 {
549  OUString aText =GetCellText( m_nCurrentPos, nColumnId );
550 
551  Point aPos( rRect.TopLeft() );
552  Size aTextSize( GetDataWindow().GetTextWidth( aText ), GetDataWindow().GetTextHeight() );
553 
554  if( aPos.X() < rRect.Left() || aPos.X() + aTextSize.Width() > rRect.Right() ||
555  aPos.Y() < rRect.Top() || aPos.Y() + aTextSize.Height() > rRect.Bottom() )
556  rDev.SetClipRegion(vcl::Region(rRect));
557 
558  rDev.DrawText( aPos, aText );
559 
560  if( rDev.IsClipRegion() )
561  rDev.SetClipRegion();
562 }
563 
565 {
566  if (nRow >= 0 && nRow == m_nDataPos)
567  return EditBrowseBox::CURRENT;
568  if ( nRow != BROWSER_ENDOFSELECTION && nRow < static_cast<tools::Long>(m_aGroupPositions.size()) && m_aGroupPositions[nRow] != NO_GROUP )
569  {
570  try
571  {
572  uno::Reference< report::XGroup> xGroup = m_pParent->getGroup(m_aGroupPositions[nRow]);
573  return (xGroup->getHeaderOn() || xGroup->getFooterOn())? EditBrowseBox::HEADERFOOTER : EditBrowseBox::CLEAN;
574  }
575  catch(uno::Exception&)
576  {
577  TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while try to get a group!");
578  }
579  }
580  return EditBrowseBox::CLEAN;
581 }
582 
583 // XContainerListener
584 
585 void OFieldExpressionControl::elementInserted(const container::ContainerEvent& evt)
586 {
587  if ( m_bIgnoreEvent )
588  return;
589  SolarMutexGuard aSolarGuard;
590  ::osl::MutexGuard aGuard( m_aMutex );
591  sal_Int32 nGroupPos = 0;
592  if ( !(evt.Accessor >>= nGroupPos) )
593  return;
594 
595  if ( nGroupPos >= GetRowCount() )
596  {
597  sal_Int32 nAddedRows = nGroupPos - GetRowCount();
598  RowInserted(nAddedRows);
599  for (sal_Int32 i = 0; i < nAddedRows; ++i)
600  m_aGroupPositions.push_back(NO_GROUP);
601  m_aGroupPositions[nGroupPos] = nGroupPos;
602  }
603  else
604  {
605  ::std::vector<sal_Int32>::iterator aFind = m_aGroupPositions.begin()+ nGroupPos;
606  if ( aFind == m_aGroupPositions.end() )
607  aFind = ::std::find(m_aGroupPositions.begin(),m_aGroupPositions.end(),NO_GROUP);
608 
609  if ( aFind != m_aGroupPositions.end() )
610  {
611  if ( *aFind != NO_GROUP )
612  aFind = m_aGroupPositions.insert(aFind,nGroupPos);
613  else
614  *aFind = nGroupPos;
615 
616  ::std::vector<sal_Int32>::const_iterator aEnd = m_aGroupPositions.end();
617  for(++aFind;aFind != aEnd;++aFind)
618  if ( *aFind != NO_GROUP )
619  ++*aFind;
620  }
621  }
622  Invalidate();
623 }
624 
625 void OFieldExpressionControl::elementRemoved(const container::ContainerEvent& evt)
626 {
627  SolarMutexGuard aSolarGuard;
628  ::osl::MutexGuard aGuard( m_aMutex );
629 
630  if ( m_bIgnoreEvent )
631  return;
632 
633  sal_Int32 nGroupPos = 0;
634  if ( !(evt.Accessor >>= nGroupPos) )
635  return;
636 
637  std::vector<sal_Int32>::iterator aEnd = m_aGroupPositions.end();
638  std::vector<sal_Int32>::iterator aFind = std::find(m_aGroupPositions.begin(), aEnd, nGroupPos);
639  if (aFind != aEnd)
640  {
641  *aFind = NO_GROUP;
642  for(++aFind;aFind != aEnd;++aFind)
643  if ( *aFind != NO_GROUP )
644  --*aFind;
645  Invalidate();
646  }
647 }
648 
650 {
651  return !m_pParent->isReadOnly() && GetSelectRowCount() > 0;
652 }
653 
655 {
656  if (IsDeleteAllowed())
657  {
658  if (rEvt.GetKeyCode().GetCode() == KEY_DELETE && // Delete rows
659  !rEvt.GetKeyCode().IsShift() &&
660  !rEvt.GetKeyCode().IsMod1())
661  {
662  DeleteRows();
663  return;
664  }
665  }
667 }
668 
670 {
671  switch (rEvt.GetCommand())
672  {
673  case CommandEventId::ContextMenu:
674  {
675  if (!rEvt.IsMouseEvent())
676  {
678  return;
679  }
680 
681  sal_uInt16 nColId = GetColumnId(GetColumnAtXPosPixel(rEvt.GetMousePosPixel().X()));
682 
683  if ( nColId == HANDLE_ID )
684  {
685  bool bEnable = false;
687  while( nIndex != SFX_ENDOFSELECTION && !bEnable )
688  {
689  if ( m_aGroupPositions[nIndex] != NO_GROUP )
690  bEnable = true;
691  nIndex = NextSelectedRow();
692  }
693 
694  ::tools::Rectangle aRect(rEvt.GetMousePosPixel(), Size(1, 1));
695  weld::Window* pPopupParent = weld::GetPopupParent(*this, aRect);
696  std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pPopupParent, "modules/dbreport/ui/groupsortmenu.ui"));
697  std::unique_ptr<weld::Menu> xContextMenu(xBuilder->weld_menu("menu"));
698  xContextMenu->set_sensitive("delete", IsDeleteAllowed() && bEnable);
699  if (!xContextMenu->popup_at_rect(pPopupParent, aRect).isEmpty())
700  {
701  if( m_nDeleteEvent )
703  m_nDeleteEvent = Application::PostUserEvent( LINK(this, OFieldExpressionControl, DelayedDelete), nullptr, true );
704  }
705  }
706  [[fallthrough]];
707  }
708  default:
710  }
711 
712 }
713 
715 {
716 
717  bool bIsEditing = IsEditing();
718  if (bIsEditing)
719  {
720  DeactivateCell();
721  }
723  if (nIndex == SFX_ENDOFSELECTION)
724  {
725  nIndex = GetCurRow();
726  }
727  bool bFirstTime = true;
728 
729  tools::Long nOldDataPos = nIndex;
730  uno::Sequence< beans::PropertyValue > aArgs(1);
731  aArgs[0].Name = PROPERTY_GROUP;
732  m_bIgnoreEvent = true;
733  while( nIndex >= 0 )
734  {
735  if ( m_aGroupPositions[nIndex] != NO_GROUP )
736  {
737  if ( bFirstTime )
738  {
739  bFirstTime = false;
740  OUString sUndoAction(RptResId(RID_STR_UNDO_REMOVE_SELECTION));
741  m_pParent->m_pController->getUndoManager().EnterListAction( sUndoAction, OUString(), 0, ViewShellId(-1) );
742  }
743 
744  sal_Int32 nGroupPos = m_aGroupPositions[nIndex];
745  uno::Reference< report::XGroup> xGroup = m_pParent->getGroup(nGroupPos);
746  aArgs[0].Value <<= xGroup;
747  // we use this way to create undo actions
748  m_pParent->m_pController->executeChecked(SID_GROUP_REMOVE,aArgs);
749 
750  std::vector<sal_Int32>::iterator aEnd = m_aGroupPositions.end();
751  std::vector<sal_Int32>::iterator aFind = std::find(m_aGroupPositions.begin(), aEnd, nGroupPos);
752  if (aFind != aEnd)
753  {
754  *aFind = NO_GROUP;
755  for(++aFind;aFind != aEnd;++aFind)
756  if ( *aFind != NO_GROUP )
757  --*aFind;
758  }
759  }
760  nIndex = NextSelectedRow();
761  }
762 
763  if ( !bFirstTime )
765 
766  m_nDataPos = GetCurRow();
767  InvalidateStatusCell( nOldDataPos );
769  ActivateCell();
771  m_bIgnoreEvent = false;
772  Invalidate();
773 }
774 
775 IMPL_LINK_NOARG( OFieldExpressionControl, DelayedDelete, void*, void )
776 {
777  m_nDeleteEvent = nullptr;
778  DeleteRows();
779 }
780 
782 {
783  return LogicToPixel(Size(106, 75), MapMode(MapUnit::MapAppFont));
784 }
785 
787  OReportController* pController)
788  : GenericDialogController(pParent, "modules/dbreport/ui/floatingsort.ui", "FloatingSort")
790  , m_pController(pController)
791  , m_xGroups(m_pController->getReportDefinition()->getGroups())
792  , m_bReadOnly(bReadOnly)
793  , m_xToolBox(m_xBuilder->weld_toolbar("toolbox"))
794  , m_xProperties(m_xBuilder->weld_widget("properties"))
795  , m_xOrderLst(m_xBuilder->weld_combo_box("sorting"))
796  , m_xHeaderLst(m_xBuilder->weld_combo_box("header"))
797  , m_xFooterLst(m_xBuilder->weld_combo_box("footer"))
798  , m_xGroupOnLst(m_xBuilder->weld_combo_box("group"))
799  , m_xGroupIntervalEd(m_xBuilder->weld_spin_button("interval"))
800  , m_xKeepTogetherLst(m_xBuilder->weld_combo_box("keep"))
801  , m_xHelpWindow(m_xBuilder->weld_label("helptext"))
802  , m_xBox(m_xBuilder->weld_container("box"))
803  , m_xTableCtrlParent(m_xBox->CreateChildFrame())
804  , m_xFieldExpression(VclPtr<OFieldExpressionControl>::Create(this, m_xTableCtrlParent))
805 {
806  m_xHelpWindow->set_size_request(-1, m_xHelpWindow->get_text_height() * 4);
807  m_xFieldExpression->set_hexpand(true);
808  m_xFieldExpression->set_vexpand(true);
809 
810  weld::Widget* pControlsLst[] = { m_xHeaderLst.get(), m_xFooterLst.get(), m_xGroupOnLst.get(),
811  m_xKeepTogetherLst.get(), m_xOrderLst.get(), m_xGroupIntervalEd.get() };
812  for (weld::Widget* i : pControlsLst)
813  {
814  i->connect_focus_in(LINK(this, OGroupsSortingDialog, OnWidgetFocusGot));
815  i->show();
816  }
817 
818  m_xGroupIntervalEd->connect_focus_out(LINK(this, OGroupsSortingDialog, OnWidgetFocusLost));
819 
820  for (size_t i = 0; i < SAL_N_ELEMENTS(pControlsLst) - 1; ++i)
821  dynamic_cast<weld::ComboBox&>(*pControlsLst[i]).connect_changed(LINK(this,OGroupsSortingDialog,LBChangeHdl));
822 
823  m_pReportListener = new OPropertyChangeMultiplexer(this, m_pController->getReportDefinition());
824  m_pReportListener->addProperty(PROPERTY_COMMAND);
826 
827  m_xFieldExpression->lateInit();
828  fillColumns();
829  Size aPrefSize = m_xFieldExpression->GetOptimalSize();
830  m_xBox->set_size_request(aPrefSize.Width(), aPrefSize.Height());
831  m_xFieldExpression->Show();
832 
833  m_xToolBox->connect_clicked(LINK(this, OGroupsSortingDialog, OnFormatAction));
834 
835  checkButtons(0);
836 }
837 
839 {
840  m_pReportListener->dispose();
841  if ( m_pCurrentGroupListener.is() )
842  m_pCurrentGroupListener->dispose();
843  m_xFieldExpression.disposeAndClear();
844  m_xTableCtrlParent->dispose();
845  m_xTableCtrlParent.clear();
846 }
847 
849 {
850  m_xFieldExpression->Invalidate();
851  sal_Int32 nCurRow = m_xFieldExpression->GetCurRow();
852  m_xFieldExpression->DeactivateCell();
853  m_xFieldExpression->ActivateCell(nCurRow, m_xFieldExpression->GetCurColumnId());
854  DisplayData(nCurRow);
855 }
856 
857 void OGroupsSortingDialog::DisplayData( sal_Int32 _nRow )
858 {
859  const sal_Int32 nGroupPos = m_xFieldExpression->getGroupPosition(_nRow);
860  const bool bEmpty = nGroupPos == NO_GROUP;
861  m_xProperties->set_sensitive(!bEmpty);
862 
863  checkButtons(_nRow);
864 
865  if ( m_pCurrentGroupListener.is() )
866  m_pCurrentGroupListener->dispose();
867  m_pCurrentGroupListener = nullptr;
868  if (!bEmpty)
869  {
870  uno::Reference< report::XGroup> xGroup = getGroup(nGroupPos);
871 
875 
876  displayGroup(xGroup);
877  }
878 }
879 
880 void OGroupsSortingDialog::SaveData( sal_Int32 _nRow)
881 {
882  sal_Int32 nGroupPos = m_xFieldExpression->getGroupPosition(_nRow);
883  if ( nGroupPos == NO_GROUP )
884  return;
885 
886  uno::Reference< report::XGroup> xGroup = getGroup(nGroupPos);
887  if (m_xHeaderLst->get_value_changed_from_saved())
888  xGroup->setHeaderOn( m_xHeaderLst->get_active() == 0 );
889  if (m_xFooterLst->get_value_changed_from_saved())
890  xGroup->setFooterOn( m_xFooterLst->get_active() == 0 );
891  if (m_xKeepTogetherLst->get_value_changed_from_saved())
892  xGroup->setKeepTogether( m_xKeepTogetherLst->get_active() );
893  if (m_xGroupOnLst->get_value_changed_from_saved())
894  {
895  auto nGroupOn = m_xGroupOnLst->get_active_id().toInt32();
896  xGroup->setGroupOn( nGroupOn );
897  }
898  if (m_xGroupIntervalEd->get_value_changed_from_saved())
899  {
900  xGroup->setGroupInterval(m_xGroupIntervalEd->get_value());
901  m_xGroupIntervalEd->save_value();
902  }
903  if ( m_xOrderLst->get_value_changed_from_saved() )
904  xGroup->setSortAscending( m_xOrderLst->get_active() == 0 );
905 
906  weld::ComboBox* pControls[] = { m_xHeaderLst.get(), m_xFooterLst.get(), m_xGroupOnLst.get(),
907  m_xKeepTogetherLst.get(), m_xOrderLst.get() };
908  for (weld::ComboBox* pControl : pControls)
909  pControl->save_value();
910 }
911 
912 sal_Int32 OGroupsSortingDialog::getColumnDataType(const OUString& _sColumnName)
913 {
914  sal_Int32 nDataType = sdbc::DataType::VARCHAR;
915  try
916  {
917  if ( !m_xColumns.is() )
918  fillColumns();
919  if ( m_xColumns.is() && m_xColumns->hasByName(_sColumnName) )
920  {
921  uno::Reference< beans::XPropertySet> xColumn(m_xColumns->getByName(_sColumnName),uno::UNO_QUERY);
922  if ( xColumn.is() )
923  xColumn->getPropertyValue(PROPERTY_TYPE) >>= nDataType;
924  }
925  }
926  catch(uno::Exception&)
927  {
928  TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while getting the type of a column");
929  }
930 
931  return nDataType;
932 }
933 
935 {
936  m_xHelpWindow->set_label(RptResId(STR_RPT_HELP_FIELD));
937 }
938 
939 IMPL_LINK(OGroupsSortingDialog, OnWidgetFocusGot, weld::Widget&, rControl, void )
940 {
941  const std::pair<weld::Widget*, TranslateId> pControls[] = {
942  { m_xHeaderLst.get(), STR_RPT_HELP_HEADER },
943  { m_xFooterLst.get(), STR_RPT_HELP_FOOTER },
944  { m_xGroupOnLst.get(), STR_RPT_HELP_GROUPON },
945  { m_xGroupIntervalEd.get(), STR_RPT_HELP_INTERVAL },
946  { m_xKeepTogetherLst.get(), STR_RPT_HELP_KEEP },
947  { m_xOrderLst.get(), STR_RPT_HELP_SORT }
948  };
949  for (size_t i = 0; i < SAL_N_ELEMENTS(pControls); ++i)
950  {
951  if (&rControl == pControls[i].first)
952  {
953  weld::ComboBox* pListBox = dynamic_cast<weld::ComboBox*>( &rControl );
954  if ( pListBox )
955  pListBox->save_value();
956  weld::SpinButton* pNumericField = dynamic_cast<weld::SpinButton*>(&rControl);
957  if ( pNumericField )
958  pNumericField->save_value();
959  //shows the text given by the id in the multiline edit
960  m_xHelpWindow->set_label(RptResId(pControls[i].second));
961  break;
962  }
963  }
964 }
965 
967 {
968  if (m_xFieldExpression)
969  {
970  if (m_xGroupIntervalEd->get_value_changed_from_saved())
971  SaveData(m_xFieldExpression->GetCurRow());
972  }
973 }
974 
975 IMPL_LINK(OGroupsSortingDialog, OnFormatAction, const OString&, rCommand, void)
976 {
977  if ( !m_xFieldExpression )
978  return;
979 
980  tools::Long nIndex = m_xFieldExpression->GetCurrRow();
981  sal_Int32 nGroupPos = m_xFieldExpression->getGroupPosition(nIndex);
982  uno::Sequence<uno::Any> aClipboardList;
983  if ( nIndex >= 0 && nGroupPos != NO_GROUP )
984  {
985  aClipboardList.realloc(1);
986  aClipboardList[0] = m_xGroups->getByIndex(nGroupPos);
987  }
988  if (rCommand == "up")
989  {
990  --nIndex;
991  }
992  if (rCommand == "down")
993  {
994  ++nIndex;
995  }
996  if (rCommand == "delete")
997  {
998  Application::PostUserEvent(LINK(m_xFieldExpression, OFieldExpressionControl, DelayedDelete));
999  }
1000  else
1001  {
1002  if ( nIndex >= 0 && aClipboardList.hasElements() )
1003  {
1004  m_xFieldExpression->SetNoSelection();
1005  m_xFieldExpression->moveGroups(aClipboardList,nIndex,false);
1006  m_xFieldExpression->DeactivateCell();
1007  m_xFieldExpression->GoToRow(nIndex);
1008  m_xFieldExpression->ActivateCell(nIndex, m_xFieldExpression->GetCurColumnId());
1009  DisplayData(nIndex);
1010  }
1011  }
1012 }
1013 
1014 IMPL_LINK( OGroupsSortingDialog, LBChangeHdl, weld::ComboBox&, rListBox, void )
1015 {
1016  if ( !rListBox.get_value_changed_from_saved() )
1017  return;
1018 
1019  sal_Int32 nRow = m_xFieldExpression->GetCurRow();
1020  sal_Int32 nGroupPos = m_xFieldExpression->getGroupPosition(nRow);
1021  if (&rListBox != m_xHeaderLst.get() && &rListBox != m_xFooterLst.get())
1022  {
1023  if ( rListBox.get_value_changed_from_saved() )
1024  SaveData(nRow);
1025  if ( &rListBox == m_xGroupOnLst.get() )
1026  m_xGroupIntervalEd->set_sensitive(rListBox.get_active() != 0);
1027  }
1028  else if ( nGroupPos != NO_GROUP )
1029  {
1030  uno::Reference< report::XGroup> xGroup = getGroup(nGroupPos);
1031  uno::Sequence< beans::PropertyValue > aArgs(2);
1032  aArgs[1].Name = PROPERTY_GROUP;
1033  aArgs[1].Value <<= xGroup;
1034 
1035  if ( m_xHeaderLst.get() == &rListBox )
1036  aArgs[0].Name = PROPERTY_HEADERON;
1037  else
1038  aArgs[0].Name = PROPERTY_FOOTERON;
1039 
1040  aArgs[0].Value <<= rListBox.get_active() == 0;
1041  m_pController->executeChecked(m_xHeaderLst.get() == &rListBox ? SID_GROUPHEADER : SID_GROUPFOOTER, aArgs);
1042  m_xFieldExpression->InvalidateHandleColumn();
1043  }
1044 }
1045 
1046 void OGroupsSortingDialog::_propertyChanged(const beans::PropertyChangeEvent& _rEvent)
1047 {
1048  uno::Reference< report::XGroup > xGroup(_rEvent.Source,uno::UNO_QUERY);
1049  if ( xGroup.is() )
1050  displayGroup(xGroup);
1051  else
1052  fillColumns();
1053 }
1054 
1056 {
1058  m_xFieldExpression->fillColumns(m_xColumns);
1059 }
1060 
1061 void OGroupsSortingDialog::displayGroup(const uno::Reference<report::XGroup>& _xGroup)
1062 {
1063  m_xHeaderLst->set_active(_xGroup->getHeaderOn() ? 0 : 1 );
1064  m_xFooterLst->set_active(_xGroup->getFooterOn() ? 0 : 1 );
1065  sal_Int32 nDataType = getColumnDataType(_xGroup->getExpression());
1066 
1067  // first clear whole group on list
1068  while (m_xGroupOnLst->get_count() > 1 )
1069  {
1070  m_xGroupOnLst->remove(1);
1071  }
1072 
1073  switch(nDataType)
1074  {
1075  case sdbc::DataType::LONGVARCHAR:
1076  case sdbc::DataType::VARCHAR:
1077  case sdbc::DataType::CHAR:
1078  m_xGroupOnLst->append(OUString::number(report::GroupOn::PREFIX_CHARACTERS), RptResId(STR_RPT_PREFIXCHARS));
1079  break;
1080  case sdbc::DataType::DATE:
1081  case sdbc::DataType::TIME:
1082  case sdbc::DataType::TIMESTAMP:
1083  {
1084  const TranslateId aIds[] = { STR_RPT_YEAR, STR_RPT_QUARTER,STR_RPT_MONTH,STR_RPT_WEEK,STR_RPT_DAY,STR_RPT_HOUR,STR_RPT_MINUTE };
1085  for (size_t i = 0; i < SAL_N_ELEMENTS(aIds); ++i)
1086  {
1087  m_xGroupOnLst->append(OUString::number(i+2), RptResId(aIds[i]));
1088  }
1089  }
1090  break;
1091  default:
1092  m_xGroupOnLst->append(OUString::number(report::GroupOn::INTERVAL), RptResId(STR_RPT_INTERVAL));
1093  break;
1094  }
1095  sal_Int32 nPos = 0;
1096  switch(_xGroup->getGroupOn())
1097  {
1098  case report::GroupOn::DEFAULT:
1099  nPos = 0;
1100  break;
1101  case report::GroupOn::PREFIX_CHARACTERS:
1102  nPos = 1;
1103  break;
1104  case report::GroupOn::YEAR:
1105  nPos = 1;
1106  break;
1107  case report::GroupOn::QUARTAL:
1108  nPos = 2;
1109  break;
1110  case report::GroupOn::MONTH:
1111  nPos = 3;
1112  break;
1113  case report::GroupOn::WEEK:
1114  nPos = 4;
1115  break;
1116  case report::GroupOn::DAY:
1117  nPos = 5;
1118  break;
1119  case report::GroupOn::HOUR:
1120  nPos = 6;
1121  break;
1122  case report::GroupOn::MINUTE:
1123  nPos = 7;
1124  break;
1125  case report::GroupOn::INTERVAL:
1126  nPos = 1;
1127  break;
1128  default:
1129  nPos = 0;
1130  }
1131  m_xGroupOnLst->set_active(nPos);
1132  m_xGroupIntervalEd->set_value(_xGroup->getGroupInterval());
1133  m_xGroupIntervalEd->save_value();
1134  m_xGroupIntervalEd->set_sensitive( nPos != 0 );
1135  m_xKeepTogetherLst->set_active(_xGroup->getKeepTogether());
1136  m_xOrderLst->set_active(_xGroup->getSortAscending() ? 0 : 1);
1137 
1138  weld::ComboBox* pControls[] = { m_xHeaderLst.get(), m_xFooterLst.get(), m_xGroupOnLst.get(),
1139  m_xKeepTogetherLst.get(), m_xOrderLst.get() };
1140  for (weld::ComboBox* pControl : pControls)
1141  pControl->save_value();
1142 
1143  bool bReadOnly = !m_pController->isEditable();
1144  for (weld::ComboBox* pControl : pControls)
1145  pControl->set_sensitive(!bReadOnly);
1146  m_xGroupIntervalEd->set_editable(!bReadOnly);
1147 }
1148 
1150 {
1151  sal_Int32 nGroupCount = m_xGroups->getCount();
1152  sal_Int32 nRowCount = m_xFieldExpression->GetRowCount();
1153  bool bEnabled = nGroupCount > 1;
1154 
1155  if (bEnabled && _nRow > 0 )
1156  {
1157  m_xToolBox->set_item_sensitive("up", true);
1158  }
1159  else
1160  {
1161  m_xToolBox->set_item_sensitive("up", false);
1162  }
1163  if (bEnabled && _nRow < (nRowCount - 1) )
1164  {
1165  m_xToolBox->set_item_sensitive("down", true);
1166  }
1167  else
1168  {
1169  m_xToolBox->set_item_sensitive("down", false);
1170  }
1171 
1172  sal_Int32 nGroupPos = m_xFieldExpression->getGroupPosition(_nRow);
1173  if ( nGroupPos != NO_GROUP )
1174  {
1175  bool bEnableDelete = nGroupCount > 0;
1176  m_xToolBox->set_item_sensitive("delete", bEnableDelete);
1177  }
1178  else
1179  {
1180  m_xToolBox->set_item_sensitive("delete", false);
1181  }
1182 }
1183 
1184 } // rptui
1185 
1186 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void InsertHandleColumn(sal_uLong nWidth)
void SetClipRegion()
std::unique_ptr< weld::ComboBox > m_xKeepTogetherLst
void SetMode(BrowserMode nMode)
sal_Int32 GetRowAtYPosPixel(tools::Long nY, bool bRelToBrowser=true) const
#define PROPERTY_LABEL
Definition: strings.hxx:90
css::uno::Reference< css::report::XGroups > & getGroups()
returns the groups
sal_Int32 nIndex
sal_Int32 NextSelectedRow()
virtual void KeyInput(const KeyEvent &rEvt) override
std::unique_ptr< weld::ComboBox > m_xHeaderLst
css::uno::Any GetAny(SotClipboardFormatId nFormat, const OUString &rDestDoc) const
#define PROPERTY_HEADERON
Definition: strings.hxx:71
void SAL_CALL elementReplaced(const css::container::ContainerEvent &Event) override
EditBrowseBoxFlags
void SetFocusInHdl(const Link< LinkParamNone *, void > &rHdl)
#define PROPERTY_GROUP
Definition: strings.hxx:48
std::unique_ptr< ContentProperties > pData
void DisplayData(sal_Int32 _nRow)
updates the listboxes with the new group properties
signed char sal_Int8
rtl::Reference< OFieldExpressionControlContainerListener > aContainerListener
constexpr tools::Long Left() const
#define FIELD_EXPRESSION
void Create(SwFormatVertOrient &rItem, SvStream &rStrm, sal_uInt16 nVersionAbusedAsSize)
long Long
virtual void SelectRow(sal_Int32 nRow, bool _bSelect=true, bool bExpand=true) override
void disposeAndClear()
void moveGroups(const uno::Sequence< uno::Any > &_aGroups, sal_Int32 _nRow, bool _bSelect=true)
move groups given by _aGroups
virtual bool CursorMoving(sal_Int32 nNewRow, sal_uInt16 nNewCol)
::rptui::OReportController * m_pController
sal_Int32 getColumnDataType(const OUString &_sColumnName)
returns the data type for the given column name
css::uno::Reference< css::report::XGroups > m_xGroups
virtual sal_Int8 ExecuteDrop(const BrowserExecuteDropEvent &rEvt) override
std::unique_ptr< weld::SpinButton > m_xGroupIntervalEd
virtual bool SaveModified() override
sal_Int32 GetSelectRowCount() const
void SetWeight(FontWeight)
css::uno::Reference< css::awt::XWindow > m_xTableCtrlParent
virtual bool SeekRow(sal_Int32 nRow) override
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
virtual void DeactivateCell(bool bUpdate=true)
sal_uInt16 GetCode() const
weld::ComboBox & get_widget()
virtual void dispose() override
constexpr sal_Int32 BROWSER_ENDOFSELECTION
::rtl::Reference< comphelper::OPropertyChangeMultiplexer > m_pCurrentGroupListener
#define PROPERTY_POSITIONY
Definition: strings.hxx:75
bool lateInit
OUString Name
bool IsEditing() const
SfxUndoManager & getUndoManager() const
virtual int get_active() const =0
void RowInserted(sal_Int32 nRow, sal_Int32 nNumRows=1, bool bDoPaint=true, bool bKeepSelection=false)
void SetFont(const vcl::Font &rNewFont)
WEIGHT_LIGHT
sal_uInt16 GetColumnAtXPosPixel(tools::Long nX) const
static SotClipboardFormatId getReportGroupId()
static void lcl_addToList_throw(weld::ComboBox &_rListBox,::std::vector< ColumnInfo > &o_aColumnList, const uno::Reference< container::XNameAccess > &i_xColumns)
virtual void Command(const CommandEvent &rEvt) override
weld::ComboBox & GetComboBox() const
BrowserDataWin & GetDataWindow() const
virtual void StartDrag(sal_Int8 nAction, const Point &rPosPixel) override
#define PROPERTY_FOOTERON
Definition: strings.hxx:72
#define DND_ACTION_MOVE
virtual void set_entry_editable(bool bEditable)=0
constexpr tools::Long Width() const
std::unique_ptr< weld::ComboBox > m_xFooterLst
virtual void dispose() override
virtual sal_Int8 AcceptDrop(const AcceptDropEvent &rEvt) override
bool IsMouseEvent() const
int nCount
VclPtr< OFieldExpressionControl > mpParent
#define PROPERTY_COMMANDTYPE
Definition: strings.hxx:66
#define DND_ACTION_NONE
#define PROPERTY_TYPE
Definition: strings.hxx:217
std::mutex m_aMutex
void fillColumns(const uno::Reference< container::XNameAccess > &_xColumns)
virtual void KeyInput(const KeyEvent &rEvt) override
std::unique_ptr< weld::ComboBox > m_xGroupOnLst
virtual RowStatus GetRowStatus(sal_Int32 nRow) const override
virtual void SetNoSelection() override
VclPtr< OFieldExpressionControl > m_xFieldExpression
OFieldExpressionControl(OGroupsSortingDialog *pParentDialog, const css::uno::Reference< css::awt::XWindow > &rParent)
virtual sal_Int32 GetRowCount() const override
sal_Int32 GetCurRow() const
std::unique_ptr< weld::Toolbar > m_xToolBox
virtual void Command(const CommandEvent &rEvt) override
friend friend class OPropertyChangeMultiplexer
#define SAL_N_ELEMENTS(arr)
static void RemoveUserEvent(ImplSVEvent *nUserEvent)
void InvalidateStatusCell(sal_Int32 nRow)
#define GROUPS_START_LEN
#define TOOLS_WARN_EXCEPTION(area, stream)
OUString RptResId(TranslateId aId)
int i
bool IsClipRegion() const
void connect_changed(const Link< ComboBox &, void > &rLink)
uno::Sequence< uno::Any > fillSelectedGroups()
returns the sequence with the selected groups
IMPL_LINK_NOARG(OAddFieldWindow, FocusChangeHdl, weld::Container &, void)
Definition: AddField.cxx:120
::std::vector< ColumnInfo > m_aColumnInfo
weld::Window * GetPopupParent(vcl::Window &rOutWin, tools::Rectangle &rRect)
void adjustSectionName(const css::uno::Reference< css::report::XGroup > &_xGroup, sal_Int32 _nPos)
set the name of the header and footer of the group by the expression appended by the localized name o...
virtual void _propertyChanged(const css::beans::PropertyChangeEvent &_rEvent) override
constexpr tools::Long Right() const
const vcl::Font & GetFont() const
WEIGHT_NORMAL
CommandEventId GetCommand() const
void SAL_CALL elementRemoved(const css::container::ContainerEvent &Event) override
constexpr tools::Long Top() const
DECL_LISTENERMULTIPLEXER_END void SAL_CALL elementInserted(const css::container::ContainerEvent &Event) override
::std::vector< sal_Int32 > m_aGroupPositions
BrowserMode
virtual void clear()=0
css::uno::Reference< css::report::XGroup > getGroup(sal_Int32 _nPos)
void elementInserted(const css::container::ContainerEvent &rEvent)
vcl::Window * GetWindow() const
sal_uInt16 GetColumnId(sal_uInt16 nPos) const
size_t LeaveListAction()
constexpr Point TopLeft() const
virtual void SaveValue()=0
sal_Int32 getGroupPosition(sal_Int32 _nRow) const
const Point & GetMousePosPixel() const
constexpr tools::Long Bottom() const
#define NO_GROUP
bool GoToRow(sal_Int32 nRow)
std::unique_ptr< weld::ComboBox > m_xOrderLst
IMPL_LINK(OAddFieldWindow, DragBeginHdl, bool &, rUnsetDragIcon, bool)
Definition: AddField.cxx:49
virtual bool CursorMoving(sal_Int32 nNewRow, sal_uInt16 nNewCol) override
const vcl::KeyCode & GetKeyCode() const
bool IsShift() const
#define HID_RPT_FIELDEXPRESSION
Definition: helpids.h:33
constexpr tools::Long Height() const
void checkButtons(sal_Int32 _nRow)
enables or disables the up and down button
sal_Int32 nDataType
const CellControllerRef & Controller() const
VclPtr< ::svt::ComboBoxControl > m_pComboCell
#define HANDLE_ID
bool IsMod1() const
static VclPtr< reference_type > Create(Arg &&...arg)
sal_Int32 FirstSelectedRow()
OGroupsSortingDialog(OGroupsSortingDialog const &)=delete
virtual void EnterListAction(const OUString &rComment, const OUString &rRepeatComment, sal_uInt16 nId, ViewShellId nViewShellId)
virtual sal_Int8 ExecuteDrop(const ExecuteDropEvent &rEvt) override
OGroupsSortingDialog * m_pParent
void save_value()
virtual Size GetOptimalSize() const override
virtual void PaintCell(OutputDevice &rDev, const tools::Rectangle &rRect, sal_uInt16 nColId) const override
bool isReadOnly() const
returns when the dialog should be read only
std::unique_ptr< weld::Widget > m_xProperties
virtual ::svt::CellController * GetController(sal_Int32 nRow, sal_uInt16 nCol) override
void fillColumns()
clears the m_xColumns member and reset the fields
bool m_bReadOnly
::rtl::Reference< comphelper::OPropertyChangeMultiplexer > m_pReportListener
Reference< XColumn > xColumn
WinBits const WB_TABSTOP
void elementRemoved(const css::container::ContainerEvent &rEvent)
void RowRemoved(sal_Int32 nRow, sal_Int32 nNumRows=1, bool bDoPaint=true)
sal_Int32 m_nCurrentPos
virtual OUString GetCellText(sal_Int32 nRow, sal_uInt16 nColId) const override
ScXMLEditAttributeMap::Entry const aEntries[]
void append_text(const OUString &rStr)
virtual ~OGroupsSortingDialog() override
virtual ~OFieldExpressionControl() override
constexpr sal_uInt16 KEY_DELETE
void dispose()
void SaveData(sal_Int32 _nRow)
saves the values from the listboxes into the group at position _nRow
constexpr OUStringLiteral first
#define PROPERTY_COMMAND
Definition: strings.hxx:59
void DrawText(const Point &rStartPt, const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, std::vector< tools::Rectangle > *pVector=nullptr, OUString *pDisplayText=nullptr, const SalLayoutGlyphs *pLayoutCache=nullptr)
css::uno::Reference< css::container::XNameAccess > m_xColumns
void displayGroup(const css::uno::Reference< css::report::XGroup > &_xGroup)
display the group props
bool IsDropFormatSupported(SotClipboardFormatId nFormat) const
virtual void InitController(::svt::CellControllerRef &rController, sal_Int32 nRow, sal_uInt16 nCol) override
#define SFX_ENDOFSELECTION
virtual void set_entry_text(const OUString &rStr)=0
css::uno::Reference< css::container::XNameAccess > const & getColumns() const
void InsertDataColumn(sal_uInt16 nItemId, const OUString &rText, tools::Long nSize, HeaderBarItemBits nBits=HeaderBarItemBits::STDSTYLE, sal_uInt16 nPos=HEADERBAR_APPEND)
sal_uInt16 nPos
static std::unique_ptr< weld::Builder > CreateBuilder(weld::Widget *pParent, const OUString &rUIFile, bool bMobile=false, sal_uInt64 nLOKWindowId=0)
sal_uInt16 ColCount() const
virtual bool SeekRow(sal_Int32 nRow) override
virtual OUString get_active_text() const =0
virtual bool IsTabAllowed(bool bForward) const override
clipboard class for group rows in the groups and sorting dialog
virtual sal_Int8 AcceptDrop(const BrowserAcceptDropEvent &rEvt) override