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