Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <editeng/eeitem.hxx>
21 :
22 : #include <editeng/flditem.hxx>
23 :
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>
32 :
33 : #include <unotools/localedatawrapper.hxx>
34 :
35 : #include "viewuno.hxx"
36 : #include "AccessibleDocument.hxx"
37 : #include <com/sun/star/accessibility/XAccessible.hpp>
38 :
39 : #include "gridwin.hxx"
40 : #include "viewdata.hxx"
41 : #include "drawview.hxx"
42 : #include "drwlayer.hxx"
43 : #include "drawpage.hxx"
44 : #include "document.hxx"
45 : #include "notemark.hxx"
46 : #include "chgtrack.hxx"
47 : #include "chgviset.hxx"
48 : #include "dbfunc.hxx"
49 : #include "tabvwsh.hxx"
50 : #include "userdat.hxx"
51 : #include "postit.hxx"
52 :
53 : // -----------------------------------------------------------------------
54 :
55 0 : bool ScGridWindow::ShowNoteMarker( SCsCOL nPosX, SCsROW nPosY, bool bKeyboard )
56 : {
57 0 : bool bDone = false;
58 :
59 0 : ScDocument* pDoc = pViewData->GetDocument();
60 0 : SCTAB nTab = pViewData->GetTabNo();
61 0 : ScAddress aCellPos( nPosX, nPosY, nTab );
62 :
63 0 : String aTrackText;
64 0 : bool bLeftEdge = false;
65 :
66 : // Change-Tracking
67 :
68 0 : ScChangeTrack* pTrack = pDoc->GetChangeTrack();
69 0 : ScChangeViewSettings* pSettings = pDoc->GetChangeViewSettings();
70 0 : if ( pTrack && pTrack->GetFirst() && pSettings && pSettings->ShowChanges())
71 : {
72 0 : const ScChangeAction* pFound = NULL;
73 0 : const ScChangeAction* pFoundContent = NULL;
74 0 : const ScChangeAction* pFoundMove = NULL;
75 0 : long nModified = 0;
76 0 : const ScChangeAction* pAction = pTrack->GetFirst();
77 0 : while (pAction)
78 : {
79 0 : if ( pAction->IsVisible() &&
80 0 : ScViewUtil::IsActionShown( *pAction, *pSettings, *pDoc ) )
81 : {
82 0 : ScChangeActionType eType = pAction->GetType();
83 0 : const ScBigRange& rBig = pAction->GetBigRange();
84 0 : if ( rBig.aStart.Tab() == nTab )
85 : {
86 0 : ScRange aRange = rBig.MakeRange();
87 :
88 0 : if ( eType == SC_CAT_DELETE_ROWS )
89 0 : aRange.aEnd.SetRow( aRange.aStart.Row() );
90 0 : else if ( eType == SC_CAT_DELETE_COLS )
91 0 : aRange.aEnd.SetCol( aRange.aStart.Col() );
92 :
93 0 : if ( aRange.In( aCellPos ) )
94 : {
95 0 : pFound = pAction; // der letzte gewinnt
96 0 : switch ( eType )
97 : {
98 : case SC_CAT_CONTENT :
99 0 : pFoundContent = pAction;
100 0 : break;
101 : case SC_CAT_MOVE :
102 0 : pFoundMove = pAction;
103 0 : break;
104 : default:
105 : {
106 : // added to avoid warnings
107 : }
108 : }
109 0 : ++nModified;
110 : }
111 : }
112 0 : if ( eType == SC_CAT_MOVE )
113 : {
114 : ScRange aRange =
115 : ((const ScChangeActionMove*)pAction)->
116 0 : GetFromRange().MakeRange();
117 0 : if ( aRange.In( aCellPos ) )
118 : {
119 0 : pFound = pAction;
120 0 : ++nModified;
121 : }
122 : }
123 : }
124 0 : pAction = pAction->GetNext();
125 : }
126 :
127 0 : if ( pFound )
128 : {
129 0 : if ( pFoundContent && pFound->GetType() != SC_CAT_CONTENT )
130 0 : pFound = pFoundContent; // Content gewinnt
131 0 : if ( pFoundMove && pFound->GetType() != SC_CAT_MOVE &&
132 0 : pFoundMove->GetActionNumber() >
133 0 : pFound->GetActionNumber() )
134 0 : pFound = pFoundMove; // Move gewinnt
135 :
136 : // bei geloeschten Spalten: Pfeil auf die linke Seite der Zelle
137 0 : if ( pFound->GetType() == SC_CAT_DELETE_COLS )
138 0 : bLeftEdge = true;
139 :
140 0 : DateTime aDT = pFound->GetDateTime();
141 0 : aTrackText = pFound->GetUser();
142 0 : aTrackText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ", " ));
143 0 : aTrackText += ScGlobal::pLocaleData->getDate(aDT);
144 0 : aTrackText += ' ';
145 0 : aTrackText += ScGlobal::pLocaleData->getTime(aDT);
146 0 : aTrackText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ":\n" ));
147 0 : String aComStr=pFound->GetComment();
148 0 : if(aComStr.Len()>0)
149 : {
150 0 : aTrackText += aComStr;
151 0 : aTrackText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "\n( " ));
152 : }
153 0 : rtl::OUString aTmp;
154 0 : pFound->GetDescription(aTmp, pDoc);
155 0 : aTrackText += String(aTmp);
156 0 : if(aComStr.Len()>0)
157 : {
158 0 : aTrackText +=')';
159 0 : }
160 : }
161 : }
162 :
163 : // Notiz nur, wenn sie nicht schon auf dem Drawing-Layer angezeigt wird:
164 0 : const ScPostIt* pNote = pDoc->GetNotes( aCellPos.Tab() )->findByAddress( aCellPos );
165 0 : if ( (aTrackText.Len() > 0) || (pNote && !pNote->IsCaptionShown()) )
166 : {
167 0 : bool bNew = true;
168 0 : bool bFast = false;
169 0 : if ( pNoteMarker ) // schon eine Notiz angezeigt
170 : {
171 0 : if ( pNoteMarker->GetDocPos() == aCellPos ) // dieselbe
172 0 : bNew = false; // dann stehenlassen
173 : else
174 0 : bFast = true; // sonst sofort
175 :
176 : // marker which was shown for ctrl-F1 isn't removed by mouse events
177 0 : if ( pNoteMarker->IsByKeyboard() && !bKeyboard )
178 0 : bNew = false;
179 : }
180 0 : if ( bNew )
181 : {
182 0 : if ( bKeyboard )
183 0 : bFast = true; // keyboard also shows the marker immediately
184 :
185 0 : delete pNoteMarker;
186 :
187 0 : bool bHSplit = pViewData->GetHSplitMode() != SC_SPLIT_NONE;
188 0 : bool bVSplit = pViewData->GetVSplitMode() != SC_SPLIT_NONE;
189 :
190 0 : Window* pLeft = pViewData->GetView()->GetWindowByPos( bVSplit ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT );
191 0 : Window* pRight = bHSplit ? pViewData->GetView()->GetWindowByPos( bVSplit ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT ) : 0;
192 0 : Window* pBottom = bVSplit ? pViewData->GetView()->GetWindowByPos( SC_SPLIT_BOTTOMLEFT ) : 0;
193 0 : Window* pDiagonal = (bHSplit && bVSplit) ? pViewData->GetView()->GetWindowByPos( SC_SPLIT_BOTTOMRIGHT ) : 0;
194 : OSL_ENSURE( pLeft, "ScGridWindow::ShowNoteMarker - missing top-left grid window" );
195 :
196 : /* If caption is shown from right or bottom windows, adjust
197 : mapmode to include size of top-left window. */
198 0 : MapMode aMapMode = GetDrawMapMode( true );
199 0 : Size aLeftSize = pLeft->PixelToLogic( pLeft->GetOutputSizePixel(), aMapMode );
200 0 : Point aOrigin = aMapMode.GetOrigin();
201 0 : if( (this == pRight) || (this == pDiagonal) )
202 0 : aOrigin.X() += aLeftSize.Width();
203 0 : if( (this == pBottom) || (this == pDiagonal) )
204 0 : aOrigin.Y() += aLeftSize.Height();
205 0 : aMapMode.SetOrigin( aOrigin );
206 :
207 : pNoteMarker = new ScNoteMarker( pLeft, pRight, pBottom, pDiagonal,
208 : pDoc, aCellPos, aTrackText,
209 0 : aMapMode, bLeftEdge, bFast, bKeyboard );
210 0 : if ( pViewData->GetScDrawView() )
211 : {
212 : // get position for aCellPos
213 0 : if ( pDoc )
214 : {
215 : // get draw position in hmm for aCellPos
216 0 : Point aOldPos( pDoc->GetColOffset( aCellPos.Col(), aCellPos.Tab() ), pDoc->GetRowOffset( aCellPos.Row(), aCellPos.Tab() ) );
217 0 : aOldPos.X() = sc::TwipsToHMM( aOldPos.X() );
218 0 : aOldPos.Y() = sc::TwipsToHMM( aOldPos.Y() );
219 : // get screen pos in hmm for aCellPos
220 : // and equiv screen pos
221 0 : Point aScreenPos = pViewData->GetScrPos( aCellPos.Col(), aCellPos.Row(), eWhich, sal_True );
222 0 : MapMode aDrawMode = GetDrawMapMode();
223 0 : Point aCurPosHmm = PixelToLogic(aScreenPos, aDrawMode );
224 0 : Point aGridOff = aCurPosHmm -aOldPos;
225 0 : pNoteMarker->SetGridOff( aGridOff );
226 : }
227 0 : }
228 : }
229 :
230 0 : bDone = true; // something is shown (old or new)
231 : }
232 :
233 0 : return bDone;
234 : }
235 :
236 : // -----------------------------------------------------------------------
237 :
238 0 : void ScGridWindow::RequestHelp(const HelpEvent& rHEvt)
239 : {
240 0 : sal_Bool bDone = false;
241 0 : sal_Bool bHelpEnabled = ( rHEvt.GetMode() & ( HELPMODE_BALLOON | HELPMODE_QUICK ) ) != 0;
242 0 : SdrView* pDrView = pViewData->GetScDrawView();
243 :
244 0 : sal_Bool bDrawTextEdit = false;
245 0 : if (pDrView)
246 0 : bDrawTextEdit = pDrView->IsTextEdit();
247 :
248 : // notes or change tracking
249 :
250 0 : if ( bHelpEnabled && !bDrawTextEdit )
251 : {
252 0 : Point aPosPixel = ScreenToOutputPixel( rHEvt.GetMousePosPixel() );
253 : SCsCOL nPosX;
254 : SCsROW nPosY;
255 0 : pViewData->GetPosFromPixel( aPosPixel.X(), aPosPixel.Y(), eWhich, nPosX, nPosY );
256 :
257 0 : if ( ShowNoteMarker( nPosX, nPosY, false ) )
258 : {
259 0 : Window::RequestHelp( rHEvt ); // alte Tip/Balloon ausschalten
260 0 : bDone = sal_True;
261 : }
262 : }
263 :
264 0 : if ( !bDone && pNoteMarker )
265 : {
266 0 : if ( pNoteMarker->IsByKeyboard() )
267 : {
268 : // marker which was shown for ctrl-F1 isn't removed by mouse events
269 : }
270 : else
271 0 : DELETEZ(pNoteMarker);
272 : }
273 :
274 : // Image-Map / Text-URL
275 :
276 0 : if ( bHelpEnabled && !bDone && !nButtonDown ) // nur ohne gedrueckten Button
277 : {
278 0 : String aHelpText;
279 0 : Rectangle aPixRect;
280 0 : Point aPosPixel = ScreenToOutputPixel( rHEvt.GetMousePosPixel() );
281 :
282 0 : if ( pDrView ) // URL / Image-Map
283 : {
284 0 : SdrViewEvent aVEvt;
285 0 : MouseEvent aMEvt( aPosPixel, 1, 0, MOUSE_LEFT );
286 0 : SdrHitKind eHit = pDrView->PickAnything( aMEvt, SDRMOUSEBUTTONDOWN, aVEvt );
287 :
288 0 : if ( eHit != SDRHIT_NONE && aVEvt.pObj != NULL )
289 : {
290 : // URL fuer IMapObject unter Pointer ist Hilfetext
291 0 : if ( ScDrawLayer::GetIMapInfo( aVEvt.pObj ) )
292 : {
293 0 : Point aLogicPos = PixelToLogic( aPosPixel );
294 : IMapObject* pIMapObj = ScDrawLayer::GetHitIMapObject(
295 0 : aVEvt.pObj, aLogicPos, *this );
296 :
297 0 : if ( pIMapObj )
298 : {
299 : // Bei ImageMaps die Description anzeigen, wenn vorhanden
300 0 : aHelpText = pIMapObj->GetAltText();
301 0 : if (!aHelpText.Len())
302 0 : aHelpText = pIMapObj->GetURL();
303 0 : aPixRect = LogicToPixel(aVEvt.pObj->GetLogicRect());
304 : }
305 : }
306 : // URL in shape text or at shape itself (URL in text overrides object URL)
307 0 : if ( aHelpText.Len() == 0 )
308 : {
309 0 : if( aVEvt.eEvent == SDREVENT_EXECUTEURL )
310 : {
311 0 : aHelpText = aVEvt.pURLField->GetURL();
312 0 : aPixRect = LogicToPixel(aVEvt.pObj->GetLogicRect());
313 : }
314 : else
315 : {
316 0 : SdrObject* pObj = 0;
317 0 : SdrPageView* pPV = 0;
318 0 : Point aMDPos = PixelToLogic( aPosPixel );
319 0 : if ( pDrView->PickObj(aMDPos, pDrView->getHitTolLog(), pObj, pPV, SDRSEARCH_ALSOONMASTER) )
320 : {
321 0 : if ( pObj->IsGroupObject() )
322 : {
323 0 : SdrObject* pHit = 0;
324 0 : if ( pDrView->PickObj(aMDPos, pDrView->getHitTolLog(), pHit, pPV, SDRSEARCH_DEEP ) )
325 0 : pObj = pHit;
326 : }
327 0 : ScMacroInfo* pInfo = ScDrawLayer::GetMacroInfo( pObj );
328 0 : if ( pInfo && (pInfo->GetHlink().getLength() > 0) )
329 : {
330 0 : aPixRect = LogicToPixel(aVEvt.pObj->GetLogicRect());
331 0 : aHelpText = pInfo->GetHlink();
332 : }
333 : }
334 : }
335 : }
336 0 : }
337 : }
338 :
339 0 : if ( !aHelpText.Len() ) // Text-URL
340 : {
341 0 : String aUrl;
342 0 : if ( GetEditUrl( aPosPixel, NULL, &aUrl, NULL ) )
343 : {
344 : aHelpText = INetURLObject::decode( aUrl, INET_HEX_ESCAPE,
345 0 : INetURLObject::DECODE_UNAMBIGUOUS );
346 :
347 0 : ScDocument* pDoc = pViewData->GetDocument();
348 : SCsCOL nPosX;
349 : SCsROW nPosY;
350 0 : SCTAB nTab = pViewData->GetTabNo();
351 0 : pViewData->GetPosFromPixel( aPosPixel.X(), aPosPixel.Y(), eWhich, nPosX, nPosY );
352 0 : const ScPatternAttr* pPattern = pDoc->GetPattern( nPosX, nPosY, nTab );
353 :
354 : // bForceToTop = sal_False, use the cell's real position
355 0 : aPixRect = pViewData->GetEditArea( eWhich, nPosX, nPosY, this, pPattern, false );
356 0 : }
357 : }
358 :
359 0 : if ( aHelpText.Len() )
360 : {
361 0 : Rectangle aScreenRect(OutputToScreenPixel(aPixRect.TopLeft()),
362 0 : OutputToScreenPixel(aPixRect.BottomRight()));
363 :
364 0 : if ( rHEvt.GetMode() & HELPMODE_BALLOON )
365 0 : Help::ShowBalloon(this,rHEvt.GetMousePosPixel(), aScreenRect, aHelpText);
366 0 : else if ( rHEvt.GetMode() & HELPMODE_QUICK )
367 0 : Help::ShowQuickHelp(this,aScreenRect, aHelpText);
368 :
369 0 : bDone = sal_True;
370 0 : }
371 : }
372 :
373 : // Basic-Controls
374 :
375 0 : if ( pDrView && bHelpEnabled && !bDone )
376 : {
377 0 : SdrPageView* pPV = pDrView->GetSdrPageView();
378 : OSL_ENSURE( pPV, "SdrPageView* ist NULL" );
379 0 : if (pPV)
380 0 : bDone = ((ScDrawPage*)pPV->GetPage())->RequestHelp( this, pDrView, rHEvt );
381 : }
382 :
383 : // Wenn QuickHelp fuer AutoFill angezeigt wird, nicht wieder wegnehmen lassen
384 :
385 0 : if ( nMouseStatus == SC_GM_TABDOWN && pViewData->GetRefType() == SC_REFTYPE_FILL &&
386 0 : Help::IsQuickHelpEnabled() )
387 0 : bDone = sal_True;
388 :
389 0 : if (!bDone)
390 0 : Window::RequestHelp( rHEvt );
391 0 : }
392 :
393 0 : bool ScGridWindow::IsMyModel(SdrEditView* pSdrView)
394 : {
395 : return pSdrView &&
396 0 : pSdrView->GetModel() == pViewData->GetDocument()->GetDrawLayer();
397 : }
398 :
399 0 : void ScGridWindow::HideNoteMarker()
400 : {
401 0 : DELETEZ(pNoteMarker);
402 0 : }
403 :
404 : com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
405 0 : ScGridWindow::CreateAccessible()
406 : {
407 : ScAccessibleDocument* pAccessibleDocument =
408 : new ScAccessibleDocument(GetAccessibleParentWindow()->GetAccessible(),
409 0 : pViewData->GetViewShell(), eWhich);
410 :
411 0 : com::sun::star::uno::Reference < ::com::sun::star::accessibility::XAccessible > xAccessible = pAccessibleDocument;
412 :
413 0 : pAccessibleDocument->Init();
414 :
415 0 : return xAccessible;
416 15 : }
417 :
418 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|