1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/eeitem.hxx>
22 #include <editeng/flditem.hxx>
24 #include <editeng/editview.hxx>
25 #include <svx/svdobj.hxx>
26 #include <svx/svdpagv.hxx>
27 #include <svtools/imapobj.hxx>
28 #include <vcl/cursor.hxx>
29 #include <vcl/help.hxx>
30 #include <vcl/svapp.hxx>
31 #include <tools/urlobj.hxx>
32 #include <sfx2/viewfrm.hxx>
34 #include <unotools/localedatawrapper.hxx>
35 #include <unotools/securityoptions.hxx>
37 #include "viewuno.hxx"
38 #include "AccessibleDocument.hxx"
39 #include <com/sun/star/accessibility/XAccessible.hpp>
41 #include "gridwin.hxx"
42 #include "viewdata.hxx"
43 #include "drawview.hxx"
44 #include "drwlayer.hxx"
45 #include "drawpage.hxx"
46 #include "document.hxx"
47 #include "notemark.hxx"
48 #include "chgtrack.hxx"
49 #include "chgviset.hxx"
51 #include "tabvwsh.hxx"
52 #include "userdat.hxx"
55 #include "globstr.hrc"
57 bool ScGridWindow::ShowNoteMarker( SCsCOL nPosX
, SCsROW nPosY
, bool bKeyboard
)
61 ScDocument
* pDoc
= pViewData
->GetDocument();
62 SCTAB nTab
= pViewData
->GetTabNo();
63 ScAddress
aCellPos( nPosX
, nPosY
, nTab
);
66 bool bLeftEdge
= false;
70 ScChangeTrack
* pTrack
= pDoc
->GetChangeTrack();
71 ScChangeViewSettings
* pSettings
= pDoc
->GetChangeViewSettings();
72 if ( pTrack
&& pTrack
->GetFirst() && pSettings
&& pSettings
->ShowChanges())
74 const ScChangeAction
* pFound
= NULL
;
75 const ScChangeAction
* pFoundContent
= NULL
;
76 const ScChangeAction
* pFoundMove
= NULL
;
78 const ScChangeAction
* pAction
= pTrack
->GetFirst();
81 if ( pAction
->IsVisible() &&
82 ScViewUtil::IsActionShown( *pAction
, *pSettings
, *pDoc
) )
84 ScChangeActionType eType
= pAction
->GetType();
85 const ScBigRange
& rBig
= pAction
->GetBigRange();
86 if ( rBig
.aStart
.Tab() == nTab
)
88 ScRange aRange
= rBig
.MakeRange();
90 if ( eType
== SC_CAT_DELETE_ROWS
)
91 aRange
.aEnd
.SetRow( aRange
.aStart
.Row() );
92 else if ( eType
== SC_CAT_DELETE_COLS
)
93 aRange
.aEnd
.SetCol( aRange
.aStart
.Col() );
95 if ( aRange
.In( aCellPos
) )
97 pFound
= pAction
; // der letzte gewinnt
100 case SC_CAT_CONTENT
:
101 pFoundContent
= pAction
;
104 pFoundMove
= pAction
;
108 // added to avoid warnings
114 if ( eType
== SC_CAT_MOVE
)
117 static_cast<const ScChangeActionMove
*>(pAction
)->
118 GetFromRange().MakeRange();
119 if ( aRange
.In( aCellPos
) )
126 pAction
= pAction
->GetNext();
131 if ( pFoundContent
&& pFound
->GetType() != SC_CAT_CONTENT
)
132 pFound
= pFoundContent
; // Content gewinnt
133 if ( pFoundMove
&& pFound
->GetType() != SC_CAT_MOVE
&&
134 pFoundMove
->GetActionNumber() >
135 pFound
->GetActionNumber() )
136 pFound
= pFoundMove
; // Move gewinnt
138 // bei geloeschten Spalten: Pfeil auf die linke Seite der Zelle
139 if ( pFound
->GetType() == SC_CAT_DELETE_COLS
)
142 DateTime aDT
= pFound
->GetDateTime();
143 aTrackText
= pFound
->GetUser();
145 aTrackText
+= ScGlobal::pLocaleData
->getDate(aDT
);
147 aTrackText
+= ScGlobal::pLocaleData
->getTime(aDT
);
149 OUString aComStr
=pFound
->GetComment();
150 if(!aComStr
.isEmpty())
152 aTrackText
+= aComStr
;
153 aTrackText
+= "\n( ";
156 pFound
->GetDescription(aTmp
, pDoc
);
158 if(!aComStr
.isEmpty())
165 // Notiz nur, wenn sie nicht schon auf dem Drawing-Layer angezeigt wird:
166 const ScPostIt
* pNote
= pDoc
->GetNote( aCellPos
);
167 if ( (!aTrackText
.isEmpty()) || (pNote
&& !pNote
->IsCaptionShown()) )
171 if (mpNoteMarker
) // schon eine Notiz angezeigt
173 if (mpNoteMarker
->GetDocPos() == aCellPos
)
174 bNew
= false; // dann stehenlassen
176 bFast
= true; // sonst sofort
178 // marker which was shown for ctrl-F1 isn't removed by mouse events
179 if (mpNoteMarker
->IsByKeyboard() && !bKeyboard
)
185 bFast
= true; // keyboard also shows the marker immediately
187 mpNoteMarker
.reset();
189 bool bHSplit
= pViewData
->GetHSplitMode() != SC_SPLIT_NONE
;
190 bool bVSplit
= pViewData
->GetVSplitMode() != SC_SPLIT_NONE
;
192 vcl::Window
* pLeft
= pViewData
->GetView()->GetWindowByPos( bVSplit
? SC_SPLIT_TOPLEFT
: SC_SPLIT_BOTTOMLEFT
);
193 vcl::Window
* pRight
= bHSplit
? pViewData
->GetView()->GetWindowByPos( bVSplit
? SC_SPLIT_TOPRIGHT
: SC_SPLIT_BOTTOMRIGHT
) : 0;
194 vcl::Window
* pBottom
= bVSplit
? pViewData
->GetView()->GetWindowByPos( SC_SPLIT_BOTTOMLEFT
) : 0;
195 vcl::Window
* pDiagonal
= (bHSplit
&& bVSplit
) ? pViewData
->GetView()->GetWindowByPos( SC_SPLIT_BOTTOMRIGHT
) : 0;
196 OSL_ENSURE( pLeft
, "ScGridWindow::ShowNoteMarker - missing top-left grid window" );
198 /* If caption is shown from right or bottom windows, adjust
199 mapmode to include size of top-left window. */
200 MapMode aMapMode
= GetDrawMapMode( true );
201 Size aLeftSize
= pLeft
->PixelToLogic( pLeft
->GetOutputSizePixel(), aMapMode
);
202 Point aOrigin
= aMapMode
.GetOrigin();
203 if( (this == pRight
) || (this == pDiagonal
) )
204 aOrigin
.X() += aLeftSize
.Width();
205 if( (this == pBottom
) || (this == pDiagonal
) )
206 aOrigin
.Y() += aLeftSize
.Height();
207 aMapMode
.SetOrigin( aOrigin
);
209 mpNoteMarker
.reset(new ScNoteMarker(pLeft
, pRight
, pBottom
, pDiagonal
,
210 pDoc
, aCellPos
, aTrackText
,
211 aMapMode
, bLeftEdge
, bFast
, bKeyboard
));
212 if ( pViewData
->GetScDrawView() )
214 // get position for aCellPos
215 // get draw position in hmm for aCellPos
216 Point
aOldPos( pDoc
->GetColOffset( aCellPos
.Col(), aCellPos
.Tab() ), pDoc
->GetRowOffset( aCellPos
.Row(), aCellPos
.Tab() ) );
217 aOldPos
.X() = sc::TwipsToHMM( aOldPos
.X() );
218 aOldPos
.Y() = sc::TwipsToHMM( aOldPos
.Y() );
219 // get screen pos in hmm for aCellPos
220 // and equiv screen pos
221 Point aScreenPos
= pViewData
->GetScrPos( aCellPos
.Col(), aCellPos
.Row(), eWhich
, true );
222 MapMode aDrawMode
= GetDrawMapMode();
223 Point aCurPosHmm
= PixelToLogic(aScreenPos
, aDrawMode
);
224 Point aGridOff
= aCurPosHmm
-aOldPos
;
225 // fdo#63323 fix the X Position for the showing comment when
226 // the mouse over the cell when the sheet are RTL
227 if ( pDoc
->IsNegativePage(nTab
))
228 aGridOff
.setX(aCurPosHmm
.getX() + aOldPos
.getX());
229 mpNoteMarker
->SetGridOff( aGridOff
);
233 bDone
= true; // something is shown (old or new)
239 void ScGridWindow::RequestHelp(const HelpEvent
& rHEvt
)
241 //To know whether to prefix STR_CTRLCLICKHYERLINK or STR_CLICKHYPERLINK
242 //to hyperlink tooltips/help text
243 SvtSecurityOptions aSecOpt
;
244 bool bCtrlClickHlink
= aSecOpt
.IsOptionSet( SvtSecurityOptions::E_CTRLCLICK_HYPERLINK
);
245 //Global string STR_CTRLCLICKHYPERLINK i.e,
246 // "ctrl-click to follow link:" for not MacOS
247 // "⌘-click to follow link:" for MacOs
248 vcl::KeyCode
aCode( KEY_SPACE
);
249 vcl::KeyCode
aModifiedCode( KEY_SPACE
, KEY_MOD1
);
250 OUString
aModStr( aModifiedCode
.GetName() );
251 aModStr
= aModStr
.replaceFirst(aCode
.GetName(), OUString());
252 aModStr
= aModStr
.replaceAll("+", OUString());
253 OUString aCtrlClickHlinkStr
= ScGlobal::GetRscString( STR_CTRLCLICKHYPERLINK
);
255 aCtrlClickHlinkStr
= aCtrlClickHlinkStr
.replaceAll("%s", aModStr
);
256 //Global string STR_CLICKHYPERLINK i.e, "click to open hyperlink"
257 OUString aClickHlinkStr
= ScGlobal::GetRscString( STR_CLICKHYPERLINK
);
259 bool bHelpEnabled
= bool(rHEvt
.GetMode() & ( HelpEventMode::BALLOON
| HelpEventMode::QUICK
));
260 SdrView
* pDrView
= pViewData
->GetScDrawView();
261 bool bDrawTextEdit
= false;
263 bDrawTextEdit
= pDrView
->IsTextEdit();
264 // notes or change tracking
265 if ( bHelpEnabled
&& !bDrawTextEdit
)
267 Point aPosPixel
= ScreenToOutputPixel( rHEvt
.GetMousePosPixel() );
270 pViewData
->GetPosFromPixel( aPosPixel
.X(), aPosPixel
.Y(), eWhich
, nPosX
, nPosY
);
272 if ( ShowNoteMarker( nPosX
, nPosY
, false ) )
274 Window::RequestHelp( rHEvt
); // alte Tip/Balloon ausschalten
279 if (!bDone
&& mpNoteMarker
)
281 if (mpNoteMarker
->IsByKeyboard())
283 // marker which was shown for ctrl-F1 isn't removed by mouse events
287 mpNoteMarker
.reset();
291 // Image-Map / Text-URL
293 if ( bHelpEnabled
&& !bDone
&& !nButtonDown
) // nur ohne gedrueckten Button
297 Point aPosPixel
= ScreenToOutputPixel( rHEvt
.GetMousePosPixel() );
299 if ( pDrView
) // URL / Image-Map
302 MouseEvent
aMEvt( aPosPixel
, 1, MouseEventModifiers::NONE
, MOUSE_LEFT
);
303 SdrHitKind eHit
= pDrView
->PickAnything( aMEvt
, SdrMouseEventKind::BUTTONDOWN
, aVEvt
);
305 if ( eHit
!= SDRHIT_NONE
&& aVEvt
.pObj
!= NULL
)
307 // URL fuer IMapObject unter Pointer ist Hilfetext
308 if ( ScDrawLayer::GetIMapInfo( aVEvt
.pObj
) )
310 Point aLogicPos
= PixelToLogic( aPosPixel
);
311 IMapObject
* pIMapObj
= ScDrawLayer::GetHitIMapObject(
312 aVEvt
.pObj
, aLogicPos
, *this );
316 // Bei ImageMaps die Description anzeigen, wenn vorhanden
317 aHelpText
= pIMapObj
->GetAltText();
318 if (aHelpText
.isEmpty())
319 aHelpText
= pIMapObj
->GetURL();
320 if( bCtrlClickHlink
)
322 //prefix STR_CTRLCLICKHYPERLINK to aHelpText
323 aHelpText
= aCtrlClickHlinkStr
+ aHelpText
;
327 //Option not set, so prefix STR_CLICKHYPERLINK
328 aHelpText
= aClickHlinkStr
+ aHelpText
;
330 aPixRect
= LogicToPixel(aVEvt
.pObj
->GetLogicRect());
333 // URL in shape text or at shape itself (URL in text overrides object URL)
334 if ( aHelpText
.isEmpty() )
336 if( aVEvt
.eEvent
== SDREVENT_EXECUTEURL
)
338 aHelpText
= aVEvt
.pURLField
->GetURL();
339 aPixRect
= LogicToPixel(aVEvt
.pObj
->GetLogicRect());
344 SdrPageView
* pPV
= 0;
345 Point aMDPos
= PixelToLogic( aPosPixel
);
346 if ( pDrView
->PickObj(aMDPos
, pDrView
->getHitTolLog(), pObj
, pPV
, SdrSearchOptions::ALSOONMASTER
) )
348 if ( pObj
->IsGroupObject() )
351 if ( pDrView
->PickObj(aMDPos
, pDrView
->getHitTolLog(), pHit
, pPV
, SdrSearchOptions::DEEP
) )
354 ScMacroInfo
* pInfo
= ScDrawLayer::GetMacroInfo( pObj
);
355 if ( pInfo
&& (pInfo
->GetHlink().getLength() > 0) )
357 aPixRect
= LogicToPixel(aVEvt
.pObj
->GetLogicRect());
358 aHelpText
= pInfo
->GetHlink();
359 if( bCtrlClickHlink
)
361 //prefix STR_CTRLCLICKHYPERLINK to aHelpText
362 aHelpText
= aCtrlClickHlinkStr
+ aHelpText
;
366 //Option not set, so prefix STR_CLICKHYPERLINK
367 aHelpText
= aClickHlinkStr
+ aHelpText
;
377 if ( aHelpText
.isEmpty() ) // Text-URL
380 if ( GetEditUrl( aPosPixel
, NULL
, &aUrl
, NULL
) )
382 aHelpText
= INetURLObject::decode( aUrl
,
383 INetURLObject::DECODE_UNAMBIGUOUS
);
385 if( bCtrlClickHlink
)
387 //prefix STR_CTRLCLICKHYPERLINK to aHelpText
388 aHelpText
= aCtrlClickHlinkStr
+ aHelpText
;
392 //Option not set, so prefix STR_CLICKHYPERLINK
393 aHelpText
= aClickHlinkStr
+ aHelpText
;
396 ScDocument
* pDoc
= pViewData
->GetDocument();
399 SCTAB nTab
= pViewData
->GetTabNo();
400 pViewData
->GetPosFromPixel( aPosPixel
.X(), aPosPixel
.Y(), eWhich
, nPosX
, nPosY
);
401 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( nPosX
, nPosY
, nTab
);
403 // bForceToTop = sal_False, use the cell's real position
404 aPixRect
= pViewData
->GetEditArea( eWhich
, nPosX
, nPosY
, this, pPattern
, false );
408 if ( !aHelpText
.isEmpty() )
410 Rectangle
aScreenRect(OutputToScreenPixel(aPixRect
.TopLeft()),
411 OutputToScreenPixel(aPixRect
.BottomRight()));
413 if ( rHEvt
.GetMode() & HelpEventMode::BALLOON
)
414 Help::ShowBalloon(this,rHEvt
.GetMousePosPixel(), aScreenRect
, aHelpText
);
415 else if ( rHEvt
.GetMode() & HelpEventMode::QUICK
)
416 Help::ShowQuickHelp(this,aScreenRect
, aHelpText
);
424 if ( pDrView
&& bHelpEnabled
&& !bDone
)
426 SdrPageView
* pPV
= pDrView
->GetSdrPageView();
427 OSL_ENSURE( pPV
, "SdrPageView* ist NULL" );
429 bDone
= FmFormPage::RequestHelp( this, pDrView
, rHEvt
);
432 // Wenn QuickHelp fuer AutoFill angezeigt wird, nicht wieder wegnehmen lassen
434 if ( nMouseStatus
== SC_GM_TABDOWN
&& pViewData
->GetRefType() == SC_REFTYPE_FILL
&&
435 Help::IsQuickHelpEnabled() )
439 Window::RequestHelp( rHEvt
);
442 bool ScGridWindow::IsMyModel(SdrEditView
* pSdrView
)
445 pSdrView
->GetModel() == pViewData
->GetDocument()->GetDrawLayer();
448 void ScGridWindow::HideNoteMarker()
450 mpNoteMarker
.reset();
453 com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>
454 ScGridWindow::CreateAccessible()
456 com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
> xAcc
= GetAccessible(false);
462 ScAccessibleDocument
* pAccessibleDocument
=
463 new ScAccessibleDocument(GetAccessibleParentWindow()->GetAccessible(),
464 pViewData
->GetViewShell(), eWhich
);
466 xAcc
= pAccessibleDocument
;
469 pAccessibleDocument
->Init();
474 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */