Bump version to 4.3-4
[LibreOffice.git] / sc / source / ui / view / gridwin5.cxx
bloba85a5497549d683a24f6b623fcc321b2aacca35a
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/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"
50 #include "dbfunc.hxx"
51 #include "tabvwsh.hxx"
52 #include "userdat.hxx"
53 #include "postit.hxx"
54 #include "global.hxx"
55 #include "globstr.hrc"
58 bool ScGridWindow::ShowNoteMarker( SCsCOL nPosX, SCsROW nPosY, bool bKeyboard )
60 bool bDone = false;
62 ScDocument* pDoc = pViewData->GetDocument();
63 SCTAB nTab = pViewData->GetTabNo();
64 ScAddress aCellPos( nPosX, nPosY, nTab );
66 OUString aTrackText;
67 bool bLeftEdge = false;
69 // Change-Tracking
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;
78 long nModified = 0;
79 const ScChangeAction* pAction = pTrack->GetFirst();
80 while (pAction)
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
99 switch ( eType )
101 case SC_CAT_CONTENT :
102 pFoundContent = pAction;
103 break;
104 case SC_CAT_MOVE :
105 pFoundMove = pAction;
106 break;
107 default:
109 // added to avoid warnings
112 ++nModified;
115 if ( eType == SC_CAT_MOVE )
117 ScRange aRange =
118 ((const ScChangeActionMove*)pAction)->
119 GetFromRange().MakeRange();
120 if ( aRange.In( aCellPos ) )
122 pFound = pAction;
123 ++nModified;
127 pAction = pAction->GetNext();
130 if ( pFound )
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 )
141 bLeftEdge = true;
143 DateTime aDT = pFound->GetDateTime();
144 aTrackText = pFound->GetUser();
145 aTrackText += ", ";
146 aTrackText += ScGlobal::pLocaleData->getDate(aDT);
147 aTrackText += " ";
148 aTrackText += ScGlobal::pLocaleData->getTime(aDT);
149 aTrackText += ":\n";
150 OUString aComStr=pFound->GetComment();
151 if(!aComStr.isEmpty())
153 aTrackText += aComStr;
154 aTrackText += "\n( ";
156 OUString aTmp;
157 pFound->GetDescription(aTmp, pDoc);
158 aTrackText += aTmp;
159 if(!aComStr.isEmpty())
161 aTrackText += ")";
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()) )
170 bool bNew = true;
171 bool bFast = false;
172 if ( pNoteMarker ) // schon eine Notiz angezeigt
174 if ( pNoteMarker->GetDocPos() == aCellPos ) // dieselbe
175 bNew = false; // dann stehenlassen
176 else
177 bFast = true; // sonst sofort
179 // marker which was shown for ctrl-F1 isn't removed by mouse events
180 if ( pNoteMarker->IsByKeyboard() && !bKeyboard )
181 bNew = false;
183 if ( bNew )
185 if ( bKeyboard )
186 bFast = true; // keyboard also shows the marker immediately
188 delete pNoteMarker;
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)
237 return bDone;
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 );
250 bool bDone = false;
251 bool bHelpEnabled = ( rHEvt.GetMode() & ( HELPMODE_BALLOON | HELPMODE_QUICK ) ) != 0;
252 SdrView* pDrView = pViewData->GetScDrawView();
253 bool bDrawTextEdit = false;
254 if (pDrView)
255 bDrawTextEdit = pDrView->IsTextEdit();
256 // notes or change tracking
257 if ( bHelpEnabled && !bDrawTextEdit )
259 Point aPosPixel = ScreenToOutputPixel( rHEvt.GetMousePosPixel() );
260 SCsCOL nPosX;
261 SCsROW nPosY;
262 pViewData->GetPosFromPixel( aPosPixel.X(), aPosPixel.Y(), eWhich, nPosX, nPosY );
264 if ( ShowNoteMarker( nPosX, nPosY, false ) )
266 Window::RequestHelp( rHEvt ); // alte Tip/Balloon ausschalten
267 bDone = true;
271 if ( !bDone && pNoteMarker )
273 if ( pNoteMarker->IsByKeyboard() )
275 // marker which was shown for ctrl-F1 isn't removed by mouse events
277 else
278 DELETEZ(pNoteMarker);
281 // Image-Map / Text-URL
283 if ( bHelpEnabled && !bDone && !nButtonDown ) // nur ohne gedrueckten Button
285 OUString aHelpText;
286 Rectangle aPixRect;
287 Point aPosPixel = ScreenToOutputPixel( rHEvt.GetMousePosPixel() );
289 if ( pDrView ) // URL / Image-Map
291 SdrViewEvent aVEvt;
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 );
304 if ( pIMapObj )
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;
315 else
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());
331 else
333 SdrObject* pObj = 0;
334 SdrPageView* pPV = 0;
335 Point aMDPos = PixelToLogic( aPosPixel );
336 if ( pDrView->PickObj(aMDPos, pDrView->getHitTolLog(), pObj, pPV, SDRSEARCH_ALSOONMASTER) )
338 if ( pObj->IsGroupObject() )
340 SdrObject* pHit = 0;
341 if ( pDrView->PickObj(aMDPos, pDrView->getHitTolLog(), pHit, pPV, SDRSEARCH_DEEP ) )
342 pObj = pHit;
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;
354 else
356 //Option not set, so prefix STR_CLICKHYPERLINK
357 aHelpText = aClickHlinkStr + aHelpText;
367 if ( aHelpText.isEmpty() ) // Text-URL
369 OUString aUrl;
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;
380 else
382 //Option not set, so prefix STR_CLICKHYPERLINK
383 aHelpText = aClickHlinkStr + aHelpText;
387 ScDocument* pDoc = pViewData->GetDocument();
388 SCsCOL nPosX;
389 SCsROW nPosY;
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);
409 bDone = true;
413 // Basic-Controls
415 if ( pDrView && bHelpEnabled && !bDone )
417 SdrPageView* pPV = pDrView->GetSdrPageView();
418 OSL_ENSURE( pPV, "SdrPageView* ist NULL" );
419 if (pPV)
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() )
427 bDone = true;
429 if (!bDone)
430 Window::RequestHelp( rHEvt );
433 bool ScGridWindow::IsMyModel(SdrEditView* pSdrView)
435 return 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);
448 if (xAcc.is())
450 return xAcc;
453 ScAccessibleDocument* pAccessibleDocument =
454 new ScAccessibleDocument(GetAccessibleParentWindow()->GetAccessible(),
455 pViewData->GetViewShell(), eWhich);
457 xAcc = pAccessibleDocument;
458 SetAccessible(xAcc);
460 pAccessibleDocument->Init();
462 return xAcc;
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());
471 if (pAccDoc)
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);
490 return;
495 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */