diff options
Diffstat (limited to 'sc/source/ui/view/gridwin5.cxx')
-rw-r--r-- | sc/source/ui/view/gridwin5.cxx | 393 |
1 files changed, 393 insertions, 0 deletions
diff --git a/sc/source/ui/view/gridwin5.cxx b/sc/source/ui/view/gridwin5.cxx new file mode 100644 index 000000000..0d54b0747 --- /dev/null +++ b/sc/source/ui/view/gridwin5.cxx @@ -0,0 +1,393 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <editeng/flditem.hxx> + +#include <svx/fmpage.hxx> +#include <svx/svdobj.hxx> +#include <svx/svdpagv.hxx> +#include <svx/ImageMapInfo.hxx> +#include <vcl/imapobj.hxx> +#include <vcl/help.hxx> +#include <tools/urlobj.hxx> +#include <sfx2/sfxhelp.hxx> + +#include <AccessibleDocument.hxx> +#include <com/sun/star/accessibility/XAccessible.hpp> + +#include <gridwin.hxx> +#include <viewdata.hxx> +#include <drawview.hxx> +#include <drwlayer.hxx> +#include <document.hxx> +#include <notemark.hxx> +#include <chgtrack.hxx> +#include <chgviset.hxx> +#include <dbfunc.hxx> +#include <userdat.hxx> +#include <postit.hxx> +#include <global.hxx> + +bool ScGridWindow::ShowNoteMarker( SCCOL nPosX, SCROW nPosY, bool bKeyboard ) +{ + bool bDone = false; + + ScDocument* pDoc = pViewData->GetDocument(); + SCTAB nTab = pViewData->GetTabNo(); + ScAddress aCellPos( nPosX, nPosY, nTab ); + + OUString aTrackText; + bool bLeftEdge = false; + + // change tracking + + ScChangeTrack* pTrack = pDoc->GetChangeTrack(); + ScChangeViewSettings* pSettings = pDoc->GetChangeViewSettings(); + if ( pTrack && pTrack->GetFirst() && pSettings && pSettings->ShowChanges()) + { + const ScChangeAction* pFound = nullptr; + const ScChangeAction* pFoundContent = nullptr; + const ScChangeAction* pFoundMove = nullptr; + const ScChangeAction* pAction = pTrack->GetFirst(); + while (pAction) + { + if ( pAction->IsVisible() && + ScViewUtil::IsActionShown( *pAction, *pSettings, *pDoc ) ) + { + ScChangeActionType eType = pAction->GetType(); + const ScBigRange& rBig = pAction->GetBigRange(); + if ( rBig.aStart.Tab() == nTab ) + { + ScRange aRange = rBig.MakeRange(); + + if ( eType == SC_CAT_DELETE_ROWS ) + aRange.aEnd.SetRow( aRange.aStart.Row() ); + else if ( eType == SC_CAT_DELETE_COLS ) + aRange.aEnd.SetCol( aRange.aStart.Col() ); + + if ( aRange.In( aCellPos ) ) + { + pFound = pAction; // the last one wins + switch ( eType ) + { + case SC_CAT_CONTENT : + pFoundContent = pAction; + break; + case SC_CAT_MOVE : + pFoundMove = pAction; + break; + default: + { + // added to avoid warnings + } + } + } + } + if ( eType == SC_CAT_MOVE ) + { + ScRange aRange = + static_cast<const ScChangeActionMove*>(pAction)-> + GetFromRange().MakeRange(); + if ( aRange.In( aCellPos ) ) + { + pFound = pAction; + } + } + } + pAction = pAction->GetNext(); + } + + if ( pFound ) + { + if ( pFoundContent && pFound->GetType() != SC_CAT_CONTENT ) + pFound = pFoundContent; // content wins + if ( pFoundMove && pFound->GetType() != SC_CAT_MOVE && + pFoundMove->GetActionNumber() > + pFound->GetActionNumber() ) + pFound = pFoundMove; // move wins + + // for deleted columns: Arrow on the left side of the cell + if ( pFound->GetType() == SC_CAT_DELETE_COLS ) + bLeftEdge = true; + + DateTime aDT = pFound->GetDateTime(); + aTrackText = pFound->GetUser() + + ", " + + ScGlobal::getLocaleDataPtr()->getDate(aDT) + + " " + + ScGlobal::getLocaleDataPtr()->getTime(aDT) + + ":\n"; + OUString aComStr=pFound->GetComment(); + if(!aComStr.isEmpty()) + { + aTrackText += aComStr + "\n( "; + } + OUString aTmp; + pFound->GetDescription(aTmp, pDoc); + aTrackText += aTmp; + if(!aComStr.isEmpty()) + { + aTrackText += ")"; + } + } + } + + // Note, only if it is not already displayed on the Drawing Layer: + const ScPostIt* pNote = pDoc->GetNote( aCellPos ); + if ( (!aTrackText.isEmpty()) || (pNote && !pNote->IsCaptionShown()) ) + { + bool bNew = true; + bool bFast = false; + if (mpNoteMarker) // A note already shown + { + if (mpNoteMarker->GetDocPos() == aCellPos) + bNew = false; // then stop + else + bFast = true; // otherwise, at once + + // marker which was shown for ctrl-F1 isn't removed by mouse events + if (mpNoteMarker->IsByKeyboard() && !bKeyboard) + bNew = false; + } + if (bNew) + { + if (bKeyboard) + bFast = true; // keyboard also shows the marker immediately + + mpNoteMarker.reset(); + + bool bHSplit = pViewData->GetHSplitMode() != SC_SPLIT_NONE; + bool bVSplit = pViewData->GetVSplitMode() != SC_SPLIT_NONE; + + vcl::Window* pLeft = pViewData->GetView()->GetWindowByPos( bVSplit ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT ); + vcl::Window* pRight = bHSplit ? pViewData->GetView()->GetWindowByPos( bVSplit ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT ) : nullptr; + vcl::Window* pBottom = bVSplit ? pViewData->GetView()->GetWindowByPos( SC_SPLIT_BOTTOMLEFT ) : nullptr; + vcl::Window* pDiagonal = (bHSplit && bVSplit) ? pViewData->GetView()->GetWindowByPos( SC_SPLIT_BOTTOMRIGHT ) : nullptr; + OSL_ENSURE( pLeft, "ScGridWindow::ShowNoteMarker - missing top-left grid window" ); + + /* If caption is shown from right or bottom windows, adjust + mapmode to include size of top-left window. */ + MapMode aMapMode = GetDrawMapMode( true ); + Size aLeftSize = pLeft->PixelToLogic( pLeft->GetOutputSizePixel(), aMapMode ); + Point aOrigin = aMapMode.GetOrigin(); + if( (this == pRight) || (this == pDiagonal) ) + aOrigin.AdjustX(aLeftSize.Width() ); + if( (this == pBottom) || (this == pDiagonal) ) + aOrigin.AdjustY(aLeftSize.Height() ); + aMapMode.SetOrigin( aOrigin ); + + mpNoteMarker.reset(new ScNoteMarker(pLeft, pRight, pBottom, pDiagonal, + pDoc, aCellPos, aTrackText, + aMapMode, bLeftEdge, bFast, bKeyboard)); + } + + bDone = true; // something is shown (old or new) + } + + return bDone; +} + +void ScGridWindow::RequestHelp(const HelpEvent& rHEvt) +{ + bool bDone = false; + bool bHelpEnabled = bool(rHEvt.GetMode() & ( HelpEventMode::BALLOON | HelpEventMode::QUICK )); + SdrView* pDrView = pViewData->GetScDrawView(); + bool bDrawTextEdit = false; + if (pDrView) + bDrawTextEdit = pDrView->IsTextEdit(); + // notes or change tracking + if ( bHelpEnabled && !bDrawTextEdit ) + { + Point aPosPixel = ScreenToOutputPixel( rHEvt.GetMousePosPixel() ); + SCCOL nPosX; + SCROW nPosY; + pViewData->GetPosFromPixel( aPosPixel.X(), aPosPixel.Y(), eWhich, nPosX, nPosY ); + + if ( ShowNoteMarker( nPosX, nPosY, false ) ) + { + Window::RequestHelp( rHEvt ); // turn off old Tip/Balloon + bDone = true; + } + } + + if (!bDone && mpNoteMarker) + { + if (mpNoteMarker->IsByKeyboard()) + { + // marker which was shown for ctrl-F1 isn't removed by mouse events + } + else + { + mpNoteMarker.reset(); + } + } + + // Image-Map / Text-URL + + if ( bHelpEnabled && !bDone && !nButtonDown ) // only without pressed button + { + OUString aHelpText; + tools::Rectangle aPixRect; + Point aPosPixel = ScreenToOutputPixel( rHEvt.GetMousePosPixel() ); + + if ( pDrView ) // URL / Image-Map + { + SdrViewEvent aVEvt; + MouseEvent aMEvt( aPosPixel, 1, MouseEventModifiers::NONE, MOUSE_LEFT ); + SdrHitKind eHit = pDrView->PickAnything( aMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt ); + + if ( eHit != SdrHitKind::NONE && aVEvt.pObj != nullptr ) + { + // URL for IMapObject below Pointer is help text + if ( SvxIMapInfo::GetIMapInfo( aVEvt.pObj ) ) + { + Point aLogicPos = PixelToLogic( aPosPixel ); + IMapObject* pIMapObj = SvxIMapInfo::GetHitIMapObject( + aVEvt.pObj, aLogicPos, this ); + + if ( pIMapObj ) + { + // For image maps show the description, if available + aHelpText = pIMapObj->GetAltText(); + if (aHelpText.isEmpty()) + aHelpText = SfxHelp::GetURLHelpText(pIMapObj->GetURL()); + aPixRect = LogicToPixel(aVEvt.pObj->GetLogicRect()); + } + } + // URL in shape text or at shape itself (URL in text overrides object URL) + if ( aHelpText.isEmpty() ) + { + if( aVEvt.eEvent == SdrEventKind::ExecuteUrl ) + { + aHelpText = SfxHelp::GetURLHelpText(aVEvt.pURLField->GetURL()); + aPixRect = LogicToPixel(aVEvt.pObj->GetLogicRect()); + } + else + { + SdrPageView* pPV = nullptr; + Point aMDPos = PixelToLogic( aPosPixel ); + SdrObject* pObj = pDrView->PickObj(aMDPos, pDrView->getHitTolLog(), pPV, SdrSearchOptions::ALSOONMASTER); + if (pObj) + { + if ( pObj->IsGroupObject() ) + { + SdrObject* pHit = pDrView->PickObj(aMDPos, pDrView->getHitTolLog(), pPV, SdrSearchOptions::DEEP); + if (pHit) + pObj = pHit; + } + ScMacroInfo* pInfo = ScDrawLayer::GetMacroInfo( pObj ); + if ( pInfo && (pInfo->GetHlink().getLength() > 0) ) + { + aPixRect = LogicToPixel(aVEvt.pObj->GetLogicRect()); + aHelpText = SfxHelp::GetURLHelpText(pInfo->GetHlink()); + } + } + } + } + } + } + + if ( aHelpText.isEmpty() ) // Text-URL + { + OUString aUrl; + if ( GetEditUrl( aPosPixel, nullptr, &aUrl ) ) + { + aHelpText = SfxHelp::GetURLHelpText( + INetURLObject::decode(aUrl, INetURLObject::DecodeMechanism::Unambiguous)); + + ScDocument* pDoc = pViewData->GetDocument(); + SCCOL nPosX; + SCROW nPosY; + SCTAB nTab = pViewData->GetTabNo(); + pViewData->GetPosFromPixel( aPosPixel.X(), aPosPixel.Y(), eWhich, nPosX, nPosY ); + const ScPatternAttr* pPattern = pDoc->GetPattern( nPosX, nPosY, nTab ); + + // bForceToTop = sal_False, use the cell's real position + aPixRect = pViewData->GetEditArea( eWhich, nPosX, nPosY, this, pPattern, false ); + } + } + + if ( !aHelpText.isEmpty() ) + { + tools::Rectangle aScreenRect(OutputToScreenPixel(aPixRect.TopLeft()), + OutputToScreenPixel(aPixRect.BottomRight())); + + if ( rHEvt.GetMode() & HelpEventMode::BALLOON ) + Help::ShowBalloon(this,rHEvt.GetMousePosPixel(), aScreenRect, aHelpText); + else if ( rHEvt.GetMode() & HelpEventMode::QUICK ) + Help::ShowQuickHelp(this,aScreenRect, aHelpText); + + bDone = true; + } + } + + // basic controls + + if ( pDrView && bHelpEnabled && !bDone ) + { + SdrPageView* pPV = pDrView->GetSdrPageView(); + OSL_ENSURE( pPV, "SdrPageView* is NULL" ); + if (pPV) + bDone = FmFormPage::RequestHelp( this, pDrView, rHEvt ); + } + + // If QuickHelp for AutoFill is shown, do not allow it to be removed + + if ( nMouseStatus == SC_GM_TABDOWN && pViewData->GetRefType() == SC_REFTYPE_FILL && + Help::IsQuickHelpEnabled() ) + bDone = true; + + if (!bDone) + Window::RequestHelp( rHEvt ); +} + +bool ScGridWindow::IsMyModel(const SdrEditView* pSdrView) +{ + return pSdrView && + pSdrView->GetModel() == pViewData->GetDocument()->GetDrawLayer(); +} + +void ScGridWindow::HideNoteMarker() +{ + mpNoteMarker.reset(); +} + +css::uno::Reference< css::accessibility::XAccessible > + ScGridWindow::CreateAccessible() +{ + css::uno::Reference< css::accessibility::XAccessible > xAcc= GetAccessible(false); + if (xAcc.is()) + { + return xAcc; + } + + ScAccessibleDocument* pAccessibleDocument = + new ScAccessibleDocument(GetAccessibleParentWindow()->GetAccessible(), + pViewData->GetViewShell(), eWhich); + pAccessibleDocument->PreInit(); + + xAcc = pAccessibleDocument; + SetAccessible(xAcc); + + pAccessibleDocument->Init(); + + return xAcc; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |