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 <tools/urlobj.hxx>
31 #include <sfx2/viewfrm.hxx>
33 #include <unotools/localedatawrapper.hxx>
34 #include <unotools/securityoptions.hxx>
36 #include "viewuno.hxx"
37 #include "AccessibleDocument.hxx"
38 #include <com/sun/star/accessibility/XAccessible.hpp>
40 #include "gridwin.hxx"
41 #include "viewdata.hxx"
42 #include "drawview.hxx"
43 #include "drwlayer.hxx"
44 #include "drawpage.hxx"
45 #include "document.hxx"
46 #include "notemark.hxx"
47 #include "chgtrack.hxx"
48 #include "chgviset.hxx"
50 #include "tabvwsh.hxx"
51 #include "userdat.hxx"
54 #include "globstr.hrc"
55 // -----------------------------------------------------------------------
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 ((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 ( pNoteMarker
) // schon eine Notiz angezeigt
173 if ( pNoteMarker
->GetDocPos() == aCellPos
) // dieselbe
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 ( pNoteMarker
->IsByKeyboard() && !bKeyboard
)
185 bFast
= true; // keyboard also shows the marker immediately
189 bool bHSplit
= pViewData
->GetHSplitMode() != SC_SPLIT_NONE
;
190 bool bVSplit
= pViewData
->GetVSplitMode() != SC_SPLIT_NONE
;
192 Window
* pLeft
= pViewData
->GetView()->GetWindowByPos( bVSplit
? SC_SPLIT_TOPLEFT
: SC_SPLIT_BOTTOMLEFT
);
193 Window
* pRight
= bHSplit
? pViewData
->GetView()->GetWindowByPos( bVSplit
? SC_SPLIT_TOPRIGHT
: SC_SPLIT_BOTTOMRIGHT
) : 0;
194 Window
* pBottom
= bVSplit
? pViewData
->GetView()->GetWindowByPos( SC_SPLIT_BOTTOMLEFT
) : 0;
195 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 pNoteMarker
= new ScNoteMarker( pLeft
, pRight
, pBottom
, pDiagonal
,
210 pDoc
, aCellPos
, aTrackText
,
211 aMapMode
, bLeftEdge
, bFast
, bKeyboard
);
212 if ( pViewData
->GetScDrawView() )
214 // get position for aCellPos
217 // get draw position in hmm for aCellPos
218 Point
aOldPos( pDoc
->GetColOffset( aCellPos
.Col(), aCellPos
.Tab() ), pDoc
->GetRowOffset( aCellPos
.Row(), aCellPos
.Tab() ) );
219 aOldPos
.X() = sc::TwipsToHMM( aOldPos
.X() );
220 aOldPos
.Y() = sc::TwipsToHMM( aOldPos
.Y() );
221 // get screen pos in hmm for aCellPos
222 // and equiv screen pos
223 Point aScreenPos
= pViewData
->GetScrPos( aCellPos
.Col(), aCellPos
.Row(), eWhich
, sal_True
);
224 MapMode aDrawMode
= GetDrawMapMode();
225 Point aCurPosHmm
= PixelToLogic(aScreenPos
, aDrawMode
);
226 Point aGridOff
= aCurPosHmm
-aOldPos
;
227 // fdo#63323 fix the X Position for the showing comment when
228 // the mouse over the cell when the sheet are RTL
229 if ( pDoc
->IsNegativePage(nTab
))
230 aGridOff
.setX(aCurPosHmm
.getX() + aOldPos
.getX());
231 pNoteMarker
->SetGridOff( aGridOff
);
236 bDone
= true; // something is shown (old or new)
242 // -----------------------------------------------------------------------
244 void ScGridWindow::RequestHelp(const HelpEvent
& rHEvt
)
246 //To know whether to prefix STR_CTRLCLICKHYERLINK or STR_CLICKHYPERLINK
247 //to hyperlink tooltips/help text
248 SvtSecurityOptions aSecOpt
;
249 bool bCtrlClickHlink
= aSecOpt
.IsOptionSet( SvtSecurityOptions::E_CTRLCLICK_HYPERLINK
);
250 //Global string STR_CTRLCLICKHYPERLINK i.e, "ctrl+click to open hyperlink:"
251 OUString aCtrlClickHlinkStr
= ScGlobal::GetRscString( STR_CTRLCLICKHYPERLINK
);
252 //Global string STR_CLICKHYPERLINK i.e, "click to open hyperlink"
253 OUString aClickHlinkStr
= ScGlobal::GetRscString( STR_CLICKHYPERLINK
);
254 sal_Bool bDone
= false;
255 sal_Bool bHelpEnabled
= ( rHEvt
.GetMode() & ( HELPMODE_BALLOON
| HELPMODE_QUICK
) ) != 0;
256 SdrView
* pDrView
= pViewData
->GetScDrawView();
257 sal_Bool bDrawTextEdit
= false;
259 bDrawTextEdit
= pDrView
->IsTextEdit();
260 // notes or change tracking
261 if ( bHelpEnabled
&& !bDrawTextEdit
)
263 Point aPosPixel
= ScreenToOutputPixel( rHEvt
.GetMousePosPixel() );
266 pViewData
->GetPosFromPixel( aPosPixel
.X(), aPosPixel
.Y(), eWhich
, nPosX
, nPosY
);
268 if ( ShowNoteMarker( nPosX
, nPosY
, false ) )
270 Window::RequestHelp( rHEvt
); // alte Tip/Balloon ausschalten
275 if ( !bDone
&& pNoteMarker
)
277 if ( pNoteMarker
->IsByKeyboard() )
279 // marker which was shown for ctrl-F1 isn't removed by mouse events
282 DELETEZ(pNoteMarker
);
285 // Image-Map / Text-URL
287 if ( bHelpEnabled
&& !bDone
&& !nButtonDown
) // nur ohne gedrueckten Button
291 Point aPosPixel
= ScreenToOutputPixel( rHEvt
.GetMousePosPixel() );
293 if ( pDrView
) // URL / Image-Map
296 MouseEvent
aMEvt( aPosPixel
, 1, 0, MOUSE_LEFT
);
297 SdrHitKind eHit
= pDrView
->PickAnything( aMEvt
, SDRMOUSEBUTTONDOWN
, aVEvt
);
299 if ( eHit
!= SDRHIT_NONE
&& aVEvt
.pObj
!= NULL
)
301 // URL fuer IMapObject unter Pointer ist Hilfetext
302 if ( ScDrawLayer::GetIMapInfo( aVEvt
.pObj
) )
304 Point aLogicPos
= PixelToLogic( aPosPixel
);
305 IMapObject
* pIMapObj
= ScDrawLayer::GetHitIMapObject(
306 aVEvt
.pObj
, aLogicPos
, *this );
310 // Bei ImageMaps die Description anzeigen, wenn vorhanden
311 aHelpText
= pIMapObj
->GetAltText();
312 if (aHelpText
.isEmpty())
313 aHelpText
= pIMapObj
->GetURL();
314 if( bCtrlClickHlink
)
316 //prefix STR_CTRLCLICKHYPERLINK to aHelpText
317 aHelpText
= aCtrlClickHlinkStr
+ aHelpText
;
321 //Option not set, so prefix STR_CLICKHYPERLINK
322 aHelpText
= aClickHlinkStr
+ aHelpText
;
324 aPixRect
= LogicToPixel(aVEvt
.pObj
->GetLogicRect());
327 // URL in shape text or at shape itself (URL in text overrides object URL)
328 if ( aHelpText
.isEmpty() )
330 if( aVEvt
.eEvent
== SDREVENT_EXECUTEURL
)
332 aHelpText
= aVEvt
.pURLField
->GetURL();
333 aPixRect
= LogicToPixel(aVEvt
.pObj
->GetLogicRect());
338 SdrPageView
* pPV
= 0;
339 Point aMDPos
= PixelToLogic( aPosPixel
);
340 if ( pDrView
->PickObj(aMDPos
, pDrView
->getHitTolLog(), pObj
, pPV
, SDRSEARCH_ALSOONMASTER
) )
342 if ( pObj
->IsGroupObject() )
345 if ( pDrView
->PickObj(aMDPos
, pDrView
->getHitTolLog(), pHit
, pPV
, SDRSEARCH_DEEP
) )
348 ScMacroInfo
* pInfo
= ScDrawLayer::GetMacroInfo( pObj
);
349 if ( pInfo
&& (pInfo
->GetHlink().getLength() > 0) )
351 aPixRect
= LogicToPixel(aVEvt
.pObj
->GetLogicRect());
352 aHelpText
= pInfo
->GetHlink();
353 if( bCtrlClickHlink
)
355 //prefix STR_CTRLCLICKHYPERLINK to aHelpText
356 aHelpText
= aCtrlClickHlinkStr
+ aHelpText
;
360 //Option not set, so prefix STR_CLICKHYPERLINK
361 aHelpText
= aClickHlinkStr
+ aHelpText
;
371 if ( aHelpText
.isEmpty() ) // Text-URL
374 if ( GetEditUrl( aPosPixel
, NULL
, &aUrl
, NULL
) )
376 aHelpText
= INetURLObject::decode( aUrl
, INET_HEX_ESCAPE
,
377 INetURLObject::DECODE_UNAMBIGUOUS
);
379 if( bCtrlClickHlink
)
381 //prefix STR_CTRLCLICKHYPERLINK to aHelpText
382 aHelpText
= aCtrlClickHlinkStr
+ aHelpText
;
386 //Option not set, so prefix STR_CLICKHYPERLINK
387 aHelpText
= aClickHlinkStr
+ aHelpText
;
391 ScDocument
* pDoc
= pViewData
->GetDocument();
394 SCTAB nTab
= pViewData
->GetTabNo();
395 pViewData
->GetPosFromPixel( aPosPixel
.X(), aPosPixel
.Y(), eWhich
, nPosX
, nPosY
);
396 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( nPosX
, nPosY
, nTab
);
398 // bForceToTop = sal_False, use the cell's real position
399 aPixRect
= pViewData
->GetEditArea( eWhich
, nPosX
, nPosY
, this, pPattern
, false );
403 if ( !aHelpText
.isEmpty() )
405 Rectangle
aScreenRect(OutputToScreenPixel(aPixRect
.TopLeft()),
406 OutputToScreenPixel(aPixRect
.BottomRight()));
408 if ( rHEvt
.GetMode() & HELPMODE_BALLOON
)
409 Help::ShowBalloon(this,rHEvt
.GetMousePosPixel(), aScreenRect
, aHelpText
);
410 else if ( rHEvt
.GetMode() & HELPMODE_QUICK
)
411 Help::ShowQuickHelp(this,aScreenRect
, aHelpText
);
419 if ( pDrView
&& bHelpEnabled
&& !bDone
)
421 SdrPageView
* pPV
= pDrView
->GetSdrPageView();
422 OSL_ENSURE( pPV
, "SdrPageView* ist NULL" );
424 bDone
= ((ScDrawPage
*)pPV
->GetPage())->RequestHelp( this, pDrView
, rHEvt
);
427 // Wenn QuickHelp fuer AutoFill angezeigt wird, nicht wieder wegnehmen lassen
429 if ( nMouseStatus
== SC_GM_TABDOWN
&& pViewData
->GetRefType() == SC_REFTYPE_FILL
&&
430 Help::IsQuickHelpEnabled() )
434 Window::RequestHelp( rHEvt
);
437 bool ScGridWindow::IsMyModel(SdrEditView
* pSdrView
)
440 pSdrView
->GetModel() == pViewData
->GetDocument()->GetDrawLayer();
443 void ScGridWindow::HideNoteMarker()
445 DELETEZ(pNoteMarker
);
448 com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>
449 ScGridWindow::CreateAccessible()
451 ScAccessibleDocument
* pAccessibleDocument
=
452 new ScAccessibleDocument(GetAccessibleParentWindow()->GetAccessible(),
453 pViewData
->GetViewShell(), eWhich
);
455 com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
> xAccessible
= pAccessibleDocument
;
457 pAccessibleDocument
->Init();
462 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */