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"
58 bool ScGridWindow::ShowNoteMarker( SCsCOL nPosX
, SCsROW nPosY
, bool bKeyboard
)
62 ScDocument
* pDoc
= pViewData
->GetDocument();
63 SCTAB nTab
= pViewData
->GetTabNo();
64 ScAddress
aCellPos( nPosX
, nPosY
, nTab
);
67 bool bLeftEdge
= false;
71 ScChangeTrack
* pTrack
= pDoc
->GetChangeTrack();
72 ScChangeViewSettings
* pSettings
= pDoc
->GetChangeViewSettings();
73 if ( pTrack
&& pTrack
->GetFirst() && pSettings
&& pSettings
->ShowChanges())
75 const ScChangeAction
* pFound
= NULL
;
76 const ScChangeAction
* pFoundContent
= NULL
;
77 const ScChangeAction
* pFoundMove
= NULL
;
79 const ScChangeAction
* pAction
= pTrack
->GetFirst();
82 if ( pAction
->IsVisible() &&
83 ScViewUtil::IsActionShown( *pAction
, *pSettings
, *pDoc
) )
85 ScChangeActionType eType
= pAction
->GetType();
86 const ScBigRange
& rBig
= pAction
->GetBigRange();
87 if ( rBig
.aStart
.Tab() == nTab
)
89 ScRange aRange
= rBig
.MakeRange();
91 if ( eType
== SC_CAT_DELETE_ROWS
)
92 aRange
.aEnd
.SetRow( aRange
.aStart
.Row() );
93 else if ( eType
== SC_CAT_DELETE_COLS
)
94 aRange
.aEnd
.SetCol( aRange
.aStart
.Col() );
96 if ( aRange
.In( aCellPos
) )
98 pFound
= pAction
; // der letzte gewinnt
101 case SC_CAT_CONTENT
:
102 pFoundContent
= pAction
;
105 pFoundMove
= pAction
;
109 // added to avoid warnings
115 if ( eType
== SC_CAT_MOVE
)
118 ((const ScChangeActionMove
*)pAction
)->
119 GetFromRange().MakeRange();
120 if ( aRange
.In( aCellPos
) )
127 pAction
= pAction
->GetNext();
132 if ( pFoundContent
&& pFound
->GetType() != SC_CAT_CONTENT
)
133 pFound
= pFoundContent
; // Content gewinnt
134 if ( pFoundMove
&& pFound
->GetType() != SC_CAT_MOVE
&&
135 pFoundMove
->GetActionNumber() >
136 pFound
->GetActionNumber() )
137 pFound
= pFoundMove
; // Move gewinnt
139 // bei geloeschten Spalten: Pfeil auf die linke Seite der Zelle
140 if ( pFound
->GetType() == SC_CAT_DELETE_COLS
)
143 DateTime aDT
= pFound
->GetDateTime();
144 aTrackText
= pFound
->GetUser();
146 aTrackText
+= ScGlobal::pLocaleData
->getDate(aDT
);
148 aTrackText
+= ScGlobal::pLocaleData
->getTime(aDT
);
150 OUString aComStr
=pFound
->GetComment();
151 if(!aComStr
.isEmpty())
153 aTrackText
+= aComStr
;
154 aTrackText
+= "\n( ";
157 pFound
->GetDescription(aTmp
, pDoc
);
159 if(!aComStr
.isEmpty())
166 // Notiz nur, wenn sie nicht schon auf dem Drawing-Layer angezeigt wird:
167 const ScPostIt
* pNote
= pDoc
->GetNote( aCellPos
);
168 if ( (!aTrackText
.isEmpty()) || (pNote
&& !pNote
->IsCaptionShown()) )
172 if ( pNoteMarker
) // schon eine Notiz angezeigt
174 if ( pNoteMarker
->GetDocPos() == aCellPos
) // dieselbe
175 bNew
= false; // dann stehenlassen
177 bFast
= true; // sonst sofort
179 // marker which was shown for ctrl-F1 isn't removed by mouse events
180 if ( pNoteMarker
->IsByKeyboard() && !bKeyboard
)
186 bFast
= true; // keyboard also shows the marker immediately
190 bool bHSplit
= pViewData
->GetHSplitMode() != SC_SPLIT_NONE
;
191 bool bVSplit
= pViewData
->GetVSplitMode() != SC_SPLIT_NONE
;
193 Window
* pLeft
= pViewData
->GetView()->GetWindowByPos( bVSplit
? SC_SPLIT_TOPLEFT
: SC_SPLIT_BOTTOMLEFT
);
194 Window
* pRight
= bHSplit
? pViewData
->GetView()->GetWindowByPos( bVSplit
? SC_SPLIT_TOPRIGHT
: SC_SPLIT_BOTTOMRIGHT
) : 0;
195 Window
* pBottom
= bVSplit
? pViewData
->GetView()->GetWindowByPos( SC_SPLIT_BOTTOMLEFT
) : 0;
196 Window
* pDiagonal
= (bHSplit
&& bVSplit
) ? pViewData
->GetView()->GetWindowByPos( SC_SPLIT_BOTTOMRIGHT
) : 0;
197 OSL_ENSURE( pLeft
, "ScGridWindow::ShowNoteMarker - missing top-left grid window" );
199 /* If caption is shown from right or bottom windows, adjust
200 mapmode to include size of top-left window. */
201 MapMode aMapMode
= GetDrawMapMode( true );
202 Size aLeftSize
= pLeft
->PixelToLogic( pLeft
->GetOutputSizePixel(), aMapMode
);
203 Point aOrigin
= aMapMode
.GetOrigin();
204 if( (this == pRight
) || (this == pDiagonal
) )
205 aOrigin
.X() += aLeftSize
.Width();
206 if( (this == pBottom
) || (this == pDiagonal
) )
207 aOrigin
.Y() += aLeftSize
.Height();
208 aMapMode
.SetOrigin( aOrigin
);
210 pNoteMarker
= new ScNoteMarker( pLeft
, pRight
, pBottom
, pDiagonal
,
211 pDoc
, aCellPos
, aTrackText
,
212 aMapMode
, bLeftEdge
, bFast
, bKeyboard
);
213 if ( pViewData
->GetScDrawView() )
215 // get position for aCellPos
216 // get draw position in hmm for aCellPos
217 Point
aOldPos( pDoc
->GetColOffset( aCellPos
.Col(), aCellPos
.Tab() ), pDoc
->GetRowOffset( aCellPos
.Row(), aCellPos
.Tab() ) );
218 aOldPos
.X() = sc::TwipsToHMM( aOldPos
.X() );
219 aOldPos
.Y() = sc::TwipsToHMM( aOldPos
.Y() );
220 // get screen pos in hmm for aCellPos
221 // and equiv screen pos
222 Point aScreenPos
= pViewData
->GetScrPos( aCellPos
.Col(), aCellPos
.Row(), eWhich
, true );
223 MapMode aDrawMode
= GetDrawMapMode();
224 Point aCurPosHmm
= PixelToLogic(aScreenPos
, aDrawMode
);
225 Point aGridOff
= aCurPosHmm
-aOldPos
;
226 // fdo#63323 fix the X Position for the showing comment when
227 // the mouse over the cell when the sheet are RTL
228 if ( pDoc
->IsNegativePage(nTab
))
229 aGridOff
.setX(aCurPosHmm
.getX() + aOldPos
.getX());
230 pNoteMarker
->SetGridOff( aGridOff
);
234 bDone
= true; // something is shown (old or new)
240 void ScGridWindow::RequestHelp(const HelpEvent
& rHEvt
)
242 //To know whether to prefix STR_CTRLCLICKHYERLINK or STR_CLICKHYPERLINK
243 //to hyperlink tooltips/help text
244 SvtSecurityOptions aSecOpt
;
245 bool bCtrlClickHlink
= aSecOpt
.IsOptionSet( SvtSecurityOptions::E_CTRLCLICK_HYPERLINK
);
246 //Global string STR_CTRLCLICKHYPERLINK i.e, "ctrl+click to open hyperlink:"
247 OUString aCtrlClickHlinkStr
= ScGlobal::GetRscString( STR_CTRLCLICKHYPERLINK
);
248 //Global string STR_CLICKHYPERLINK i.e, "click to open hyperlink"
249 OUString aClickHlinkStr
= ScGlobal::GetRscString( STR_CLICKHYPERLINK
);
251 bool bHelpEnabled
= ( rHEvt
.GetMode() & ( HELPMODE_BALLOON
| HELPMODE_QUICK
) ) != 0;
252 SdrView
* pDrView
= pViewData
->GetScDrawView();
253 bool bDrawTextEdit
= false;
255 bDrawTextEdit
= pDrView
->IsTextEdit();
256 // notes or change tracking
257 if ( bHelpEnabled
&& !bDrawTextEdit
)
259 Point aPosPixel
= ScreenToOutputPixel( rHEvt
.GetMousePosPixel() );
262 pViewData
->GetPosFromPixel( aPosPixel
.X(), aPosPixel
.Y(), eWhich
, nPosX
, nPosY
);
264 if ( ShowNoteMarker( nPosX
, nPosY
, false ) )
266 Window::RequestHelp( rHEvt
); // alte Tip/Balloon ausschalten
271 if ( !bDone
&& pNoteMarker
)
273 if ( pNoteMarker
->IsByKeyboard() )
275 // marker which was shown for ctrl-F1 isn't removed by mouse events
278 DELETEZ(pNoteMarker
);
281 // Image-Map / Text-URL
283 if ( bHelpEnabled
&& !bDone
&& !nButtonDown
) // nur ohne gedrueckten Button
287 Point aPosPixel
= ScreenToOutputPixel( rHEvt
.GetMousePosPixel() );
289 if ( pDrView
) // URL / Image-Map
292 MouseEvent
aMEvt( aPosPixel
, 1, 0, MOUSE_LEFT
);
293 SdrHitKind eHit
= pDrView
->PickAnything( aMEvt
, SDRMOUSEBUTTONDOWN
, aVEvt
);
295 if ( eHit
!= SDRHIT_NONE
&& aVEvt
.pObj
!= NULL
)
297 // URL fuer IMapObject unter Pointer ist Hilfetext
298 if ( ScDrawLayer::GetIMapInfo( aVEvt
.pObj
) )
300 Point aLogicPos
= PixelToLogic( aPosPixel
);
301 IMapObject
* pIMapObj
= ScDrawLayer::GetHitIMapObject(
302 aVEvt
.pObj
, aLogicPos
, *this );
306 // Bei ImageMaps die Description anzeigen, wenn vorhanden
307 aHelpText
= pIMapObj
->GetAltText();
308 if (aHelpText
.isEmpty())
309 aHelpText
= pIMapObj
->GetURL();
310 if( bCtrlClickHlink
)
312 //prefix STR_CTRLCLICKHYPERLINK to aHelpText
313 aHelpText
= aCtrlClickHlinkStr
+ aHelpText
;
317 //Option not set, so prefix STR_CLICKHYPERLINK
318 aHelpText
= aClickHlinkStr
+ aHelpText
;
320 aPixRect
= LogicToPixel(aVEvt
.pObj
->GetLogicRect());
323 // URL in shape text or at shape itself (URL in text overrides object URL)
324 if ( aHelpText
.isEmpty() )
326 if( aVEvt
.eEvent
== SDREVENT_EXECUTEURL
)
328 aHelpText
= aVEvt
.pURLField
->GetURL();
329 aPixRect
= LogicToPixel(aVEvt
.pObj
->GetLogicRect());
334 SdrPageView
* pPV
= 0;
335 Point aMDPos
= PixelToLogic( aPosPixel
);
336 if ( pDrView
->PickObj(aMDPos
, pDrView
->getHitTolLog(), pObj
, pPV
, SDRSEARCH_ALSOONMASTER
) )
338 if ( pObj
->IsGroupObject() )
341 if ( pDrView
->PickObj(aMDPos
, pDrView
->getHitTolLog(), pHit
, pPV
, SDRSEARCH_DEEP
) )
344 ScMacroInfo
* pInfo
= ScDrawLayer::GetMacroInfo( pObj
);
345 if ( pInfo
&& (pInfo
->GetHlink().getLength() > 0) )
347 aPixRect
= LogicToPixel(aVEvt
.pObj
->GetLogicRect());
348 aHelpText
= pInfo
->GetHlink();
349 if( bCtrlClickHlink
)
351 //prefix STR_CTRLCLICKHYPERLINK to aHelpText
352 aHelpText
= aCtrlClickHlinkStr
+ aHelpText
;
356 //Option not set, so prefix STR_CLICKHYPERLINK
357 aHelpText
= aClickHlinkStr
+ aHelpText
;
367 if ( aHelpText
.isEmpty() ) // Text-URL
370 if ( GetEditUrl( aPosPixel
, NULL
, &aUrl
, NULL
) )
372 aHelpText
= INetURLObject::decode( aUrl
, '%',
373 INetURLObject::DECODE_UNAMBIGUOUS
);
375 if( bCtrlClickHlink
)
377 //prefix STR_CTRLCLICKHYPERLINK to aHelpText
378 aHelpText
= aCtrlClickHlinkStr
+ aHelpText
;
382 //Option not set, so prefix STR_CLICKHYPERLINK
383 aHelpText
= aClickHlinkStr
+ aHelpText
;
387 ScDocument
* pDoc
= pViewData
->GetDocument();
390 SCTAB nTab
= pViewData
->GetTabNo();
391 pViewData
->GetPosFromPixel( aPosPixel
.X(), aPosPixel
.Y(), eWhich
, nPosX
, nPosY
);
392 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( nPosX
, nPosY
, nTab
);
394 // bForceToTop = sal_False, use the cell's real position
395 aPixRect
= pViewData
->GetEditArea( eWhich
, nPosX
, nPosY
, this, pPattern
, false );
399 if ( !aHelpText
.isEmpty() )
401 Rectangle
aScreenRect(OutputToScreenPixel(aPixRect
.TopLeft()),
402 OutputToScreenPixel(aPixRect
.BottomRight()));
404 if ( rHEvt
.GetMode() & HELPMODE_BALLOON
)
405 Help::ShowBalloon(this,rHEvt
.GetMousePosPixel(), aScreenRect
, aHelpText
);
406 else if ( rHEvt
.GetMode() & HELPMODE_QUICK
)
407 Help::ShowQuickHelp(this,aScreenRect
, aHelpText
);
415 if ( pDrView
&& bHelpEnabled
&& !bDone
)
417 SdrPageView
* pPV
= pDrView
->GetSdrPageView();
418 OSL_ENSURE( pPV
, "SdrPageView* ist NULL" );
420 bDone
= ((ScDrawPage
*)pPV
->GetPage())->RequestHelp( this, pDrView
, rHEvt
);
423 // Wenn QuickHelp fuer AutoFill angezeigt wird, nicht wieder wegnehmen lassen
425 if ( nMouseStatus
== SC_GM_TABDOWN
&& pViewData
->GetRefType() == SC_REFTYPE_FILL
&&
426 Help::IsQuickHelpEnabled() )
430 Window::RequestHelp( rHEvt
);
433 bool ScGridWindow::IsMyModel(SdrEditView
* pSdrView
)
436 pSdrView
->GetModel() == pViewData
->GetDocument()->GetDrawLayer();
439 void ScGridWindow::HideNoteMarker()
441 DELETEZ(pNoteMarker
);
444 com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>
445 ScGridWindow::CreateAccessible()
447 com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
> xAcc
= GetAccessible(false);
453 ScAccessibleDocument
* pAccessibleDocument
=
454 new ScAccessibleDocument(GetAccessibleParentWindow()->GetAccessible(),
455 pViewData
->GetViewShell(), eWhich
);
457 xAcc
= pAccessibleDocument
;
460 pAccessibleDocument
->Init();
465 // MT: Removed Windows::SwitchView() introduced with IA2 CWS.
466 // There are other notifications for this when the active view has chnaged, so
467 // please update the code to use that event mechanism
468 void ScGridWindow::SwitchView()
470 ScAccessibleDocumentBase
* pAccDoc
= static_cast<ScAccessibleDocumentBase
*>(GetAccessible(false).get());
473 pAccDoc
->SwitchViewFireFocus();
477 void ScGridWindow::AddChildWindow(Window
* pWindow
)
479 maChildWindows
.push_back(pWindow
);
482 void ScGridWindow::DeleteChildWindow(Window
* pWindow
)
484 for(boost::ptr_vector
<Window
>::iterator itr
= maChildWindows
.begin(),
485 itrEnd
= maChildWindows
.end(); itr
!= itrEnd
; ++itr
)
487 if(&(*itr
) == pWindow
)
489 maChildWindows
.erase(itr
);
495 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */