LibreOffice Module sc (master) 1
gridwin2.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <scitems.hxx>
21#include <vcl/settings.hxx>
22#include <comphelper/lok.hxx>
23
24#include <attrib.hxx>
25#include <gridwin.hxx>
26#include <tabvwsh.hxx>
27#include <docsh.hxx>
28#include <viewdata.hxx>
29#include <pivot.hxx>
30#include <uiitems.hxx>
31#include <scresid.hxx>
32#include <globstr.hrc>
33#include <strings.hrc>
34#include <pagedata.hxx>
35#include <dpobject.hxx>
36#include <dpsave.hxx>
37#include <dpshttab.hxx>
38#include <dbdocfun.hxx>
39#include <checklistmenu.hxx>
40#include <dpcontrol.hxx>
41#include <userlist.hxx>
42#include <scabstdlg.hxx>
43
44#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
45#include <com/sun/star/sheet/DataPilotTableHeaderData.hpp>
46
47#include <unordered_map>
48#include <memory>
49#include <vector>
50
51using namespace css;
52using namespace css::sheet;
53using css::sheet::DataPilotFieldOrientation;
54using std::vector;
55
56DataPilotFieldOrientation ScGridWindow::GetDPFieldOrientation( SCCOL nCol, SCROW nRow ) const
57{
59 SCTAB nTab = mrViewData.GetTabNo();
60 ScDPObject* pDPObj = rDoc.GetDPAtCursor(nCol, nRow, nTab);
61 if (!pDPObj)
62 return DataPilotFieldOrientation_HIDDEN;
63
64 DataPilotFieldOrientation nOrient = DataPilotFieldOrientation_HIDDEN;
65
66 // Check for page field first.
67 if (nCol > 0)
68 {
69 // look for the dimension header left of the drop-down arrow
70 tools::Long nField = pDPObj->GetHeaderDim( ScAddress( nCol-1, nRow, nTab ), nOrient );
71 if ( nField >= 0 && nOrient == DataPilotFieldOrientation_PAGE )
72 {
73 bool bIsDataLayout = false;
74 OUString aFieldName = pDPObj->GetDimName( nField, bIsDataLayout );
75 if ( !aFieldName.isEmpty() && !bIsDataLayout )
76 return DataPilotFieldOrientation_PAGE;
77 }
78 }
79
80 nOrient = DataPilotFieldOrientation_HIDDEN;
81
82 // Now, check for row/column field.
83 tools::Long nField = pDPObj->GetHeaderDim(ScAddress(nCol, nRow, nTab), nOrient);
84 if (nField >= 0 && (nOrient == DataPilotFieldOrientation_COLUMN || nOrient == DataPilotFieldOrientation_ROW) )
85 {
86 bool bIsDataLayout = false;
87 OUString aFieldName = pDPObj->GetDimName(nField, bIsDataLayout);
88 if (!aFieldName.isEmpty() && !bIsDataLayout)
89 return nOrient;
90 }
91
92 return DataPilotFieldOrientation_HIDDEN;
93}
94
95// private method for mouse button handling
97{
98 if (GetDPFieldOrientation( nCol, nRow ) == DataPilotFieldOrientation_PAGE)
99 {
100 LaunchPageFieldMenu( nCol, nRow );
101 return true;
102 }
103 return false;
104}
105
107{
109 SCTAB nTab = mrViewData.GetTabNo();
110 Point aScrPos = mrViewData.GetScrPos(nCol, nRow, eWhich);
111 Point aDiffPix = rMEvt.GetPosPixel();
112
113 aDiffPix -= aScrPos;
114 bool bLOKActive = comphelper::LibreOfficeKit::isActive();
115 bool bLayoutRTL = rDoc.IsLayoutRTL( nTab );
116 if ( bLayoutRTL && !bLOKActive )
117 aDiffPix.setX( -aDiffPix.X() );
118
119 tools::Long nSizeX, nSizeY;
120 mrViewData.GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY );
121 // The button height should not use the merged cell height, should still use single row height
122 nSizeY = ScViewData::ToPixel(rDoc.GetRowHeight(nRow, nTab), mrViewData.GetPPTY());
123 Size aScrSize(nSizeX-1, nSizeY-1);
124
125 // Check if the mouse cursor is clicking on the popup arrow box.
126 mpFilterButton.reset(new ScDPFieldButton(GetOutDev(), &GetSettings().GetStyleSettings(), &mrViewData.GetZoomY(), &rDoc));
127 mpFilterButton->setBoundingBox(aScrPos, aScrSize, bLayoutRTL && !bLOKActive);
128 mpFilterButton->setPopupLeft(bLayoutRTL && bLOKActive ? false : bLayoutRTL); // #i114944# AutoFilter button is left-aligned in RTL
129 Point aPopupPos;
130 Size aPopupSize;
131 mpFilterButton->getPopupBoundingBox(aPopupPos, aPopupSize);
132 tools::Rectangle aRect(aPopupPos, aPopupSize);
133 if (aRect.Contains(rMEvt.GetPosPixel()))
134 {
135 if ( DoPageFieldSelection( nCol, nRow ) )
136 return true;
137
138 bool bFilterActive = IsAutoFilterActive(nCol, nRow, nTab);
139 mpFilterButton->setHasHiddenMember(bFilterActive);
140 mpFilterButton->setDrawBaseButton(false);
141 mpFilterButton->setDrawPopupButton(true);
142 mpFilterButton->setPopupPressed(true);
143 mpFilterButton->draw();
144 LaunchAutoFilterMenu(nCol, nRow);
145 return true;
146 }
147
148 return false;
149}
150
151void ScGridWindow::DoPushPivotButton( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt, bool bButton, bool bPopup, bool bMultiField )
152{
154 SCTAB nTab = mrViewData.GetTabNo();
155
156 ScDPObject* pDPObj = rDoc.GetDPAtCursor(nCol, nRow, nTab);
157
158 if (pDPObj)
159 {
160 DataPilotFieldOrientation nOrient = DataPilotFieldOrientation_HIDDEN;
161 ScAddress aPos( nCol, nRow, nTab );
162 ScAddress aDimPos = aPos;
163 if (!bButton && bPopup && aDimPos.Col() > 0)
164 // For page field selection cell, the real field position is to the left.
165 aDimPos.IncCol(-1);
166
167 if (bMultiField && DPTestMultiFieldPopupArrow(rMEvt, aPos, pDPObj))
168 {
169 // Multi-field pop up menu has been launched. Don't activate
170 // field move or regular popup.
171 return;
172 }
173
174 tools::Long nField = pDPObj->GetHeaderDim(aDimPos, nOrient);
175 if ( nField >= 0 )
176 {
177 bDPMouse = false;
178 nDPField = nField;
179 pDragDPObj = pDPObj;
180
181 if (bPopup && DPTestFieldPopupArrow(rMEvt, aPos, aDimPos, pDPObj))
182 {
183 // field name pop up menu has been launched. Don't activate
184 // field move.
185 return;
186 }
187
188 if (bButton)
189 {
190 bDPMouse = true;
191 DPTestMouse( rMEvt, true );
193 }
194 }
195 else if ( pDPObj->IsFilterButton(aPos) )
196 {
197 ReleaseMouse(); // may have been captured in ButtonDown
198
199 ScQueryParam aQueryParam;
200 SCTAB nSrcTab = 0;
201 const ScSheetSourceDesc* pDesc = pDPObj->GetSheetDesc();
202 OSL_ENSURE(pDesc, "no sheet source for filter button");
203 if (pDesc)
204 {
205 aQueryParam = pDesc->GetQueryParam();
206 nSrcTab = pDesc->GetSourceRange().aStart.Tab();
207 }
208
210 aArgSet.Put( ScQueryItem( SCITEM_QUERYDATA, &mrViewData, &aQueryParam ) );
211
213
216 mrViewData.GetViewShell()->GetFrameWeld(), aArgSet, nSrcTab));
217 if ( pDlg->Execute() == RET_OK )
218 {
219 ScSheetSourceDesc aNewDesc(&rDoc);
220 if (pDesc)
221 aNewDesc = *pDesc;
222
223 const ScQueryItem& rQueryItem = pDlg->GetOutputItem();
224 aNewDesc.SetQueryParam(rQueryItem.GetQueryData());
225
226 ScDPObject aNewObj( *pDPObj );
227 aNewObj.SetSheetDesc( aNewDesc );
229 aFunc.DataPilotUpdate( pDPObj, &aNewObj, true, false );
230 mrViewData.GetView()->CursorPosChanged(); // shells may be switched
231 }
232 }
233 }
234 else
235 {
236 OSL_FAIL("Nothing here");
237 }
238}
239
241{
242 bool bLayoutRTL = mrViewData.GetDocument().IsLayoutRTL( mrViewData.GetTabNo() );
243
245 SCTAB nTab = mrViewData.GetTabNo();
246
247 ScDPObject* pDPObj = rDoc.GetDPAtCursor(nCol, nRow, nTab);
248 if (!pDPObj)
249 return;
250
251 if (!pDPObj->GetSaveData()->GetDrillDown())
252 return;
253
254 // Get the geometry of the cell.
255 Point aScrPos = mrViewData.GetScrPos(nCol, nRow, eWhich);
256 tools::Long nSizeX, nSizeY;
257 mrViewData.GetMergeSizePixel(nCol, nRow, nSizeX, nSizeY);
258 Size aScrSize(nSizeX - 1, nSizeY - 1);
259
260 sal_uInt16 nIndent = 0;
261 if (const ScIndentItem* pIndentItem = rDoc.GetAttr(nCol, nRow, nTab, ATTR_INDENT))
262 nIndent = pIndentItem->GetValue();
263
264 // Check if the mouse cursor is clicking on the toggle +/- box.
265 ScDPFieldButton aBtn(GetOutDev(), &GetSettings().GetStyleSettings(), &GetMapMode().GetScaleY());
266 aBtn.setBoundingBox(aScrPos, aScrSize, bLayoutRTL);
267 aBtn.setDrawToggleButton(true, true, nIndent);
268 Point aPopupPos;
269 Size aPopupSize;
270 aBtn.getToggleBoundingBox(aPopupPos, aPopupSize);
271 tools::Rectangle aRect(aPopupPos, aPopupSize);
272 if (aRect.Contains(rMEvt.GetPosPixel()))
273 {
274 // Mouse cursor inside the toggle +/- box.
275 sheet::DataPilotTableHeaderData aData;
276 ScAddress aCellPos(nCol, nRow, nTab);
277 pDPObj->GetHeaderPositionData(aCellPos, aData);
278 ScDPObject aNewObj(*pDPObj);
279 pDPObj->ToggleDetails(aData, &aNewObj);
281 aFunc.DataPilotUpdate(pDPObj, &aNewObj, true, false);
282 }
283}
284
285// Data Pilot interaction
286
287void ScGridWindow::DPTestMouse( const MouseEvent& rMEvt, bool bMove )
288{
289 OSL_ENSURE(pDragDPObj, "pDragDPObj missing");
290
291 // scroll window if at edges
293
294 bool bTimer = false;
295 Point aPixel = rMEvt.GetPosPixel();
296
297 SCCOL nDx = 0;
298 SCROW nDy = 0;
299 if ( aPixel.X() < 0 )
300 nDx = -1;
301 if ( aPixel.Y() < 0 )
302 nDy = -1;
303 Size aSize = GetOutputSizePixel();
304 if ( aPixel.X() >= aSize.Width() )
305 nDx = 1;
306 if ( aPixel.Y() >= aSize.Height() )
307 nDy = 1;
308 if ( nDx != 0 || nDy != 0 )
309 {
311
312 if ( nDx != 0)
314 if ( nDy != 0 )
316
317 bTimer = true;
318 }
319
320 SCCOL nPosX;
321 SCROW nPosY;
322 mrViewData.GetPosFromPixel( aPixel.X(), aPixel.Y(), eWhich, nPosX, nPosY );
323 bool bMouseLeft;
324 bool bMouseTop;
325 mrViewData.GetMouseQuadrant( aPixel, eWhich, nPosX, nPosY, bMouseLeft, bMouseTop );
326
327 ScAddress aPos( nPosX, nPosY, mrViewData.GetTabNo() );
328
329 tools::Rectangle aPosRect;
330 DataPilotFieldOrientation nOrient;
331 tools::Long nDimPos;
332 bool bHasRange = pDragDPObj->GetHeaderDrag( aPos, bMouseLeft, bMouseTop, nDPField,
333 aPosRect, nOrient, nDimPos );
334 UpdateDragRect( bHasRange && bMove, aPosRect );
335
336 bool bIsDataLayout;
337 sal_Int32 nDimFlags = 0;
338 OUString aDimName = pDragDPObj->GetDimName( nDPField, bIsDataLayout, &nDimFlags );
339 bool bAllowed = !bHasRange || ScDPObject::IsOrientationAllowed( nOrient, nDimFlags );
340
341 if (bMove) // set mouse pointer
342 {
343 PointerStyle ePointer = PointerStyle::PivotDelete;
344 if ( !bAllowed )
345 ePointer = PointerStyle::NotAllowed;
346 else if ( bHasRange )
347 switch (nOrient)
348 {
349 case DataPilotFieldOrientation_COLUMN: ePointer = PointerStyle::PivotCol; break;
350 case DataPilotFieldOrientation_ROW: ePointer = PointerStyle::PivotRow; break;
351 case DataPilotFieldOrientation_PAGE:
352 case DataPilotFieldOrientation_DATA: ePointer = PointerStyle::PivotField; break;
353 default: break;
354 }
355 SetPointer( ePointer );
356 }
357 else // execute change
358 {
359 if (!bHasRange)
360 nOrient = DataPilotFieldOrientation_HIDDEN;
361
362 if ( bIsDataLayout && ( nOrient != DataPilotFieldOrientation_COLUMN &&
363 nOrient != DataPilotFieldOrientation_ROW ) )
364 {
365 // removing data layout is not allowed
366 mrViewData.GetView()->ErrorMessage(STR_PIVOT_MOVENOTALLOWED);
367 }
368 else if ( bAllowed )
369 {
370 ScDPSaveData aSaveData( *pDragDPObj->GetSaveData() );
371
372 ScDPSaveDimension* pDim;
373 if ( bIsDataLayout )
374 pDim = aSaveData.GetDataLayoutDimension();
375 else
376 pDim = aSaveData.GetDimensionByName(aDimName);
377 pDim->SetOrientation( nOrient );
378 aSaveData.SetPosition( pDim, nDimPos );
379
381
382 ScDPObject aNewObj( *pDragDPObj );
383 aNewObj.SetSaveData( aSaveData );
385 // when dragging fields, allow re-positioning (bAllowMove)
386 aFunc.DataPilotUpdate( pDragDPObj, &aNewObj, true, false, true );
387 mrViewData.GetView()->CursorPosChanged(); // shells may be switched
388 }
389 }
390
391 if (bTimer && bMove)
392 mrViewData.GetView()->SetTimer( this, rMEvt ); // repeat event
393 else
395}
396
398 const MouseEvent& rMEvt, const ScAddress& rPos, const ScAddress& rDimPos, ScDPObject* pDPObj)
399{
400 bool bLayoutRTL = mrViewData.GetDocument().IsLayoutRTL( mrViewData.GetTabNo() );
402
403 // Get the geometry of the cell.
404 Point aScrPos = mrViewData.GetScrPos(rPos.Col(), rPos.Row(), eWhich);
405 tools::Long nSizeX, nSizeY;
406 mrViewData.GetMergeSizePixel(rPos.Col(), rPos.Row(), nSizeX, nSizeY);
407 Size aScrSize(nSizeX-1, nSizeY-1);
408
409 // Check if the mouse cursor is clicking on the popup arrow box.
410 ScDPFieldButton aBtn(GetOutDev(), &GetSettings().GetStyleSettings(), &GetMapMode().GetScaleY());
411 aBtn.setBoundingBox(aScrPos, aScrSize, bLayoutRTL);
412 aBtn.setPopupLeft(false); // DataPilot popup is always right-aligned for now
413 Point aPopupPos;
414 Size aPopupSize;
415 aBtn.getPopupBoundingBox(aPopupPos, aPopupSize);
416 tools::Rectangle aRect(aPopupPos, aPopupSize);
417 if (aRect.Contains(rMEvt.GetPosPixel()))
418 {
419 // Mouse cursor inside the popup arrow box. Launch the field menu.
420 DPLaunchFieldPopupMenu(bLOK ? aScrPos : OutputToScreenPixel(aScrPos), aScrSize, rDimPos, pDPObj);
421 return true;
422 }
423
424 return false;
425}
426
428 const MouseEvent& rMEvt, const ScAddress& rPos, ScDPObject* pDPObj)
429{
430 bool bLayoutRTL = mrViewData.GetDocument().IsLayoutRTL( mrViewData.GetTabNo() );
432
433 // Get the geometry of the cell.
434 Point aScrPos = mrViewData.GetScrPos(rPos.Col(), rPos.Row(), eWhich);
435 tools::Long nSizeX, nSizeY;
436 mrViewData.GetMergeSizePixel(rPos.Col(), rPos.Row(), nSizeX, nSizeY);
437 Size aScrSize(nSizeX - 1, nSizeY - 1);
438
439 // Check if the mouse cursor is clicking on the popup arrow box.
440 ScDPFieldButton aBtn(GetOutDev(), &GetSettings().GetStyleSettings(), &GetMapMode().GetScaleY());
441 aBtn.setBoundingBox(aScrPos, aScrSize, bLayoutRTL);
442 aBtn.setPopupLeft(false); // DataPilot popup is always right-aligned for now
443 aBtn.setDrawPopupButtonMulti(true);
444 Point aPopupPos;
445 Size aPopupSize;
446 aBtn.getPopupBoundingBox(aPopupPos, aPopupSize);
447 tools::Rectangle aRect(aPopupPos, aPopupSize);
448 if (aRect.Contains(rMEvt.GetPosPixel()))
449 {
450 DataPilotFieldOrientation nOrient;
451 pDPObj->GetHeaderDim(rPos, nOrient);
452 // Mouse cursor inside the popup arrow box. Launch the multi-field menu.
453 DPLaunchMultiFieldPopupMenu(bLOK ? aScrPos : OutputToScreenPixel(aScrPos), aScrSize, pDPObj, nOrient);
454 return true;
455 }
456
457 return false;
458}
459
460namespace {
461
462struct DPFieldPopupData : public ScCheckListMenuControl::ExtendedData
463{
465 ScDPObject* mpDPObj;
466 tools::Long mnDim;
467};
468
469struct DPMultiFieldPopupData : public DPFieldPopupData
470{
471 std::vector<tools::Long> maFieldIndices;
472 std::vector<OUString> maFieldNames;
473};
474
475class DPFieldPopupOKAction : public ScCheckListMenuControl::Action
476{
477public:
478 explicit DPFieldPopupOKAction(ScGridWindow* p) :
479 mpGridWindow(p) {}
480
481 virtual bool execute() override
482 {
483 mpGridWindow->UpdateDPFromFieldPopupMenu();
484 return true;
485 }
486private:
487 VclPtr<ScGridWindow> mpGridWindow;
488};
489
490class DPFieldChangedAction : public ScCheckListMenuControl::Action
491{
492public:
493 explicit DPFieldChangedAction(ScGridWindow* p) :
494 mpGridWindow(p) {}
495
496 virtual bool execute() override
497 {
498 mpGridWindow->UpdateDPPopupMenuForFieldChange();
499 return true;
500 }
501private:
502 VclPtr<ScGridWindow> mpGridWindow;
503};
504
505class PopupSortAction : public ScCheckListMenuControl::Action
506{
507public:
508 enum SortType { ASCENDING, DESCENDING, CUSTOM };
509
510 explicit PopupSortAction(ScDPObject* pDPObject, tools::Long nDimIndex, SortType eType,
511 sal_uInt16 nUserListIndex, ScTabViewShell* pViewShell)
512 : mpDPObject(pDPObject)
513 , mnDimIndex(nDimIndex)
514 , meType(eType)
515 , mnUserListIndex(nUserListIndex)
516 , mpViewShell(pViewShell)
517 {}
518
519 virtual bool execute() override
520 {
521 switch (meType)
522 {
523 case ASCENDING:
524 mpViewShell->DataPilotSort(mpDPObject, mnDimIndex, true);
525 break;
526 case DESCENDING:
527 mpViewShell->DataPilotSort(mpDPObject, mnDimIndex, false);
528 break;
529 case CUSTOM:
530 mpViewShell->DataPilotSort(mpDPObject, mnDimIndex, true, &mnUserListIndex);
531 break;
532 default:
533 ;
534 }
535 return true;
536 }
537
538private:
539 ScDPObject* mpDPObject;
540 tools::Long mnDimIndex;
541 SortType meType;
542 sal_uInt16 mnUserListIndex;
543 ScTabViewShell* mpViewShell;
544};
545
546}
547
548void ScGridWindow::DPLaunchFieldPopupMenu(const Point& rScreenPosition, const Size& rScreenSize,
549 const ScAddress& rAddress, ScDPObject* pDPObject)
550{
551 DataPilotFieldOrientation nOrient;
552 tools::Long nDimIndex = pDPObject->GetHeaderDim(rAddress, nOrient);
553
554 DPLaunchFieldPopupMenu(rScreenPosition, rScreenSize, nDimIndex, pDPObject);
555}
556
558 DPFieldPopupData& rDPData, bool& bDimOrientNotPage)
559{
560 if (!pDPObj)
561 return false;
562
563 rDPData.mnDim = nDimIndex;
564 pDPObj->GetSource();
565
566 bool bIsDataLayout;
567 OUString aDimName = pDPObj->GetDimName(rDPData.mnDim, bIsDataLayout);
568 pDPObj->BuildAllDimensionMembers();
569 const ScDPSaveData* pSaveData = pDPObj->GetSaveData();
570 const ScDPSaveDimension* pDim = pSaveData->GetExistingDimensionByName(aDimName);
571 if (!pDim)
572 // This should never happen.
573 return false;
574
575 bDimOrientNotPage = pDim->GetOrientation() != DataPilotFieldOrientation_PAGE;
576
577 // We need to get the list of field members.
578 pDPObj->FillLabelData(rDPData.mnDim, rDPData.maLabels);
579 rDPData.mpDPObj = pDPObj;
580
581 return true;
582}
583
584void ScGridWindow::DPLaunchMultiFieldPopupMenu(const Point& rScreenPosition, const Size& rScreenSize,
585 ScDPObject* pDPObj, DataPilotFieldOrientation nOrient)
586{
587 if (!pDPObj)
588 return;
589
590 pDPObj->GetSource();
591
592 std::unique_ptr<DPMultiFieldPopupData> pDPData(new DPMultiFieldPopupData);
593 pDPObj->GetFieldIdsNames(nOrient, pDPData->maFieldIndices, pDPData->maFieldNames);
594
595 if (pDPData->maFieldIndices.empty())
596 return;
597
598 tools::Long nDimIndex = pDPData->maFieldIndices[0];
599
600 bool bDimOrientNotPage = true;
601 if (!lcl_FillDPFieldPopupData(nDimIndex, pDPObj, *pDPData, bDimOrientNotPage))
602 return;
603
604 mpDPFieldPopup.reset();
605
606 weld::Window* pPopupParent = GetFrameWeld();
607 mpDPFieldPopup.reset(new ScCheckListMenuControl(pPopupParent, mrViewData,
608 false, -1, true));
609
610 mpDPFieldPopup->addFields(pDPData->maFieldNames);
611 DPSetupFieldPopup(std::move(pDPData), bDimOrientNotPage, pDPObj, true);
612
614
615 if (IsMouseCaptured())
616 ReleaseMouse();
617
618 tools::Rectangle aCellRect(rScreenPosition, rScreenSize);
619 mpDPFieldPopup->launch(pPopupParent, aCellRect);
620}
621
623{
624 // Populate field members.
625 size_t n = rLabelData.maMembers.size();
626 mpDPFieldPopup->setMemberSize(n);
627 for (size_t i = 0; i < n; ++i)
628 {
629 const ScDPLabelData::Member& rMem = rLabelData.maMembers[i];
630 OUString aName = rMem.getDisplayName();
631 if (aName.isEmpty())
632 // Use special string for an empty name.
633 mpDPFieldPopup->addMember(ScResId(STR_EMPTYDATA), 0.0, rMem.mbVisible, false);
634 else
635 mpDPFieldPopup->addMember(rMem.getDisplayName(), 0.0, rMem.mbVisible, false);
636 }
637}
638
639void ScGridWindow::DPSetupFieldPopup(std::unique_ptr<ScCheckListMenuControl::ExtendedData> pDPData,
640 bool bDimOrientNotPage, ScDPObject* pDPObj,
641 bool bMultiField)
642{
643 if (!mpDPFieldPopup || !pDPObj)
644 return;
645
646 const ScDPLabelData& rLabelData = static_cast<DPFieldPopupData*>(pDPData.get())->maLabels;
647 const tools::Long nDimIndex = static_cast<DPFieldPopupData*>(pDPData.get())->mnDim;
648 mpDPFieldPopup->setExtendedData(std::move(pDPData));
649
650 if (bMultiField)
651 mpDPFieldPopup->setFieldChangedAction(new DPFieldChangedAction(this));
652
653 mpDPFieldPopup->setOKAction(new DPFieldPopupOKAction(this));
654 DPPopulateFieldMembers(rLabelData);
655
656 if (bDimOrientNotPage)
657 {
658 vector<OUString> aUserSortNames;
659 ScUserList* pUserList = ScGlobal::GetUserList();
660 if (pUserList)
661 {
662 size_t n = pUserList->size();
663 aUserSortNames.reserve(n);
664 for (size_t i = 0; i < n; ++i)
665 {
666 const ScUserListData& rData = (*pUserList)[i];
667 aUserSortNames.push_back(rData.GetString());
668 }
669 }
670
671 // Populate the menus.
672 ScTabViewShell* pViewShell = mrViewData.GetViewShell();
673 mpDPFieldPopup->addMenuItem(
674 ScResId(STR_MENU_SORT_ASC),
675 new PopupSortAction(pDPObj, nDimIndex, PopupSortAction::ASCENDING, 0, pViewShell));
676 mpDPFieldPopup->addMenuItem(
677 ScResId(STR_MENU_SORT_DESC),
678 new PopupSortAction(pDPObj, nDimIndex, PopupSortAction::DESCENDING, 0, pViewShell));
679
680 ScListSubMenuControl* pSubMenu = mpDPFieldPopup->addSubMenuItem(ScResId(STR_MENU_SORT_CUSTOM), !aUserSortNames.empty(), false);
681 if (pSubMenu)
682 {
683 size_t n = aUserSortNames.size();
684 for (size_t i = 0; i < n; ++i)
685 {
686 pSubMenu->addMenuItem(aUserSortNames[i],
687 new PopupSortAction(pDPObj, nDimIndex, PopupSortAction::CUSTOM, sal_uInt16(i), pViewShell));
688 }
689 pSubMenu->resizeToFitMenuItems();
690 }
691 }
692
693 mpDPFieldPopup->initMembers();
694}
695
697{
698 if (!mpDPFieldPopup)
699 return;
700
702 aConfig.mbAllowEmptySet = false;
704 mpDPFieldPopup->setConfig(aConfig);
705}
706
707void ScGridWindow::DPLaunchFieldPopupMenu(const Point& rScrPos, const Size& rScrSize,
708 tools::Long nDimIndex, ScDPObject* pDPObj)
709{
710 std::unique_ptr<DPFieldPopupData> pDPData(new DPFieldPopupData);
711 bool bDimOrientNotPage = true;
712 if (!lcl_FillDPFieldPopupData(nDimIndex, pDPObj, *pDPData, bDimOrientNotPage))
713 return;
714
715 mpDPFieldPopup.reset();
716
717 vcl::ILibreOfficeKitNotifier* pNotifier = nullptr;
719 pNotifier = SfxViewShell::Current();
720
721 weld::Window* pPopupParent = GetFrameWeld();
722 mpDPFieldPopup.reset(new ScCheckListMenuControl(pPopupParent, mrViewData,
723 false, -1, pNotifier));
724
725 DPSetupFieldPopup(std::move(pDPData), bDimOrientNotPage, pDPObj);
726
728
729 if (IsMouseCaptured())
730 ReleaseMouse();
731
732 tools::Rectangle aCellRect(rScrPos, rScrSize);
733 mpDPFieldPopup->launch(pPopupParent, aCellRect);
734}
735
737{
738 if (!mpDPFieldPopup)
739 return;
740
741 DPMultiFieldPopupData* pDPData = static_cast<DPMultiFieldPopupData*>(mpDPFieldPopup->getExtendedData());
742 if (!pDPData)
743 return;
744
745 if (pDPData->maFieldIndices.empty())
746 return;
747
748 tools::Long nIndex = mpDPFieldPopup->getField();
749 if (nIndex < 0)
750 return;
751
752 tools::Long nDimIndex = pDPData->maFieldIndices[nIndex];
753 if (nDimIndex == pDPData->mnDim)
754 return;
755
756 bool bDimOrientNotPage = true;
757 if (!lcl_FillDPFieldPopupData(nDimIndex, pDPData->mpDPObj, *pDPData, bDimOrientNotPage))
758 return;
759
760 mpDPFieldPopup->clearMembers();
761
762 DPPopulateFieldMembers(pDPData->maLabels);
763
764 mpDPFieldPopup->initMembers();
765}
766
768{
769 typedef std::unordered_map<OUString, OUString> MemNameMapType;
770
771 if (!mpDPFieldPopup)
772 return;
773
774 DPFieldPopupData* pDPData = static_cast<DPFieldPopupData*>(mpDPFieldPopup->getExtendedData());
775 if (!pDPData)
776 return;
777
778 ScDPObject* pDPObj = pDPData->mpDPObj;
779 ScDPSaveData* pSaveData = pDPObj->GetSaveData();
780
781 bool bIsDataLayout;
782 OUString aDimName = pDPObj->GetDimName(pDPData->mnDim, bIsDataLayout);
783 ScDPSaveDimension* pDim = pSaveData->GetDimensionByName(aDimName);
784 if (!pDim)
785 return;
786
787 // Build a map of layout names to original names.
788 const ScDPLabelData& rLabelData = pDPData->maLabels;
789 MemNameMapType aMemNameMap;
790 for (const auto& rMember : rLabelData.maMembers)
791 aMemNameMap.emplace(rMember.maLayoutName, rMember.maName);
792
793 // The raw result may contain a mixture of layout names and original names.
795 mpDPFieldPopup->getResult(aRawResult);
796
797 std::unordered_map<OUString, bool> aResult;
798 for (const auto& rItem : aRawResult)
799 {
800 MemNameMapType::const_iterator itrNameMap = aMemNameMap.find(rItem.aName);
801 if (itrNameMap == aMemNameMap.end())
802 {
803 // This is an original member name. Use it as-is.
804 OUString aName = rItem.aName;
805 if (aName == ScResId(STR_EMPTYDATA))
806 // Translate the special empty name into an empty string.
807 aName.clear();
808
809 aResult.emplace(aName, rItem.bValid);
810 }
811 else
812 {
813 // This is a layout name. Get the original member name and use it.
814 aResult.emplace(itrNameMap->second, rItem.bValid);
815 }
816 }
817 pDim->UpdateMemberVisibility(aResult);
818
820 aFunc.UpdatePivotTable(*pDPObj, true, false);
821}
822
823namespace {
824
825template <typename T>
826inline
827T lcl_getValidValue(T value, T defvalue)
828{
829 return (value <0) ? defvalue : value;
830}
831
832} // anonymous namespace
833
835{
836 ScDocument const& rDoc = mrViewData.GetDocument();
837 SCCOL nPosX = 0;
838 SCROW nPosY = 0;
839 SCCOL nXRight = rDoc.MaxCol();
840 SCROW nYBottom = rDoc.MaxRow();
841
843 {
844 ScTabViewShell* pViewShell = mrViewData.GetViewShell();
845 nPosX = lcl_getValidValue(pViewShell->GetLOKStartHeaderCol(), nPosX);
846 nPosY = lcl_getValidValue(pViewShell->GetLOKStartHeaderRow(), nPosY);
847 nXRight = lcl_getValidValue(pViewShell->GetLOKEndHeaderCol(), nXRight);
848 nYBottom = lcl_getValidValue(pViewShell->GetLOKEndHeaderRow(), nYBottom);
849 }
850 else
851 {
852 nPosX = mrViewData.GetPosX(eHWhich);
853 nPosY = mrViewData.GetPosY(eVWhich);
854 nXRight = nPosX + mrViewData.VisibleCellsX(eHWhich);
855 if (nXRight > rDoc.MaxCol())
856 nXRight = rDoc.MaxCol();
857 nYBottom = nPosY + mrViewData.VisibleCellsY(eVWhich);
858 if (nYBottom > rDoc.MaxRow())
859 nYBottom = rDoc.MaxRow();
860 }
861
862 // Store the current visible range.
863 return maVisibleRange.set(nPosX, nPosY, nXRight, nYBottom);
864}
865
867{
868 DPTestMouse( rMEvt, true );
869}
870
872{
873 bDPMouse = false;
874 ReleaseMouse();
875
876 DPTestMouse( rMEvt, false );
877 SetPointer( PointerStyle::Arrow );
878}
879
880void ScGridWindow::UpdateDragRect( bool bShowRange, const tools::Rectangle& rPosRect )
881{
882 SCCOL nStartX = ( rPosRect.Left() >= 0 ) ? static_cast<SCCOL>(rPosRect.Left()) : SCCOL_MAX;
883 SCROW nStartY = ( rPosRect.Top() >= 0 ) ? static_cast<SCROW>(rPosRect.Top()) : SCROW_MAX;
884 SCCOL nEndX = ( rPosRect.Right() >= 0 ) ? static_cast<SCCOL>(rPosRect.Right()) : SCCOL_MAX;
885 SCROW nEndY = ( rPosRect.Bottom() >= 0 ) ? static_cast<SCROW>(rPosRect.Bottom()) : SCROW_MAX;
886
887 if ( bShowRange == bDragRect && nDragStartX == nStartX && nDragEndX == nEndX &&
888 nDragStartY == nStartY && nDragEndY == nEndY )
889 {
890 return; // everything unchanged
891 }
892
893 if ( bShowRange )
894 {
895 nDragStartX = nStartX;
896 nDragStartY = nStartY;
897 nDragEndX = nEndX;
898 nDragEndY = nEndY;
899 bDragRect = true;
900 }
901 else
902 bDragRect = false;
903
905}
906
907// Page-Break Mode
908
909sal_uInt16 ScGridWindow::HitPageBreak( const Point& rMouse, ScRange* pSource,
910 SCCOLROW* pBreak, SCCOLROW* pPrev )
911{
912 sal_uInt16 nFound = SC_PD_NONE; // 0
913 ScRange aSource;
914 SCCOLROW nBreak = 0;
915 SCCOLROW nPrev = 0;
916
918 if ( pPageData )
919 {
920 bool bHori = false;
921 bool bVert = false;
922 SCCOL nHitX = 0;
923 SCROW nHitY = 0;
924
925 tools::Long nMouseX = rMouse.X();
926 tools::Long nMouseY = rMouse.Y();
927 SCCOL nPosX;
928 SCROW nPosY;
929 mrViewData.GetPosFromPixel( nMouseX, nMouseY, eWhich, nPosX, nPosY );
930 Point aTL = mrViewData.GetScrPos( nPosX, nPosY, eWhich );
931 Point aBR = mrViewData.GetScrPos( nPosX+1, nPosY+1, eWhich );
932
933 // Horizontal more tolerances as for vertical, because there is more space
934 if ( nMouseX <= aTL.X() + 4 )
935 {
936 bHori = true;
937 nHitX = nPosX;
938 }
939 else if ( nMouseX >= aBR.X() - 6 )
940 {
941 bHori = true;
942 nHitX = nPosX+1; // left edge of the next cell
943 }
944 if ( nMouseY <= aTL.Y() + 2 )
945 {
946 bVert = true;
947 nHitY = nPosY;
948 }
949 else if ( nMouseY >= aBR.Y() - 4 )
950 {
951 bVert = true;
952 nHitY = nPosY+1; // upper edge of the next cell
953 }
954
955 if ( bHori || bVert )
956 {
957 sal_uInt16 nCount = sal::static_int_cast<sal_uInt16>( pPageData->GetCount() );
958 for (sal_uInt16 nPos=0; nPos<nCount && !nFound; nPos++)
959 {
960 ScPrintRangeData& rData = pPageData->GetData(nPos);
961 ScRange aRange = rData.GetPrintRange();
962 bool bLHit = ( bHori && nHitX == aRange.aStart.Col() );
963 bool bRHit = ( bHori && nHitX == aRange.aEnd.Col() + 1 );
964 bool bTHit = ( bVert && nHitY == aRange.aStart.Row() );
965 bool bBHit = ( bVert && nHitY == aRange.aEnd.Row() + 1 );
966 bool bInsideH = ( nPosX >= aRange.aStart.Col() && nPosX <= aRange.aEnd.Col() );
967 bool bInsideV = ( nPosY >= aRange.aStart.Row() && nPosY <= aRange.aEnd.Row() );
968
969 if ( bLHit )
970 {
971 if ( bTHit )
972 nFound = SC_PD_RANGE_TL;
973 else if ( bBHit )
974 nFound = SC_PD_RANGE_BL;
975 else if ( bInsideV )
976 nFound = SC_PD_RANGE_L;
977 }
978 else if ( bRHit )
979 {
980 if ( bTHit )
981 nFound = SC_PD_RANGE_TR;
982 else if ( bBHit )
983 nFound = SC_PD_RANGE_BR;
984 else if ( bInsideV )
985 nFound = SC_PD_RANGE_R;
986 }
987 else if ( bTHit && bInsideH )
988 nFound = SC_PD_RANGE_T;
989 else if ( bBHit && bInsideH )
990 nFound = SC_PD_RANGE_B;
991 if (nFound)
992 aSource = aRange;
993
994 // breaks
995
996 if ( bVert && bInsideH && !nFound )
997 {
998 size_t nRowCount = rData.GetPagesY();
999 const SCROW* pRowEnd = rData.GetPageEndY();
1000 for (size_t nRowPos=0; nRowPos+1<nRowCount; nRowPos++)
1001 if ( pRowEnd[nRowPos]+1 == nHitY )
1002 {
1003 nFound = SC_PD_BREAK_V;
1004 aSource = aRange;
1005 nBreak = nHitY;
1006 if ( nRowPos )
1007 nPrev = pRowEnd[nRowPos-1]+1;
1008 else
1009 nPrev = aRange.aStart.Row();
1010 }
1011 }
1012 if ( bHori && bInsideV && !nFound )
1013 {
1014 size_t nColCount = rData.GetPagesX();
1015 const SCCOL* pColEnd = rData.GetPageEndX();
1016 for (size_t nColPos=0; nColPos+1<nColCount; nColPos++)
1017 if ( pColEnd[nColPos]+1 == nHitX )
1018 {
1019 nFound = SC_PD_BREAK_H;
1020 aSource = aRange;
1021 nBreak = nHitX;
1022 if ( nColPos )
1023 nPrev = pColEnd[nColPos-1]+1;
1024 else
1025 nPrev = aRange.aStart.Col();
1026 }
1027 }
1028 }
1029 }
1030 }
1031
1032 if (pSource)
1033 *pSource = aSource; // print break
1034 if (pBreak)
1035 *pBreak = nBreak; // X/Y position of the moved page break
1036 if (pPrev)
1037 *pPrev = nPrev; // X/Y beginning of the page, which is above the break
1038 return nFound;
1039}
1040
1041void ScGridWindow::PagebreakMove( const MouseEvent& rMEvt, bool bUp )
1042{
1045
1046 // Scrolling
1047
1048 bool bTimer = false;
1049 Point aPos = rMEvt.GetPosPixel();
1050 SCCOL nDx = 0;
1051 SCROW nDy = 0;
1052 if ( aPos.X() < 0 ) nDx = -1;
1053 if ( aPos.Y() < 0 ) nDy = -1;
1054 Size aSize = GetOutputSizePixel();
1055 if ( aPos.X() >= aSize.Width() )
1056 nDx = 1;
1057 if ( aPos.Y() >= aSize.Height() )
1058 nDy = 1;
1059 if ( nDx != 0 || nDy != 0 )
1060 {
1061 if ( bPagebreakDrawn ) // invert
1062 {
1063 bPagebreakDrawn = false;
1065 }
1066
1067 if ( nDx != 0 ) mrViewData.GetView()->ScrollX( nDx, WhichH(eWhich) );
1068 if ( nDy != 0 ) mrViewData.GetView()->ScrollY( nDy, WhichV(eWhich) );
1069 bTimer = true;
1070 }
1071
1072 // Switching when fixating (so Scrolling works)
1073
1074 if ( eWhich == mrViewData.GetActivePart() ) //??
1075 {
1077 if ( nDx > 0 )
1078 {
1079 if ( eWhich == SC_SPLIT_TOPLEFT )
1081 else if ( eWhich == SC_SPLIT_BOTTOMLEFT )
1083 }
1084
1086 if ( nDy > 0 )
1087 {
1088 if ( eWhich == SC_SPLIT_TOPLEFT )
1090 else if ( eWhich == SC_SPLIT_TOPRIGHT )
1092 }
1093 }
1094
1095 // from here new
1096
1097 // Searching for a position between the cells (before nPosX / nPosY)
1098 SCCOL nPosX;
1099 SCROW nPosY;
1100 mrViewData.GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
1101 bool bLeft, bTop;
1102 mrViewData.GetMouseQuadrant( aPos, eWhich, nPosX, nPosY, bLeft, bTop );
1103 if ( !bLeft ) ++nPosX;
1104 if ( !bTop ) ++nPosY;
1105
1107 bool bHide = false;
1108 bool bToEnd = false;
1109 ScRange aDrawRange = aPagebreakSource;
1110 if ( bBreak )
1111 {
1113 {
1114 if ( nPosX > aPagebreakSource.aStart.Col() &&
1115 nPosX <= aPagebreakSource.aEnd.Col() + 1 ) // to the end is also allowed
1116 {
1117 bToEnd = ( nPosX == aPagebreakSource.aEnd.Col() + 1 );
1118 aDrawRange.aStart.SetCol( nPosX );
1119 aDrawRange.aEnd.SetCol( nPosX - 1 );
1120 }
1121 else
1122 bHide = true;
1123 }
1124 else
1125 {
1126 if ( nPosY > aPagebreakSource.aStart.Row() &&
1127 nPosY <= aPagebreakSource.aEnd.Row() + 1 ) // to the end is also allowed
1128 {
1129 bToEnd = ( nPosY == aPagebreakSource.aEnd.Row() + 1 );
1130 aDrawRange.aStart.SetRow( nPosY );
1131 aDrawRange.aEnd.SetRow( nPosY - 1 );
1132 }
1133 else
1134 bHide = true;
1135 }
1136 }
1137 else
1138 {
1140 aDrawRange.aStart.SetCol( nPosX );
1142 aDrawRange.aStart.SetRow( nPosY );
1144 {
1145 if ( nPosX > 0 )
1146 aDrawRange.aEnd.SetCol( nPosX-1 );
1147 else
1148 bHide = true;
1149 }
1151 {
1152 if ( nPosY > 0 )
1153 aDrawRange.aEnd.SetRow( nPosY-1 );
1154 else
1155 bHide = true;
1156 }
1157 if ( aDrawRange.aStart.Col() > aDrawRange.aEnd.Col() ||
1158 aDrawRange.aStart.Row() > aDrawRange.aEnd.Row() )
1159 bHide = true;
1160 }
1161
1162 if ( !bPagebreakDrawn || bUp || aDrawRange != aPagebreakDrag )
1163 {
1164 // draw...
1165
1166 if ( bPagebreakDrawn )
1167 {
1168 // invert
1169 bPagebreakDrawn = false;
1170 }
1171 aPagebreakDrag = aDrawRange;
1172 if ( !bUp && !bHide )
1173 {
1174 // revert
1175 bPagebreakDrawn = true;
1176 }
1178 }
1179
1180 // when ButtonUp execute the changes
1181
1182 if ( bUp )
1183 {
1184 ScViewFunc* pViewFunc = mrViewData.GetView();
1185 ScDocShell* pDocSh = mrViewData.GetDocShell();
1186 ScDocument& rDoc = pDocSh->GetDocument();
1187 SCTAB nTab = mrViewData.GetTabNo();
1188 bool bUndo (rDoc.IsUndoEnabled());
1189
1190 if ( bBreak )
1191 {
1192 bool bColumn = ( nPagebreakMouse == SC_PD_BREAK_H );
1193 SCCOLROW nNew = bColumn ? static_cast<SCCOLROW>(nPosX) : static_cast<SCCOLROW>(nPosY);
1194 if ( nNew != nPagebreakBreak )
1195 {
1196 if (bUndo)
1197 {
1198 OUString aUndo = ScResId( STR_UNDO_DRAG_BREAK );
1199 pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo, 0, mrViewData.GetViewShell()->GetViewShellId() );
1200 }
1201
1202 bool bGrow = !bHide && nNew > nPagebreakBreak;
1203 if ( bColumn )
1204 {
1205 if (rDoc.HasColBreak(static_cast<SCCOL>(nPagebreakBreak), nTab) & ScBreakType::Manual)
1206 {
1207 ScAddress aOldAddr( static_cast<SCCOL>(nPagebreakBreak), nPosY, nTab );
1208 pViewFunc->DeletePageBreak( true, true, &aOldAddr, false );
1209 }
1210 if ( !bHide && !bToEnd ) // not at the end
1211 {
1212 ScAddress aNewAddr( static_cast<SCCOL>(nNew), nPosY, nTab );
1213 pViewFunc->InsertPageBreak( true, true, &aNewAddr, false );
1214 }
1215 if ( bGrow )
1216 {
1217 // change last break to hard, and change scaling
1218 bool bManualBreak(rDoc.HasColBreak(static_cast<SCCOL>(nPagebreakPrev), nTab) & ScBreakType::Manual);
1219 if ( static_cast<SCCOL>(nPagebreakPrev) > aPagebreakSource.aStart.Col() && !bManualBreak )
1220 {
1221 ScAddress aPrev( static_cast<SCCOL>(nPagebreakPrev), nPosY, nTab );
1222 pViewFunc->InsertPageBreak( true, true, &aPrev, false );
1223 }
1224
1225 if (!pDocSh->AdjustPrintZoom( ScRange(
1226 static_cast<SCCOL>(nPagebreakPrev),0,nTab, static_cast<SCCOL>(nNew-1),0,nTab ) ))
1227 bGrow = false;
1228 }
1229 }
1230 else
1231 {
1233 {
1234 ScAddress aOldAddr( nPosX, nPagebreakBreak, nTab );
1235 pViewFunc->DeletePageBreak( false, true, &aOldAddr, false );
1236 }
1237 if ( !bHide && !bToEnd ) // not at the end
1238 {
1239 ScAddress aNewAddr( nPosX, nNew, nTab );
1240 pViewFunc->InsertPageBreak( false, true, &aNewAddr, false );
1241 }
1242 if ( bGrow )
1243 {
1244 // change last break to hard, and change scaling
1245 bool bManualBreak(rDoc.HasRowBreak(nPagebreakPrev, nTab) & ScBreakType::Manual);
1246 if ( nPagebreakPrev > aPagebreakSource.aStart.Row() && !bManualBreak )
1247 {
1248 ScAddress aPrev( nPosX, nPagebreakPrev, nTab );
1249 pViewFunc->InsertPageBreak( false, true, &aPrev, false );
1250 }
1251
1252 if (!pDocSh->AdjustPrintZoom( ScRange(
1253 0,nPagebreakPrev,nTab, 0,nNew-1,nTab ) ))
1254 bGrow = false;
1255 }
1256 }
1257
1258 if (bUndo)
1259 {
1260 pDocSh->GetUndoManager()->LeaveListAction();
1261 }
1262
1263 if (!bGrow) // otherwise has already happened in AdjustPrintZoom
1264 {
1265 pViewFunc->UpdatePageBreakData( true );
1266 pDocSh->SetDocumentModified();
1267 }
1268 }
1269 }
1270 else if ( bHide || aPagebreakDrag != aPagebreakSource )
1271 {
1272 // set print range
1273
1274 OUString aNewRanges;
1275 sal_uInt16 nOldCount = rDoc.GetPrintRangeCount( nTab );
1276 if ( nOldCount )
1277 {
1278 for (sal_uInt16 nPos=0; nPos<nOldCount; nPos++)
1279 {
1280 const ScRange* pOld = rDoc.GetPrintRange( nTab, nPos );
1281 if ( pOld )
1282 {
1283 OUString aTemp;
1284 if ( *pOld != aPagebreakSource )
1285 aTemp = pOld->Format(rDoc, ScRefFlags::VALID);
1286 else if ( !bHide )
1288 if (!aTemp.isEmpty())
1289 {
1290 if ( !aNewRanges.isEmpty() )
1291 aNewRanges += ";";
1292 aNewRanges += aTemp;
1293 }
1294 }
1295 }
1296 }
1297 else if (!bHide)
1298 aNewRanges = aPagebreakDrag.Format(rDoc, ScRefFlags::VALID);
1299
1300 pViewFunc->SetPrintRanges( rDoc.IsPrintEntireSheet( nTab ), &aNewRanges, nullptr, nullptr, false );
1301 }
1302 }
1303
1304 // Timer for Scrolling
1305
1306 if (bTimer && !bUp)
1307 mrViewData.GetView()->SetTimer( this, rMEvt ); // repeat event
1308 else
1310}
1311
1312/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const SCCOL SCCOL_MAX
Definition: address.hxx:56
const SCROW SCROW_MAX
Definition: address.hxx:55
const Point & GetPosPixel() const
constexpr tools::Long Y() const
void setX(tools::Long nX)
constexpr tools::Long X() const
virtual VclPtr< AbstractScPivotFilterDlg > CreateScPivotFilterDlg(weld::Window *pParent, const SfxItemSet &rArgSet, sal_uInt16 nSourceTab)=0
static SC_DLLPUBLIC ScAbstractDialogFactory * Create()
Definition: scabstdlg.cxx:37
SCTAB Tab() const
Definition: address.hxx:283
void SetCol(SCCOL nColP)
Definition: address.hxx:291
void IncCol(SCCOL nDelta=1)
Definition: address.hxx:316
SCROW Row() const
Definition: address.hxx:274
void SetRow(SCROW nRowP)
Definition: address.hxx:287
SCCOL Col() const
Definition: address.hxx:279
Action to perform when an event takes place.
This class implements a popup window for the auto filter dropdown.
std::set< ResultEntry > ResultType
bool UpdatePivotTable(ScDPObject &rDPObj, bool bRecord, bool bApi)
Definition: dbdocfun.cxx:1592
bool DataPilotUpdate(ScDPObject *pOldObj, const ScDPObject *pNewObj, bool bRecord, bool bApi, bool bAllowMove=false)
Definition: dbdocfun.cxx:1297
This class takes care of physically drawing field button controls inside data pilot tables.
Definition: dpcontrol.hxx:36
void getToggleBoundingBox(Point &rPos, Size &rSize) const
Definition: dpcontrol.cxx:195
void setPopupLeft(bool b)
Definition: dpcontrol.cxx:103
void setDrawPopupButtonMulti(bool b)
Definition: dpcontrol.cxx:81
void setDrawToggleButton(bool b, bool bCollapse, sal_Int32 nIndent)
Definition: dpcontrol.cxx:86
void setBoundingBox(const Point &rPos, const Size &rSize, bool bLayoutRTL)
Definition: dpcontrol.cxx:60
void getPopupBoundingBox(Point &rPos, Size &rSize) const
Definition: dpcontrol.cxx:167
void GetHeaderPositionData(const ScAddress &rPos, css::sheet::DataPilotTableHeaderData &rData)
Definition: dpobject.cxx:1303
void SetSaveData(const ScDPSaveData &rData)
Definition: dpobject.cxx:387
static bool IsOrientationAllowed(css::sheet::DataPilotFieldOrientation nOrient, sal_Int32 nDimFlags)
Definition: dpobject.cxx:2745
css::uno::Reference< css::sheet::XDimensionsSupplier > const & GetSource()
Definition: dpobject.cxx:516
bool GetHeaderDrag(const ScAddress &rPos, bool bMouseLeft, bool bMouseTop, tools::Long nDragDim, tools::Rectangle &rPosRect, css::sheet::DataPilotFieldOrientation &rOrient, tools::Long &rDimPos)
Definition: dpobject.cxx:1426
tools::Long GetHeaderDim(const ScAddress &rPos, css::sheet::DataPilotFieldOrientation &rOrient)
Definition: dpobject.cxx:1419
void BuildAllDimensionMembers()
Definition: dpobject.cxx:960
bool IsFilterButton(const ScAddress &rPos)
Definition: dpobject.cxx:1412
void SetSheetDesc(const ScSheetSourceDesc &rDesc)
Definition: dpobject.cxx:415
const ScSheetSourceDesc * GetSheetDesc() const
Definition: dpobject.hxx:156
void ToggleDetails(const css::sheet::DataPilotTableHeaderData &rElemDesc, ScDPObject *pDestObj)
Definition: dpobject.cxx:1999
ScDPSaveData * GetSaveData() const
Definition: dpobject.hxx:141
OUString GetDimName(tools::Long nDim, bool &rIsDataLayout, sal_Int32 *pFlags=nullptr)
Definition: dpobject.cxx:1207
void GetFieldIdsNames(css::sheet::DataPilotFieldOrientation nOrient, std::vector< tools::Long > &rIndices, std::vector< OUString > &rNames)
Definition: dpobject.cxx:2485
void FillLabelData(sal_Int32 nDim, ScDPLabelData &Labels)
Definition: dpobject.cxx:2448
SC_DLLPUBLIC ScDPSaveDimension * GetExistingDimensionByName(std::u16string_view rName) const
Definition: dpsave.cxx:849
bool GetDrillDown() const
Definition: dpsave.hxx:343
void SetPosition(ScDPSaveDimension *pDim, tools::Long nNew)
Definition: dpsave.cxx:959
SC_DLLPUBLIC ScDPSaveDimension * GetDataLayoutDimension()
Definition: dpsave.cxx:870
SC_DLLPUBLIC ScDPSaveDimension * GetDimensionByName(const OUString &rName)
Get a dimension object by its name.
Definition: dpsave.cxx:838
void UpdateMemberVisibility(const std::unordered_map< OUString, bool > &rData)
Definition: dpsave.cxx:613
void SetOrientation(css::sheet::DataPilotFieldOrientation nNew)
Definition: dpsave.cxx:319
css::sheet::DataPilotFieldOrientation GetOrientation() const
Definition: dpsave.hxx:202
bool AdjustPrintZoom(const ScRange &rRange)
Definition: docsh4.cxx:1699
void SetDocumentModified()
Definition: docsh.cxx:2982
const ScDocument & GetDocument() const
Definition: docsh.hxx:219
virtual SfxUndoManager * GetUndoManager() override
Definition: docsh.cxx:2968
SC_DLLPUBLIC sal_uInt16 GetRowHeight(SCROW nRow, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4161
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:892
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:893
SC_DLLPUBLIC const ScRange * GetPrintRange(SCTAB nTab, sal_uInt16 nPos)
Definition: document.cxx:6268
SC_DLLPUBLIC ScBreakType HasRowBreak(SCROW nRow, SCTAB nTab) const
Definition: document.cxx:4355
SC_DLLPUBLIC ScBreakType HasColBreak(SCCOL nCol, SCTAB nTab) const
Definition: document.cxx:4369
SC_DLLPUBLIC ScDPObject * GetDPAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Definition: documen3.cxx:377
SC_DLLPUBLIC bool IsLayoutRTL(SCTAB nTab) const
Definition: document.cxx:974
bool IsUndoEnabled() const
Definition: document.hxx:1595
SC_DLLPUBLIC sal_uInt16 GetPrintRangeCount(SCTAB nTab)
Definition: document.cxx:6261
bool IsPrintEntireSheet(SCTAB nTab) const
Returns true, if the specified sheet is always printed.
Definition: document.cxx:6255
SC_DLLPUBLIC const SfxPoolItem * GetAttr(SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt16 nWhich) const
Definition: document.cxx:4684
static SC_DLLPUBLIC ScUserList * GetUserList()
Definition: global.cxx:288
void DPMouseButtonUp(const MouseEvent &rMEvt)
Definition: gridwin2.cxx:871
bool DoPageFieldSelection(SCCOL nCol, SCROW nRow)
Definition: gridwin2.cxx:96
void UpdateDPPopupMenuForFieldChange()
Definition: gridwin2.cxx:736
SCROW nDragStartY
Definition: gridwin.hxx:190
SCCOLROW nPagebreakPrev
Definition: gridwin.hxx:183
css::sheet::DataPilotFieldOrientation GetDPFieldOrientation(SCCOL nCol, SCROW nRow) const
Definition: gridwin2.cxx:56
void DPPopulateFieldMembers(const ScDPLabelData &rLabelData)
Definition: gridwin2.cxx:622
ScDPObject * pDragDPObj
Definition: gridwin.hxx:175
void DPLaunchFieldPopupMenu(const Point &rScrPos, const Size &rScrSize, const ScAddress &rPos, ScDPObject *pDPObj)
Definition: gridwin2.cxx:548
ScHSplitPos eHWhich
Definition: gridwin.hxx:155
SCCOLROW nPagebreakBreak
Definition: gridwin.hxx:182
std::unique_ptr< ScDPFieldButton > mpFilterButton
Definition: gridwin.hxx:163
void DPSetupFieldPopup(std::unique_ptr< ScCheckListMenuControl::ExtendedData > pDPData, bool bDimOrientNotPage, ScDPObject *pDPObj, bool bMultiField=false)
Definition: gridwin2.cxx:639
SCCOL nDragEndX
Definition: gridwin.hxx:191
SCROW nDragEndY
Definition: gridwin.hxx:192
void DPConfigFieldPopup()
Definition: gridwin2.cxx:696
tools::Long nDPField
Definition: gridwin.hxx:174
bool DPTestFieldPopupArrow(const MouseEvent &rMEvt, const ScAddress &rPos, const ScAddress &rDimPos, ScDPObject *pDPObj)
Check if the mouse click is on a field popup button.
Definition: gridwin2.cxx:397
bool DPTestMultiFieldPopupArrow(const MouseEvent &rMEvt, const ScAddress &rPos, ScDPObject *pDPObj)
Definition: gridwin2.cxx:427
void DoPushPivotToggle(SCCOL nCol, SCROW nRow, const MouseEvent &rMEvt)
Definition: gridwin2.cxx:240
void UpdateDragRect(bool bShowRange, const tools::Rectangle &rPosRect)
Definition: gridwin2.cxx:880
SCCOL nDragStartX
Definition: gridwin.hxx:189
ScRange aPagebreakSource
Definition: gridwin.hxx:184
void UpdateDPFromFieldPopupMenu()
Definition: gridwin2.cxx:767
ScRange aPagebreakDrag
Definition: gridwin.hxx:185
ScVSplitPos eVWhich
Definition: gridwin.hxx:156
void UpdateDragRectOverlay()
Definition: gridwin.cxx:6761
void DoPushPivotButton(SCCOL nCol, SCROW nRow, const MouseEvent &rMEvt, bool bButton, bool bPopup, bool bMultiField)
Definition: gridwin2.cxx:151
void LaunchAutoFilterMenu(SCCOL nCol, SCROW nRow)
Definition: gridwin.cxx:937
void DPLaunchMultiFieldPopupMenu(const Point &rScrPos, const Size &rScrSize, ScDPObject *pDPObj, css::sheet::DataPilotFieldOrientation nOrient)
Definition: gridwin2.cxx:584
void PagebreakMove(const MouseEvent &rMEvt, bool bUp)
Definition: gridwin2.cxx:1041
bool bPagebreakDrawn
Definition: gridwin.hxx:215
void DPMouseMove(const MouseEvent &rMEvt)
Definition: gridwin2.cxx:866
std::unique_ptr< ScCheckListMenuControl > mpDPFieldPopup
Definition: gridwin.hxx:162
void LaunchPageFieldMenu(SCCOL nCol, SCROW nRow)
Definition: gridwin.cxx:1327
bool IsAutoFilterActive(SCCOL nCol, SCROW nRow, SCTAB nTab)
Definition: gridwin4.cxx:2306
sal_uInt16 HitPageBreak(const Point &rMouse, ScRange *pSource, SCCOLROW *pBreak, SCCOLROW *pPrev)
Definition: gridwin2.cxx:909
sal_uInt16 nPagebreakMouse
Definition: gridwin.hxx:181
ScViewData & mrViewData
Definition: gridwin.hxx:153
bool bDPMouse
Definition: gridwin.hxx:212
void DPTestMouse(const MouseEvent &rMEvt, bool bMove)
Definition: gridwin2.cxx:287
ScSplitPos eWhich
Definition: gridwin.hxx:154
bool DoAutoFilterButton(SCCOL nCol, SCROW nRow, const MouseEvent &rMEvt)
Definition: gridwin2.cxx:106
bool UpdateVisibleRange()
Definition: gridwin2.cxx:834
VisibleRange maVisibleRange
Definition: gridwin.hxx:138
bool bDragRect
Definition: gridwin.hxx:216
void addMenuItem(const OUString &rText, ScCheckListMenuControl::Action *pAction)
size_t GetCount() const
Definition: pagedata.hxx:73
ScPrintRangeData & GetData(size_t i)
Definition: pagedata.cxx:60
size_t GetPagesX() const
Definition: pagedata.hxx:49
const SCCOL * GetPageEndX() const
Definition: pagedata.hxx:50
const SCROW * GetPageEndY() const
Definition: pagedata.hxx:52
size_t GetPagesY() const
Definition: pagedata.hxx:51
const ScRange & GetPrintRange() const
Definition: pagedata.hxx:44
const ScQueryParam & GetQueryData() const
Definition: uiitems.cxx:215
OUString Format(const ScDocument &rDocument, ScRefFlags nFlags=ScRefFlags::ZERO, const ScAddress::Details &rDetails=ScAddress::detailsOOOa1, bool bFullAddressNotation=false) const
Returns string with formatted cell range from aStart to aEnd, according to provided address conventio...
Definition: address.cxx:2170
ScAddress aEnd
Definition: address.hxx:498
ScAddress aStart
Definition: address.hxx:497
This class contains authoritative information on the internal reference used as the data source for d...
Definition: dpshttab.hxx:40
const ScQueryParam & GetQueryParam() const
Definition: dpshttab.hxx:63
SC_DLLPUBLIC const ScRange & GetSourceRange() const
Get the range that contains the source data.
Definition: dpshttab.cxx:230
void SetQueryParam(const ScQueryParam &rParam)
Definition: dpshttab.cxx:270
void UpdatePageBreakData(bool bForcePaint=false)
Definition: tabview2.cxx:1590
SCROW GetLOKStartHeaderRow() const
Definition: tabview.hxx:619
SCROW GetLOKEndHeaderRow() const
Definition: tabview.hxx:620
void ErrorMessage(TranslateId pGlobStrId)
Definition: tabview2.cxx:1553
SCCOL GetLOKStartHeaderCol() const
Definition: tabview.hxx:621
void ScrollX(tools::Long nDeltaX, ScHSplitPos eWhich, bool bUpdBars=true)
Definition: tabview.cxx:1221
void SetTimer(ScGridWindow *pWin, const MouseEvent &rMEvt)
Definition: tabview.cxx:237
void ActivatePart(ScSplitPos eWhich)
Definition: tabview3.cxx:2907
void ResetTimer()
Definition: tabview.cxx:244
void ScrollY(tools::Long nDeltaY, ScVSplitPos eWhich, bool bUpdBars=true)
Definition: tabview.cxx:1304
void CursorPosChanged()
Definition: tabview3.cxx:626
SCCOL GetLOKEndHeaderCol() const
Definition: tabview.hxx:622
ScPageBreakData * GetPageBreakData()
Definition: tabview.hxx:339
Stores individual user-defined sort list.
Definition: userlist.hxx:32
const OUString & GetString() const
Definition: userlist.hxx:49
Collection of user-defined sort lists.
Definition: userlist.hxx:62
size_t size() const
Definition: userlist.hxx:84
bool GetMergeSizePixel(SCCOL nX, SCROW nY, tools::Long &rSizeXPix, tools::Long &rSizeYPix) const
Definition: viewdata.cxx:2732
void GetMouseQuadrant(const Point &rClickPos, ScSplitPos eWhich, SCCOL nPosX, SCROW nPosY, bool &rLeft, bool &rTop)
Definition: viewdata.cxx:2900
const Fraction & GetZoomY() const
Definition: viewdata.hxx:460
SCTAB GetTabNo() const
Definition: viewdata.hxx:395
ScDocument & GetDocument() const
Definition: viewdata.hxx:380
SCROW GetPosY(ScVSplitPos eWhich, SCTAB nForTab=-1) const
Definition: viewdata.cxx:1417
ScSplitMode GetHSplitMode() const
Definition: viewdata.hxx:416
double GetPPTY() const
Definition: viewdata.hxx:469
ScDocShell * GetDocShell() const
Definition: viewdata.hxx:354
void GetPosFromPixel(tools::Long nClickX, tools::Long nClickY, ScSplitPos eWhich, SCCOL &rPosX, SCROW &rPosY, bool bTestMerge=true, bool bRepair=false, SCTAB nForTab=-1)
Definition: viewdata.cxx:2785
ScTabViewShell * GetViewShell() const
Definition: viewdata.hxx:357
static tools::Long ToPixel(sal_uInt16 nTwips, double nFactor)
Definition: viewdata.hxx:700
ScDBFunc * GetView() const
Definition: viewdata.cxx:864
SCROW VisibleCellsY(ScVSplitPos eWhichY) const
Definition: viewdata.cxx:2717
ScSplitPos GetActivePart() const
Definition: viewdata.hxx:398
Point GetScrPos(SCCOL nWhereX, SCROW nWhereY, ScSplitPos eWhich, bool bAllowNeg=false, SCTAB nForTab=-1) const
Definition: viewdata.cxx:2380
SCCOL VisibleCellsX(ScHSplitPos eWhichX) const
Definition: viewdata.cxx:2712
ScSplitMode GetVSplitMode() const
Definition: viewdata.hxx:417
SCCOL GetPosX(ScHSplitPos eWhich, SCTAB nForTab=-1) const
Definition: viewdata.cxx:1403
SC_DLLPUBLIC void DeletePageBreak(bool bColumn, bool bRecord=true, const ScAddress *pPos=nullptr, bool bSetModified=true)
Definition: viewfun2.cxx:987
void SetPrintRanges(bool bEntireSheet, const OUString *pPrint, const OUString *pRepCol, const OUString *pRepRow, bool bAddPrint)
Definition: viewfun2.cxx:1043
SC_DLLPUBLIC void InsertPageBreak(bool bColumn, bool bRecord=true, const ScAddress *pPos=nullptr, bool bSetModified=true)
Definition: viewfun2.cxx:970
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
SfxItemPool & GetPool() const
size_t LeaveListAction()
virtual void EnterListAction(const OUString &rComment, const OUString &rRepeatComment, sal_uInt16 nId, ViewShellId nViewShellId)
weld::Window * GetFrameWeld() const
ViewShellId GetViewShellId() const override
static SAL_WARN_UNUSED_RESULT SfxViewShell * Current()
constexpr tools::Long Height() const
constexpr tools::Long Width() const
bool Contains(const Point &rPOINT) const
constexpr tools::Long Top() const
constexpr tools::Long Right() const
constexpr tools::Long Left() const
constexpr tools::Long Bottom() const
virtual void SetPointer(PointerStyle) override
Point OutputToScreenPixel(const Point &rPos) const
void StartTracking(StartTrackingFlags nFlags=StartTrackingFlags::NONE)
bool IsMouseCaptured() const
const AllSettings & GetSettings() const
const MapMode & GetMapMode() const
::OutputDevice const * GetOutDev() const
void ReleaseMouse()
Size GetOutputSizePixel() const
weld::Window * GetFrameWeld() const
Any value
int nCount
DocumentType eType
bool lcl_FillDPFieldPopupData(tools::Long nDimIndex, ScDPObject *pDPObj, DPFieldPopupData &rDPData, bool &bDimOrientNotPage)
Definition: gridwin2.cxx:557
#define SC_PD_RANGE_R
Definition: gridwin.hxx:74
#define SC_PD_RANGE_TL
Definition: gridwin.hxx:77
#define SC_PD_RANGE_T
Definition: gridwin.hxx:75
#define SC_PD_RANGE_B
Definition: gridwin.hxx:76
#define SC_PD_RANGE_TR
Definition: gridwin.hxx:78
#define SC_PD_RANGE_L
Definition: gridwin.hxx:73
#define SC_PD_RANGE_BR
Definition: gridwin.hxx:80
#define SC_PD_BREAK_V
Definition: gridwin.hxx:82
#define SC_PD_NONE
Definition: gridwin.hxx:72
#define SC_PD_BREAK_H
Definition: gridwin.hxx:81
#define SC_PD_RANGE_BL
Definition: gridwin.hxx:79
sal_Int32 nIndex
OUString aName
void * p
sal_Int64 n
sal_uInt16 nPos
constexpr OUStringLiteral aData
int i
long Long
uint8_t maLabels[mnMaxStaticSize]
PointerStyle
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:90
constexpr TypedWhichId< ScIndentItem > ATTR_INDENT(131)
#define SCITEM_QUERYDATA
Definition: scitems.hxx:91
Configuration options for this popup window.
Extended data that the client code may need to store.
SC_DLLPUBLIC OUString const & getDisplayName() const
Definition: pivot2.cxx:46
std::vector< Member > maMembers
Definition: pivot.hxx:98
bool set(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
Definition: gridwin.cxx:181
sal_Int32 SCCOLROW
a type capable of holding either SCCOL or SCROW
Definition: types.hxx:23
sal_Int16 SCTAB
Definition: types.hxx:22
sal_Int16 SCCOL
Definition: types.hxx:21
sal_Int32 SCROW
Definition: types.hxx:17
bool bPopup
RET_OK
@ SC_SPLIT_BOTTOMRIGHT
Definition: viewdata.hxx:44
@ SC_SPLIT_TOPLEFT
Definition: viewdata.hxx:44
@ SC_SPLIT_BOTTOMLEFT
Definition: viewdata.hxx:44
@ SC_SPLIT_TOPRIGHT
Definition: viewdata.hxx:44
ScHSplitPos WhichH(ScSplitPos ePos)
Definition: viewdata.hxx:722
@ SC_SPLIT_FIX
Definition: viewdata.hxx:42
ScVSplitPos WhichV(ScSplitPos ePos)
Definition: viewdata.hxx:728
RedlineType meType