tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / ui / view / gridwin5.cxx
blob5d6a8d78bfd8da50439ae60499ee9e6f716f9a46
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <editeng/flditem.hxx>
22 #include <svx/fmpage.hxx>
23 #include <svx/svdobj.hxx>
24 #include <svx/svdpagv.hxx>
25 #include <svx/ImageMapInfo.hxx>
26 #include <vcl/imapobj.hxx>
27 #include <vcl/help.hxx>
28 #include <tools/urlobj.hxx>
29 #include <sfx2/sfxhelp.hxx>
31 #include <AccessibleDocument.hxx>
32 #include <com/sun/star/accessibility/XAccessible.hpp>
34 #include <gridwin.hxx>
35 #include <viewdata.hxx>
36 #include <drawview.hxx>
37 #include <drwlayer.hxx>
38 #include <document.hxx>
39 #include <notemark.hxx>
40 #include <chgtrack.hxx>
41 #include <chgviset.hxx>
42 #include <dbfunc.hxx>
43 #include <postit.hxx>
44 #include <global.hxx>
46 bool ScGridWindow::ShowNoteMarker( SCCOL nPosX, SCROW nPosY, bool bKeyboard )
48 bool bDone = false;
50 ScDocument& rDoc = mrViewData.GetDocument();
51 SCTAB nTab = mrViewData.GetTabNo();
52 ScAddress aCellPos( nPosX, nPosY, nTab );
54 OUString aTrackText;
55 bool bLeftEdge = false;
57 // change tracking
59 ScChangeTrack* pTrack = rDoc.GetChangeTrack();
60 ScChangeViewSettings* pSettings = rDoc.GetChangeViewSettings();
61 if ( pTrack && pTrack->GetFirst() && pSettings && pSettings->ShowChanges())
63 const ScChangeAction* pFound = nullptr;
64 const ScChangeAction* pFoundContent = nullptr;
65 const ScChangeAction* pFoundMove = nullptr;
66 const ScChangeAction* pAction = pTrack->GetFirst();
67 while (pAction)
69 if ( pAction->IsVisible() &&
70 ScViewUtil::IsActionShown( *pAction, *pSettings, rDoc ) )
72 ScChangeActionType eType = pAction->GetType();
73 const ScBigRange& rBig = pAction->GetBigRange();
74 if ( rBig.aStart.Tab() == nTab )
76 ScRange aRange = rBig.MakeRange( rDoc );
78 if ( eType == SC_CAT_DELETE_ROWS )
79 aRange.aEnd.SetRow( aRange.aStart.Row() );
80 else if ( eType == SC_CAT_DELETE_COLS )
81 aRange.aEnd.SetCol( aRange.aStart.Col() );
83 if ( aRange.Contains( aCellPos ) )
85 pFound = pAction; // the last one wins
86 switch ( eType )
88 case SC_CAT_CONTENT :
89 pFoundContent = pAction;
90 break;
91 case SC_CAT_MOVE :
92 pFoundMove = pAction;
93 break;
94 default:
96 // added to avoid warnings
101 if ( eType == SC_CAT_MOVE )
103 ScRange aRange =
104 static_cast<const ScChangeActionMove*>(pAction)->
105 GetFromRange().MakeRange( rDoc );
106 if ( aRange.Contains( aCellPos ) )
108 pFound = pAction;
112 pAction = pAction->GetNext();
115 if ( pFound )
117 if ( pFoundContent && pFound->GetType() != SC_CAT_CONTENT )
118 pFound = pFoundContent; // content wins
119 if ( pFoundMove && pFound->GetType() != SC_CAT_MOVE &&
120 pFoundMove->GetActionNumber() >
121 pFound->GetActionNumber() )
122 pFound = pFoundMove; // move wins
124 // for deleted columns: Arrow on the left side of the cell
125 if ( pFound->GetType() == SC_CAT_DELETE_COLS )
126 bLeftEdge = true;
128 DateTime aDT = pFound->GetDateTime();
129 aTrackText = pFound->GetUser()
130 + ", "
131 + ScGlobal::getLocaleData().getDate(aDT)
132 + " "
133 + ScGlobal::getLocaleData().getTime(aDT)
134 + ":\n";
135 OUString aComStr=pFound->GetComment();
136 if(!aComStr.isEmpty())
138 aTrackText += aComStr + "\n( ";
140 OUString aTmp = pFound->GetDescription(rDoc);
141 aTrackText += aTmp;
142 if(!aComStr.isEmpty())
144 aTrackText += ")";
149 // Note, only if it is not already displayed on the Drawing Layer:
150 const ScPostIt* pNote = rDoc.GetNote( aCellPos );
151 if ( (!aTrackText.isEmpty()) || (pNote && !pNote->IsCaptionShown()) )
153 bool bNew = true;
154 bool bFast = false;
155 if (mpNoteMarker) // A note already shown
157 if (mpNoteMarker->GetDocPos() == aCellPos)
158 bNew = false; // then stop
159 else
160 bFast = true; // otherwise, at once
162 // marker which was shown for ctrl-F1 isn't removed by mouse events
163 if (mpNoteMarker->IsByKeyboard() && !bKeyboard)
164 bNew = false;
166 if (bNew)
168 if (bKeyboard)
169 bFast = true; // keyboard also shows the marker immediately
171 mpNoteMarker.reset();
173 bool bHSplit = mrViewData.GetHSplitMode() != SC_SPLIT_NONE;
174 bool bVSplit = mrViewData.GetVSplitMode() != SC_SPLIT_NONE;
176 vcl::Window* pLeft = mrViewData.GetView()->GetWindowByPos( bVSplit ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT );
177 vcl::Window* pRight = bHSplit ? mrViewData.GetView()->GetWindowByPos( bVSplit ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT ) : nullptr;
178 vcl::Window* pBottom = bVSplit ? mrViewData.GetView()->GetWindowByPos( SC_SPLIT_BOTTOMLEFT ) : nullptr;
179 vcl::Window* pDiagonal = (bHSplit && bVSplit) ? mrViewData.GetView()->GetWindowByPos( SC_SPLIT_BOTTOMRIGHT ) : nullptr;
180 assert(pLeft && "ScGridWindow::ShowNoteMarker - missing top-left grid window");
182 /* If caption is shown from right or bottom windows, adjust
183 mapmode to include size of top-left window. */
184 MapMode aMapMode = GetDrawMapMode( true );
185 Size aLeftSize = pLeft->PixelToLogic( pLeft->GetOutputSizePixel(), aMapMode );
186 Point aOrigin = aMapMode.GetOrigin();
187 if( (this == pRight) || (this == pDiagonal) )
188 aOrigin.AdjustX(aLeftSize.Width() );
189 if( (this == pBottom) || (this == pDiagonal) )
190 aOrigin.AdjustY(aLeftSize.Height() );
191 aMapMode.SetOrigin( aOrigin );
193 mpNoteMarker.reset(new ScNoteMarker(pLeft, pRight, pBottom, pDiagonal,
194 &rDoc, aCellPos, aTrackText,
195 aMapMode, bLeftEdge, bFast, bKeyboard));
198 bDone = true; // something is shown (old or new)
201 return bDone;
204 void ScGridWindow::RequestHelp(const HelpEvent& rHEvt)
206 bool bDone = false;
207 OUString aFormulaText;
208 tools::Rectangle aFormulaPixRect;
209 bool bHelpEnabled = bool(rHEvt.GetMode() & ( HelpEventMode::BALLOON | HelpEventMode::QUICK ));
210 SdrView* pDrView = mrViewData.GetScDrawView();
211 bool bDrawTextEdit = false;
212 if (pDrView)
213 bDrawTextEdit = pDrView->IsTextEdit();
214 // notes or change tracking
215 if ( bHelpEnabled && !bDrawTextEdit )
217 Point aPosPixel = ScreenToOutputPixel( rHEvt.GetMousePosPixel() );
218 SCCOL nPosX;
219 SCROW nPosY;
220 ScDocument& rDoc = mrViewData.GetDocument();
221 SCTAB nTab = mrViewData.GetTabNo();
222 const ScViewOptions& rOpts = mrViewData.GetOptions();
223 mrViewData.GetPosFromPixel( aPosPixel.X(), aPosPixel.Y(), eWhich, nPosX, nPosY );
225 if ( ShowNoteMarker( nPosX, nPosY, false ) )
227 Window::RequestHelp( rHEvt ); // turn off old Tip/Balloon
228 bDone = true;
231 if ( rOpts.GetOption( VOPT_FORMULAS_MARKS ) )
233 aFormulaText = rDoc.GetFormula( nPosX, nPosY, nTab );
234 if ( !aFormulaText.isEmpty() ) {
235 const ScPatternAttr* pPattern = rDoc.GetPattern( nPosX, nPosY, nTab );
236 aFormulaPixRect = mrViewData.GetEditArea( eWhich, nPosX, nPosY, this, pPattern, true );
241 if (!bDone && mpNoteMarker)
243 if (mpNoteMarker->IsByKeyboard())
245 // marker which was shown for ctrl-F1 isn't removed by mouse events
247 else
249 mpNoteMarker.reset();
253 if ( !aFormulaText.isEmpty() )
255 tools::Rectangle aScreenRect(OutputToScreenPixel(aFormulaPixRect.TopLeft()),
256 OutputToScreenPixel(aFormulaPixRect.BottomRight()));
257 if ( rHEvt.GetMode() & HelpEventMode::BALLOON )
258 Help::ShowBalloon(this, rHEvt.GetMousePosPixel(), aScreenRect, aFormulaText);
259 else if ( rHEvt.GetMode() & HelpEventMode::QUICK )
260 Help::ShowQuickHelp(this, aScreenRect, aFormulaText);
261 bDone = true;
264 // Image-Map / Text-URL
266 if ( bHelpEnabled && !bDone && !nButtonDown ) // only without pressed button
268 OUString aHelpText;
269 tools::Rectangle aPixRect;
270 Point aPosPixel = ScreenToOutputPixel( rHEvt.GetMousePosPixel() );
272 if ( pDrView ) // URL / Image-Map
274 SdrViewEvent aVEvt;
275 MouseEvent aMEvt( aPosPixel, 1, MouseEventModifiers::NONE, MOUSE_LEFT );
276 SdrHitKind eHit = pDrView->PickAnything( aMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt );
278 if ( eHit != SdrHitKind::NONE && aVEvt.mpObj != nullptr )
280 // URL for IMapObject below Pointer is help text
281 if (SvxIMapInfo::GetIMapInfo(aVEvt.mpObj))
283 Point aLogicPos = PixelToLogic( aPosPixel );
284 IMapObject* pIMapObj = SvxIMapInfo::GetHitIMapObject(
285 aVEvt.mpObj, aLogicPos, GetOutDev() );
287 if ( pIMapObj )
289 // For image maps show the description, if available
290 aHelpText = pIMapObj->GetAltText();
291 if (aHelpText.isEmpty())
292 aHelpText = SfxHelp::GetURLHelpText(pIMapObj->GetURL());
293 aPixRect = LogicToPixel(aVEvt.mpObj->GetLogicRect());
296 // URL in shape text or at shape itself (URL in text overrides object URL)
297 if ( aHelpText.isEmpty() )
299 if( aVEvt.meEvent == SdrEventKind::ExecuteUrl )
301 if (aVEvt.mpURLField && !aVEvt.mpURLField->GetURL().startsWith("#"))
303 aHelpText = SfxHelp::GetURLHelpText(aVEvt.mpURLField->GetURL());
304 aPixRect = LogicToPixel(aVEvt.mpObj->GetLogicRect());
307 else
309 SdrPageView* pPV = nullptr;
310 Point aMDPos = PixelToLogic( aPosPixel );
311 SdrObject* pObj = pDrView->PickObj(aMDPos, pDrView->getHitTolLog(), pPV, SdrSearchOptions::ALSOONMASTER);
312 if (pObj)
314 if ( pObj->IsGroupObject() )
316 SdrObject* pHit = pDrView->PickObj(aMDPos, pDrView->getHitTolLog(), pPV, SdrSearchOptions::DEEP);
317 if (pHit)
318 pObj = pHit;
320 // Fragments pointing into the current document need no tooltip
321 // describing the ctrl-click functionality.
322 if ( !pObj->getHyperlink().isEmpty() && !pObj->getHyperlink().startsWith("#") )
324 aPixRect = LogicToPixel(aVEvt.mpObj->GetLogicRect());
325 aHelpText = SfxHelp::GetURLHelpText(pObj->getHyperlink());
333 if ( aHelpText.isEmpty() ) // Text-URL
335 OUString aUrl;
336 if ( GetEditUrl( aPosPixel, nullptr, &aUrl ) )
338 aHelpText = SfxHelp::GetURLHelpText(
339 INetURLObject::decode(aUrl, INetURLObject::DecodeMechanism::Unambiguous));
341 ScDocument& rDoc = mrViewData.GetDocument();
342 SCCOL nPosX;
343 SCROW nPosY;
344 SCTAB nTab = mrViewData.GetTabNo();
345 mrViewData.GetPosFromPixel( aPosPixel.X(), aPosPixel.Y(), eWhich, nPosX, nPosY );
346 const ScPatternAttr* pPattern = rDoc.GetPattern( nPosX, nPosY, nTab );
348 // bForceToTop = sal_False, use the cell's real position
349 aPixRect = mrViewData.GetEditArea( eWhich, nPosX, nPosY, this, pPattern, false );
353 if ( !aHelpText.isEmpty() )
355 tools::Rectangle aScreenRect(OutputToScreenPixel(aPixRect.TopLeft()),
356 OutputToScreenPixel(aPixRect.BottomRight()));
358 if ( rHEvt.GetMode() & HelpEventMode::BALLOON )
359 Help::ShowBalloon(this,rHEvt.GetMousePosPixel(), aScreenRect, aHelpText);
360 else if ( rHEvt.GetMode() & HelpEventMode::QUICK )
361 Help::ShowQuickHelp(this,aScreenRect, aHelpText);
363 bDone = true;
367 // basic controls
369 if ( pDrView && bHelpEnabled && !bDone )
371 SdrPageView* pPV = pDrView->GetSdrPageView();
372 OSL_ENSURE( pPV, "SdrPageView* is NULL" );
373 if (pPV)
374 bDone = FmFormPage::RequestHelp( this, pDrView, rHEvt );
377 // If QuickHelp for AutoFill is shown, do not allow it to be removed
379 if ( nMouseStatus == SC_GM_TABDOWN && mrViewData.GetRefType() == SC_REFTYPE_FILL &&
380 Help::IsQuickHelpEnabled() )
381 bDone = true;
383 if (!bDone)
384 Window::RequestHelp( rHEvt );
387 bool ScGridWindow::IsMyModel(const SdrEditView* pSdrView)
389 return pSdrView &&
390 &pSdrView->GetModel() == mrViewData.GetDocument().GetDrawLayer();
393 void ScGridWindow::HideNoteMarker()
395 mpNoteMarker.reset();
398 css::uno::Reference< css::accessibility::XAccessible >
399 ScGridWindow::CreateAccessible()
401 css::uno::Reference< css::accessibility::XAccessible > xAcc= GetAccessible(false);
402 if (xAcc.is())
404 return xAcc;
407 rtl::Reference<ScAccessibleDocument> pAccessibleDocument =
408 new ScAccessibleDocument(GetAccessibleParentWindow()->GetAccessible(),
409 mrViewData.GetViewShell(), eWhich);
410 pAccessibleDocument->PreInit();
412 xAcc = pAccessibleDocument;
413 SetAccessible(xAcc);
415 pAccessibleDocument->Init();
417 return xAcc;
420 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */