29 #include <uiitems.hxx>
31 #include <globstr.hrc>
32 #include <strings.hrc>
43 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
45 #include <unordered_map>
51 using css::sheet::DataPilotFieldOrientation;
57 SCTAB nTab = mrViewData.GetTabNo();
60 return DataPilotFieldOrientation_HIDDEN;
62 DataPilotFieldOrientation nOrient = DataPilotFieldOrientation_HIDDEN;
69 if ( nField >= 0 && nOrient == DataPilotFieldOrientation_PAGE )
71 bool bIsDataLayout =
false;
72 OUString aFieldName = pDPObj->
GetDimName( nField, bIsDataLayout );
73 if ( !aFieldName.isEmpty() && !bIsDataLayout )
74 return DataPilotFieldOrientation_PAGE;
78 nOrient = DataPilotFieldOrientation_HIDDEN;
82 if (nField >= 0 && (nOrient == DataPilotFieldOrientation_COLUMN || nOrient == DataPilotFieldOrientation_ROW) )
84 bool bIsDataLayout =
false;
85 OUString aFieldName = pDPObj->
GetDimName(nField, bIsDataLayout);
86 if (!aFieldName.isEmpty() && !bIsDataLayout)
90 return DataPilotFieldOrientation_HIDDEN;
96 if (GetDPFieldOrientation( nCol, nRow ) == DataPilotFieldOrientation_PAGE)
98 LaunchPageFieldMenu( nCol, nRow );
107 SCTAB nTab = mrViewData.GetTabNo();
108 Point aScrPos = mrViewData.GetScrPos(nCol, nRow, eWhich);
114 aDiffPix.setX( -aDiffPix.X() );
117 mrViewData.GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY );
120 Size aScrSize(nSizeX-1, nSizeY-1);
123 mpFilterButton.reset(
new ScDPFieldButton(
this, &GetSettings().GetStyleSettings(), &mrViewData.GetZoomY(), &rDoc));
124 mpFilterButton->setBoundingBox(aScrPos, aScrSize, bLayoutRTL);
125 mpFilterButton->setPopupLeft(bLayoutRTL);
128 mpFilterButton->getPopupBoundingBox(aPopupPos, aPopupSize);
132 if ( DoPageFieldSelection( nCol, nRow ) )
135 bool bFilterActive = IsAutoFilterActive(nCol, nRow, nTab);
136 mpFilterButton->setHasHiddenMember(bFilterActive);
137 mpFilterButton->setDrawBaseButton(
false);
138 mpFilterButton->setDrawPopupButton(
true);
139 mpFilterButton->setPopupPressed(
true);
140 mpFilterButton->draw();
141 LaunchAutoFilterMenu(nCol, nRow);
151 SCTAB nTab = mrViewData.GetTabNo();
157 DataPilotFieldOrientation nOrient = DataPilotFieldOrientation_HIDDEN;
160 if (!bButton && bPopup && aDimPos.
Col() > 0)
170 if (bPopup && DPTestFieldPopupArrow(rMEvt, aPos, aDimPos, pDPObj))
180 DPTestMouse( rMEvt,
true );
191 OSL_ENSURE(pDesc,
"no sheet source for filter button");
198 SfxItemSet aArgSet( mrViewData.GetViewShell()->GetPool(),
206 mrViewData.GetViewShell()->GetFrameWeld(), aArgSet, nSrcTab));
220 mrViewData.GetView()->CursorPosChanged();
226 OSL_FAIL(
"Nothing here");
234 OSL_ENSURE(pDragDPObj,
"pDragDPObj missing");
244 if ( aPixel.X() < 0 )
246 if ( aPixel.Y() < 0 )
248 Size aSize = GetOutputSizePixel();
249 if ( aPixel.X() >= aSize.
Width() )
251 if ( aPixel.Y() >= aSize.
Height() )
253 if ( nDx != 0 || nDy != 0 )
258 mrViewData.GetView()->ScrollX( nDx,
WhichH(eWhich) );
260 mrViewData.GetView()->ScrollY( nDy,
WhichV(eWhich) );
267 mrViewData.GetPosFromPixel( aPixel.X(), aPixel.Y(), eWhich, nPosX, nPosY );
270 mrViewData.GetMouseQuadrant( aPixel, eWhich, nPosX, nPosY, bMouseLeft, bMouseTop );
272 ScAddress aPos( nPosX, nPosY, mrViewData.GetTabNo() );
275 DataPilotFieldOrientation nOrient;
277 bool bHasRange = pDragDPObj->GetHeaderDrag( aPos, bMouseLeft, bMouseTop, nDPField,
278 aPosRect, nOrient, nDimPos );
279 UpdateDragRect( bHasRange && bMove, aPosRect );
282 sal_Int32 nDimFlags = 0;
283 OUString aDimName = pDragDPObj->GetDimName( nDPField, bIsDataLayout, &nDimFlags );
290 ePointer = PointerStyle::NotAllowed;
291 else if ( bHasRange )
294 case DataPilotFieldOrientation_COLUMN: ePointer = PointerStyle::PivotCol;
break;
295 case DataPilotFieldOrientation_ROW: ePointer = PointerStyle::PivotRow;
break;
296 case DataPilotFieldOrientation_PAGE:
297 case DataPilotFieldOrientation_DATA: ePointer = PointerStyle::PivotField;
break;
300 SetPointer( ePointer );
305 nOrient = DataPilotFieldOrientation_HIDDEN;
307 if ( bIsDataLayout && ( nOrient != DataPilotFieldOrientation_COLUMN &&
308 nOrient != DataPilotFieldOrientation_ROW ) )
311 mrViewData.GetView()->ErrorMessage(STR_PIVOT_MOVENOTALLOWED);
319 pDim = aSaveData.GetDataLayoutDimension();
321 pDim = aSaveData.GetDimensionByName(aDimName);
323 aSaveData.SetPosition( pDim, nDimPos );
332 mrViewData.GetView()->CursorPosChanged();
337 mrViewData.GetView()->SetTimer(
this, rMEvt );
339 mrViewData.GetView()->ResetTimer();
345 bool bLayoutRTL = mrViewData.GetDocument().IsLayoutRTL( mrViewData.GetTabNo() );
348 Point aScrPos = mrViewData.GetScrPos(rPos.
Col(), rPos.
Row(), eWhich);
350 mrViewData.GetMergeSizePixel(rPos.
Col(), rPos.
Row(), nSizeX, nSizeY);
351 Size aScrSize(nSizeX-1, nSizeY-1);
364 DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos), aScrSize, rDimPos, pDPObj);
386 virtual void execute()
override
388 mpGridWindow->UpdateDPFromFieldPopupMenu();
397 enum SortType { ASCENDING, DESCENDING,
CUSTOM };
401 : mpDPObject(pDPObject)
402 , mnDimIndex(nDimIndex)
404 , mnUserListIndex(nUserListIndex)
405 , mpViewShell(pViewShell)
408 virtual void execute()
override
413 mpViewShell->DataPilotSort(mpDPObject, mnDimIndex,
true);
416 mpViewShell->DataPilotSort(mpDPObject, mnDimIndex,
false);
419 mpViewShell->DataPilotSort(mpDPObject, mnDimIndex,
true, &mnUserListIndex);
430 sal_uInt16 mnUserListIndex;
439 DataPilotFieldOrientation nOrient;
442 DPLaunchFieldPopupMenu(rScreenPosition, rScreenSize, nDimIndex, pDPObject);
448 std::unique_ptr<DPFieldPopupData> pDPData(
new DPFieldPopupData);
449 pDPData->mnDim = nDimIndex;
453 OUString aDimName = pDPObj->
GetDimName(pDPData->mnDim, bIsDataLayout);
461 bool bDimOrientNotPage = pDim->
GetOrientation() != DataPilotFieldOrientation_PAGE;
465 pDPData->mpDPObj = pDPObj;
469 mpDPFieldPopup.disposeAndClear();
471 vcl::ILibreOfficeKitNotifier* pNotifier =
nullptr;
476 bDimOrientNotPage,
false, -1,
477 nullptr, pNotifier));
481 rControl.
setOKAction(
new DPFieldPopupOKAction(
this));
486 for (
size_t i = 0;
i < n; ++
i)
498 if (bDimOrientNotPage)
500 vector<OUString> aUserSortNames;
504 size_t n = pUserList->
size();
505 aUserSortNames.reserve(n);
506 for (
size_t i = 0;
i < n; ++
i)
509 aUserSortNames.push_back(rData.
GetString());
517 new PopupSortAction(pDPObj, nDimIndex, PopupSortAction::ASCENDING, 0, pViewShell));
520 new PopupSortAction(pDPObj, nDimIndex, PopupSortAction::DESCENDING, 0, pViewShell));
526 size_t n = aUserSortNames.size();
527 for (
size_t i = 0;
i < n; ++
i)
530 new PopupSortAction(pDPObj, nDimIndex, PopupSortAction::CUSTOM, sal_uInt16(i), pViewShell));
542 aConfig.
mbRTL = mrViewData.GetDocument().IsLayoutRTL(mrViewData.GetTabNo());
544 if (IsMouseCaptured())
546 rControl.
launch(aCellRect);
551 typedef std::unordered_map<OUString, OUString> MemNameMapType;
558 DPFieldPopupData* pDPData =
static_cast<DPFieldPopupData*
>(rControl.
getExtendedData());
566 OUString aDimName = pDPObj->
GetDimName(pDPData->mnDim, bIsDataLayout);
573 MemNameMapType aMemNameMap;
574 for (
const auto& rMember : rLabelData.
maMembers)
575 aMemNameMap.emplace(rMember.maLayoutName, rMember.maName);
581 std::unordered_map<OUString, bool> aResult;
582 for (
const auto& rItem : aRawResult)
584 MemNameMapType::const_iterator itrNameMap = aMemNameMap.find(rItem.aName);
585 if (itrNameMap == aMemNameMap.end())
588 OUString
aName = rItem.aName;
589 if (aName ==
ScResId(STR_EMPTYDATA))
593 aResult.emplace(aName, rItem.bValid);
598 aResult.emplace(itrNameMap->second, rItem.bValid);
609 template <
typename T>
611 T lcl_getValidValue(T value, T defvalue)
613 return (value <0) ? defvalue : value;
620 ScDocument const& rDoc = mrViewData.GetDocument();
636 nPosX = mrViewData.GetPosX(eHWhich);
637 nPosY = mrViewData.GetPosY(eVWhich);
638 nXRight = nPosX + mrViewData.VisibleCellsX(eHWhich);
639 if (nXRight > rDoc.
MaxCol())
641 nYBottom = nPosY + mrViewData.VisibleCellsY(eVWhich);
642 if (nYBottom > rDoc.
MaxRow())
647 return maVisibleRange.set(nPosX, nPosY, nXRight, nYBottom);
652 DPTestMouse( rMEvt,
true );
660 DPTestMouse( rMEvt,
false );
661 SetPointer( PointerStyle::Arrow );
671 if ( bShowRange == bDragRect && nDragStartX == nStartX && nDragEndX == nEndX &&
672 nDragStartY == nStartY && nDragEndY == nEndY )
679 nDragStartX = nStartX;
680 nDragStartY = nStartY;
688 UpdateDragRectOverlay();
713 mrViewData.GetPosFromPixel( nMouseX, nMouseY, eWhich, nPosX, nPosY );
714 Point aTL = mrViewData.GetScrPos( nPosX, nPosY, eWhich );
715 Point aBR = mrViewData.GetScrPos( nPosX+1, nPosY+1, eWhich );
718 if ( nMouseX <= aTL.X() + 4 )
723 else if ( nMouseX >= aBR.X() - 6 )
728 if ( nMouseY <= aTL.Y() + 2 )
733 else if ( nMouseY >= aBR.Y() - 4 )
739 if ( bHori || bVert )
741 sal_uInt16
nCount = sal::static_int_cast<sal_uInt16>( pPageData->
GetCount() );
746 bool bLHit = ( bHori && nHitX == aRange.
aStart.
Col() );
747 bool bRHit = ( bHori && nHitX == aRange.
aEnd.
Col() + 1 );
748 bool bTHit = ( bVert && nHitY == aRange.
aStart.
Row() );
749 bool bBHit = ( bVert && nHitY == aRange.
aEnd.
Row() + 1 );
750 bool bInsideH = ( nPosX >= aRange.
aStart.
Col() && nPosX <= aRange.
aEnd.
Col() );
751 bool bInsideV = ( nPosY >= aRange.
aStart.
Row() && nPosY <= aRange.
aEnd.
Row() );
771 else if ( bTHit && bInsideH )
773 else if ( bBHit && bInsideH )
780 if ( bVert && bInsideH && !nFound )
784 for (
size_t nRowPos=0; nRowPos+1<nRowCount; nRowPos++)
785 if ( pRowEnd[nRowPos]+1 == nHitY )
791 nPrev = pRowEnd[nRowPos-1]+1;
796 if ( bHori && bInsideV && !nFound )
800 for (
size_t nColPos=0; nColPos+1<nColCount; nColPos++)
801 if ( pColEnd[nColPos]+1 == nHitX )
807 nPrev = pColEnd[nColPos-1]+1;
836 if ( aPos.X() < 0 ) nDx = -1;
837 if ( aPos.Y() < 0 ) nDy = -1;
838 Size aSize = GetOutputSizePixel();
839 if ( aPos.X() >= aSize.
Width() )
841 if ( aPos.Y() >= aSize.
Height() )
843 if ( nDx != 0 || nDy != 0 )
845 if ( bPagebreakDrawn )
847 bPagebreakDrawn =
false;
848 UpdateDragRectOverlay();
851 if ( nDx != 0 ) mrViewData.GetView()->ScrollX( nDx,
WhichH(eWhich) );
852 if ( nDy != 0 ) mrViewData.GetView()->ScrollY( nDy,
WhichV(eWhich) );
858 if ( eWhich == mrViewData.GetActivePart() )
884 mrViewData.GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
886 mrViewData.GetMouseQuadrant( aPos, eWhich, nPosX, nPosY, bLeft, bTop );
887 if ( !bLeft ) ++nPosX;
888 if ( !bTop ) ++nPosY;
893 ScRange aDrawRange = aPagebreakSource;
898 if ( nPosX > aPagebreakSource.aStart.Col() &&
899 nPosX <= aPagebreakSource.aEnd.Col() + 1 )
901 bToEnd = ( nPosX == aPagebreakSource.aEnd.Col() + 1 );
910 if ( nPosY > aPagebreakSource.aStart.Row() &&
911 nPosY <= aPagebreakSource.aEnd.Row() + 1 )
913 bToEnd = ( nPosY == aPagebreakSource.aEnd.Row() + 1 );
946 if ( !bPagebreakDrawn || bUp || aDrawRange != aPagebreakDrag )
950 if ( bPagebreakDrawn )
953 bPagebreakDrawn =
false;
955 aPagebreakDrag = aDrawRange;
956 if ( !bUp && !bHide )
959 bPagebreakDrawn =
true;
961 UpdateDragRectOverlay();
969 ScDocShell* pDocSh = mrViewData.GetDocShell();
971 SCTAB nTab = mrViewData.GetTabNo();
977 SCCOLROW nNew = bColumn ?
static_cast<SCCOLROW>(nPosX) : static_cast<SCCOLROW>(nPosY);
978 if ( nNew != nPagebreakBreak )
982 OUString aUndo =
ScResId( STR_UNDO_DRAG_BREAK );
986 bool bGrow = !bHide && nNew > nPagebreakBreak;
991 ScAddress aOldAddr( static_cast<SCCOL>(nPagebreakBreak), nPosY, nTab );
994 if ( !bHide && !bToEnd )
996 ScAddress aNewAddr( static_cast<SCCOL>(nNew), nPosY, nTab );
1003 if ( static_cast<SCCOL>(nPagebreakPrev) > aPagebreakSource.aStart.Col() && !bManualBreak )
1005 ScAddress aPrev( static_cast<SCCOL>(nPagebreakPrev), nPosY, nTab );
1010 static_cast<SCCOL>(nPagebreakPrev),0,nTab, static_cast<SCCOL>(nNew-1),0,nTab ) ))
1018 ScAddress aOldAddr( nPosX, nPagebreakBreak, nTab );
1021 if ( !bHide && !bToEnd )
1023 ScAddress aNewAddr( nPosX, nNew, nTab );
1030 if ( nPagebreakPrev > aPagebreakSource.aStart.Row() && !bManualBreak )
1032 ScAddress aPrev( nPosX, nPagebreakPrev, nTab );
1037 0,nPagebreakPrev,nTab, 0,nNew-1,nTab ) ))
1054 else if ( bHide || aPagebreakDrag != aPagebreakSource )
1058 OUString aNewRanges;
1068 if ( *pOld != aPagebreakSource )
1072 if (!aTemp.isEmpty())
1074 if ( !aNewRanges.isEmpty() )
1076 aNewRanges += aTemp;
1091 mrViewData.GetView()->SetTimer(
this, rMEvt );
1093 mrViewData.GetView()->ResetTimer();
SC_DLLPUBLIC void InsertPageBreak(bool bColumn, bool bRecord=true, const ScAddress *pPos=nullptr, bool bSetModified=true)
SC_DLLPUBLIC ScDPObject * GetDPAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab) const
void DPMouseMove(const MouseEvent &rMEvt)
SCROW GetLOKStartHeaderRow() const
Collection of user-defined sort lists.
ScVSplitPos WhichV(ScSplitPos ePos)
void SetOrientation(css::sheet::DataPilotFieldOrientation nNew)
std::vector< Member > maMembers
void SetPrintRanges(bool bEntireSheet, const OUString *pPrint, const OUString *pRepCol, const OUString *pRepRow, bool bAddPrint)
bool DoAutoFilterButton(SCCOL nCol, SCROW nRow, const MouseEvent &rMEvt)
css::sheet::DataPilotFieldOrientation GetOrientation() const
void UpdateDPFromFieldPopupMenu()
bool DPTestFieldPopupArrow(const MouseEvent &rMEvt, const ScAddress &rPos, const ScAddress &rDimPos, ScDPObject *pDPObj)
Check if the mouse click is on a field popup button.
const SCCOL * GetPageEndX() const
ScHSplitPos WhichH(ScSplitPos ePos)
void FillLabelData(sal_Int32 nDim, ScDPLabelData &Labels)
ScPrintRangeData & GetData(size_t i)
void SetDocumentModified()
const ContentProperties & rData
virtual short Execute()=0
void SetQueryParam(const ScQueryParam &rParam)
SC_DLLPUBLIC ScBreakType HasRowBreak(SCROW nRow, SCTAB nTab) const
SC_DLLPUBLIC sal_uInt16 GetRowHeight(SCROW nRow, SCTAB nTab, bool bHiddenAsZero=true) const
bool UpdatePivotTable(ScDPObject &rDPObj, bool bRecord, bool bApi)
virtual SfxUndoManager * GetUndoManager() override
const SCROW * GetPageEndY() const
SCCOL GetLOKEndHeaderCol() const
bool AdjustPrintZoom(const ScRange &rRange)
static tools::Long ToPixel(sal_uInt16 nTwips, double nFactor)
Stores individual user-defined sort list.
SC_DLLPUBLIC SCROW MaxRow() const
sal_Int32 SCCOLROW
a type capable of holding either SCCOL or SCROW
SCROW GetLOKEndHeaderRow() const
static SfxViewShell * Current()
SC_DLLPUBLIC const ScRange * GetPrintRange(SCTAB nTab, sal_uInt16 nPos)
SC_DLLPUBLIC const ScRange & GetSourceRange() const
Get the range that contains the source data.
void SetSheetDesc(const ScSheetSourceDesc &rDesc)
uint8_t maLabels[mnMaxStaticSize]
bool IsPrintEntireSheet(SCTAB nTab) const
Returns true, if the specified sheet is always printed.
SC_DLLPUBLIC void DeletePageBreak(bool bColumn, bool bRecord=true, const ScAddress *pPos=nullptr, bool bSetModified=true)
void UpdateDragRect(bool bShowRange, const tools::Rectangle &rPosRect)
const ScQueryParam & GetQueryParam() const
SC_DLLPUBLIC OUString const & getDisplayName() const
bool IsFilterButton(const ScAddress &rPos)
SC_DLLPUBLIC SCCOL MaxCol() const
SC_DLLPUBLIC sal_uInt16 GetPrintRangeCount(SCTAB nTab)
void IncCol(SCCOL nDelta=1)
css::uno::Reference< css::sheet::XDimensionsSupplier > const & GetSource()
bool DataPilotUpdate(ScDPObject *pOldObj, const ScDPObject *pNewObj, bool bRecord, bool bApi, bool bAllowMove=false)
void SetSaveData(const ScDPSaveData &rData)
SC_DLLPUBLIC 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...
const ScRange & GetPrintRange() const
void DPMouseButtonUp(const MouseEvent &rMEvt)
tools::Long Width() const
bool DoPageFieldSelection(SCCOL nCol, SCROW nRow)
OUString ScResId(const char *pId)
const OUString & GetString() const
static SC_DLLPUBLIC ScUserList * GetUserList()
void PagebreakMove(const MouseEvent &rMEvt, bool bUp)
ScDPSaveData * GetSaveData() const
const ScQueryParam & GetQueryData() const
SC_DLLPUBLIC ScDPSaveDimension * GetExistingDimensionByName(std::u16string_view rName) const
void DPTestMouse(const MouseEvent &rMEvt, bool bMove)
bool UpdateVisibleRange()
SfxViewShell * GetViewShell() const
OUString GetDimName(tools::Long nDim, bool &rIsDataLayout, sal_Int32 *pFlags=nullptr)
static bool IsOrientationAllowed(css::sheet::DataPilotFieldOrientation nOrient, sal_Int32 nDimFlags)
virtual const ScQueryItem & GetOutputItem()=0
void UpdateMemberVisibility(const std::unordered_map< OUString, bool > &rData)
SC_DLLPUBLIC ScBreakType HasColBreak(SCCOL nCol, SCTAB nTab) const
static SC_DLLPUBLIC ScAbstractDialogFactory * Create()
const ScSheetSourceDesc * GetSheetDesc() const
tools::Long Height() const
virtual void EnterListAction(const OUString &rComment, const OUString &rRepeatComment, sal_uInt16 nId, ViewShellId nViewShellId)
const ScDocument & GetDocument() const
css::sheet::DataPilotFieldOrientation GetDPFieldOrientation(SCCOL nCol, SCROW nRow) const
SCCOL GetLOKStartHeaderCol() const
const Point & GetPosPixel() const
void DoPushPivotButton(SCCOL nCol, SCROW nRow, const MouseEvent &rMEvt, bool bButton, bool bPopup)
SC_DLLPUBLIC bool IsLayoutRTL(SCTAB nTab) const
virtual VclPtr< AbstractScPivotFilterDlg > CreateScPivotFilterDlg(weld::Window *pParent, const SfxItemSet &rArgSet, sal_uInt16 nSourceTab)=0
bool IsUndoEnabled() const
void DPLaunchFieldPopupMenu(const Point &rScrPos, const Size &rScrSize, const ScAddress &rPos, ScDPObject *pDPObj)
void BuildAllDimensionMembers()
This class contains authoritative information on the internal reference used as the data source for d...
SC_DLLPUBLIC ScDPSaveDimension * GetDimensionByName(const OUString &rName)
Get a dimension object by its name.
void UpdatePageBreakData(bool bForcePaint=false)
tools::Long GetHeaderDim(const ScAddress &rPos, css::sheet::DataPilotFieldOrientation &rOrient)
sal_uInt16 HitPageBreak(const Point &rMouse, ScRange *pSource, SCCOLROW *pBreak, SCCOLROW *pPrev)