xref: /AOO41X/main/sc/source/ui/view/gridwin5.cxx (revision 661500d247158afbdec8c06dc980356593a00698)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26 
27 // INCLUDE ---------------------------------------------------------------
28 
29 #include <editeng/eeitem.hxx>
30 
31 #include <editeng/flditem.hxx>
32 
33 #include <editeng/editview.hxx>
34 #include <svx/svdobj.hxx>
35 #include <svx/svdpagv.hxx>
36 #include <svtools/imapobj.hxx>
37 #include <vcl/cursor.hxx>
38 #include <vcl/help.hxx>
39 #include <tools/urlobj.hxx>
40 #include <sfx2/viewfrm.hxx>
41 
42 #include <unotools/localedatawrapper.hxx>
43 
44 #include "viewuno.hxx"
45 #include "AccessibleDocument.hxx"
46 #include <com/sun/star/accessibility/XAccessible.hpp>
47 
48 #include "gridwin.hxx"
49 #include "viewdata.hxx"
50 #include "drawview.hxx"
51 #include "drwlayer.hxx"
52 #include "drawpage.hxx"
53 #include "document.hxx"
54 #include "notemark.hxx"
55 #include "chgtrack.hxx"
56 #include "chgviset.hxx"
57 #include "dbfunc.hxx"
58 #include "tabvwsh.hxx"
59 #include "userdat.hxx"
60 #include "postit.hxx"
61 #include <vcl/svapp.hxx>
62 
63 // -----------------------------------------------------------------------
64 
ScHideTextCursor(ScViewData * pData,ScSplitPos eW)65 ScHideTextCursor::ScHideTextCursor( ScViewData* pData, ScSplitPos eW ) :
66     pViewData(pData),
67     eWhich(eW)
68 {
69     Window* pWin = pViewData->GetView()->GetWindowByPos( eWhich );
70     if (pWin)
71     {
72         Cursor* pCur = pWin->GetCursor();
73         if ( pCur && pCur->IsVisible() )
74             pCur->Hide();
75     }
76 }
77 
~ScHideTextCursor()78 ScHideTextCursor::~ScHideTextCursor()
79 {
80     Window* pWin = pViewData->GetView()->GetWindowByPos( eWhich );
81     if (pWin)
82     {
83         // restore text cursor
84         if ( pViewData->HasEditView(eWhich) && pWin->HasFocus() )
85             pViewData->GetEditView(eWhich)->ShowCursor( sal_False, sal_True );
86     }
87 }
88 
89 // -----------------------------------------------------------------------
90 
ShowNoteMarker(SCsCOL nPosX,SCsROW nPosY,sal_Bool bKeyboard)91 sal_Bool ScGridWindow::ShowNoteMarker( SCsCOL nPosX, SCsROW nPosY, sal_Bool bKeyboard )
92 {
93     sal_Bool bDone = sal_False;
94 
95     ScDocument* pDoc = pViewData->GetDocument();
96     SCTAB       nTab = pViewData->GetTabNo();
97     ScAddress   aCellPos( nPosX, nPosY, nTab );
98 
99     String aTrackText;
100     sal_Bool bLeftEdge = sal_False;
101 
102     // Change-Tracking
103 
104     ScChangeTrack* pTrack = pDoc->GetChangeTrack();
105     ScChangeViewSettings* pSettings = pDoc->GetChangeViewSettings();
106     if ( pTrack && pTrack->GetFirst() && pSettings && pSettings->ShowChanges())
107     {
108         const ScChangeAction* pFound = NULL;
109         const ScChangeAction* pFoundContent = NULL;
110         const ScChangeAction* pFoundMove = NULL;
111         long nModified = 0;
112         const ScChangeAction* pAction = pTrack->GetFirst();
113         while (pAction)
114         {
115             if ( pAction->IsVisible() &&
116                  ScViewUtil::IsActionShown( *pAction, *pSettings, *pDoc ) )
117             {
118                 ScChangeActionType eType = pAction->GetType();
119                 const ScBigRange& rBig = pAction->GetBigRange();
120                 if ( rBig.aStart.Tab() == nTab )
121                 {
122                     ScRange aRange = rBig.MakeRange();
123 
124                     if ( eType == SC_CAT_DELETE_ROWS )
125                         aRange.aEnd.SetRow( aRange.aStart.Row() );
126                     else if ( eType == SC_CAT_DELETE_COLS )
127                         aRange.aEnd.SetCol( aRange.aStart.Col() );
128 
129                     if ( aRange.In( aCellPos ) )
130                     {
131                         pFound = pAction; // der letzte gewinnt
132                         switch ( eType )
133                         {
134                             case SC_CAT_CONTENT :
135                                 pFoundContent = pAction;
136                             break;
137                             case SC_CAT_MOVE :
138                                 pFoundMove = pAction;
139                             break;
140                             default:
141                             {
142                                 // added to avoid warnings
143                             }
144                         }
145                         ++nModified;
146                     }
147                 }
148                 if ( eType == SC_CAT_MOVE )
149                 {
150                     ScRange aRange =
151                         ((const ScChangeActionMove*)pAction)->
152                         GetFromRange().MakeRange();
153                     if ( aRange.In( aCellPos ) )
154                     {
155                         pFound = pAction;
156                         ++nModified;
157                     }
158                 }
159             }
160             pAction = pAction->GetNext();
161         }
162 
163         if ( pFound )
164         {
165             if ( pFoundContent && pFound->GetType() != SC_CAT_CONTENT )
166                 pFound = pFoundContent; // Content gewinnt
167             if ( pFoundMove && pFound->GetType() != SC_CAT_MOVE &&
168                     pFoundMove->GetActionNumber() >
169                     pFound->GetActionNumber() )
170                 pFound = pFoundMove; // Move gewinnt
171 
172             // bei geloeschten Spalten: Pfeil auf die linke Seite der Zelle
173             if ( pFound->GetType() == SC_CAT_DELETE_COLS )
174                 bLeftEdge = sal_True;
175 
176             DateTime aDT = pFound->GetDateTime();
177             aTrackText = pFound->GetUser();
178             aTrackText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " - " ));
179             aTrackText += ScGlobal::pLocaleData->getDate(aDT);
180             aTrackText += ' ';
181             aTrackText += ScGlobal::pLocaleData->getTime(aDT);
182             aTrackText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "\n" ));
183             String aComStr=pFound->GetComment();
184             if(aComStr.Len()>0)
185             {
186                 aTrackText += aComStr;
187                 aTrackText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "\n(" ));
188             }
189             pFound->GetDescription( aTrackText, pDoc );
190             if(aComStr.Len()>0)
191             {
192                 aTrackText +=')';
193             }
194         }
195     }
196 
197     // Notiz nur, wenn sie nicht schon auf dem Drawing-Layer angezeigt wird:
198     const ScPostIt* pNote = pDoc->GetNote( aCellPos );
199     if ( (aTrackText.Len() > 0) || (pNote && !pNote->IsCaptionShown()) )
200     {
201         sal_Bool bNew = sal_True;
202         sal_Bool bFast = sal_False;
203         if ( pNoteMarker ) // schon eine Notiz angezeigt
204         {
205             if ( pNoteMarker->GetDocPos() == aCellPos ) // dieselbe
206                 bNew = sal_False;                           // dann stehenlassen
207             else
208                 bFast = sal_True;                           // sonst sofort
209 
210             // marker which was shown for ctrl-F1 isn't removed by mouse events
211             if ( pNoteMarker->IsByKeyboard() && !bKeyboard )
212                 bNew = sal_False;
213         }
214         if ( bNew )
215         {
216             if ( bKeyboard )
217                 bFast = sal_True; // keyboard also shows the marker immediately
218 
219             delete pNoteMarker;
220 
221             bool bHSplit = pViewData->GetHSplitMode() != SC_SPLIT_NONE;
222             bool bVSplit = pViewData->GetVSplitMode() != SC_SPLIT_NONE;
223 
224             Window* pLeft = pViewData->GetView()->GetWindowByPos( bVSplit ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT );
225             Window* pRight = bHSplit ? pViewData->GetView()->GetWindowByPos( bVSplit ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT ) : 0;
226             Window* pBottom = bVSplit ? pViewData->GetView()->GetWindowByPos( SC_SPLIT_BOTTOMLEFT ) : 0;
227             Window* pDiagonal = (bHSplit && bVSplit) ? pViewData->GetView()->GetWindowByPos( SC_SPLIT_BOTTOMRIGHT ) : 0;
228             DBG_ASSERT( pLeft, "ScGridWindow::ShowNoteMarker - missing top-left grid window" );
229 
230             /* If caption is shown from right or bottom windows, adjust mapmode to include size of top-left window. */
231             MapMode aMapMode = GetDrawMapMode( sal_True );
232             Size aLeftSize = pLeft->PixelToLogic( pLeft->GetOutputSizePixel(), aMapMode );
233             Point aOrigin = aMapMode.GetOrigin();
234             if( (this == pRight) || (this == pDiagonal) )
235                 aOrigin.X() += aLeftSize.Width();
236             if( (this == pBottom) || (this == pDiagonal) )
237                 aOrigin.Y() += aLeftSize.Height();
238             aMapMode.SetOrigin( aOrigin );
239 
240             pNoteMarker = new ScNoteMarker( pLeft, pRight, pBottom, pDiagonal,
241                                             pDoc, aCellPos, aTrackText,
242                                             aMapMode, bLeftEdge, bFast, bKeyboard );
243         }
244 
245         bDone = sal_True; // something is shown (old or new)
246     }
247 
248     return bDone;
249 }
250 
251 // -----------------------------------------------------------------------
252 
RequestHelp(const HelpEvent & rHEvt)253 void ScGridWindow::RequestHelp(const HelpEvent& rHEvt)
254 {
255     sal_Bool bDone = sal_False;
256     sal_Bool bHelpEnabled = ( rHEvt.GetMode() & ( HELPMODE_BALLOON | HELPMODE_QUICK ) ) != 0;
257     SdrView* pDrView = pViewData->GetScDrawView();
258 
259     sal_Bool bDrawTextEdit = sal_False;
260     if (pDrView)
261         bDrawTextEdit = pDrView->IsTextEdit();
262 
263     // notes or change tracking
264 
265     if ( bHelpEnabled && !bDrawTextEdit )
266     {
267         Point       aPosPixel = ScreenToOutputPixel( rHEvt.GetMousePosPixel() );
268         SCsCOL nPosX;
269         SCsROW nPosY;
270         pViewData->GetPosFromPixel( aPosPixel.X(), aPosPixel.Y(), eWhich, nPosX, nPosY );
271 
272         if ( ShowNoteMarker( nPosX, nPosY, sal_False ) )
273         {
274             Window::RequestHelp( rHEvt ); // alte Tip/Balloon ausschalten
275             bDone = sal_True;
276         }
277     }
278 
279     if ( !bDone && pNoteMarker )
280     {
281         if ( pNoteMarker->IsByKeyboard() )
282         {
283             // marker which was shown for ctrl-F1 isn't removed by mouse events
284         }
285         else
286             DELETEZ(pNoteMarker);
287     }
288 
289     // Image-Map / Text-URL
290 
291     if ( bHelpEnabled && !bDone && !nButtonDown ) // nur ohne gedrueckten Button
292     {
293         String aHelpText;
294         Rectangle aPixRect;
295         Point aPosPixel = ScreenToOutputPixel( rHEvt.GetMousePosPixel() );
296 
297         if ( pDrView ) // URL / Image-Map
298         {
299             SdrViewEvent aVEvt;
300             MouseEvent aMEvt( aPosPixel, 1, 0, MOUSE_LEFT );
301             SdrHitKind eHit = pDrView->PickAnything( aMEvt, SDRMOUSEBUTTONDOWN, aVEvt );
302 
303             if ( eHit != SDRHIT_NONE && aVEvt.pObj != NULL )
304             {
305                 // URL fuer IMapObject unter Pointer ist Hilfetext
306                 if ( ScDrawLayer::GetIMapInfo( aVEvt.pObj ) )
307                 {
308                     Point aLogicPos = PixelToLogic( aPosPixel );
309                     IMapObject* pIMapObj = ScDrawLayer::GetHitIMapObject(
310                                                     aVEvt.pObj, aLogicPos, *this );
311 
312                     if ( pIMapObj )
313                     {
314                         // #44990# Bei ImageMaps die Description anzeigen, wenn vorhanden
315                         aHelpText = pIMapObj->GetAltText();
316                         if (!aHelpText.Len())
317                             aHelpText = pIMapObj->GetURL();
318                         aPixRect = LogicToPixel(aVEvt.pObj->GetLogicRect());
319                     }
320                 }
321                 // URL in shape text or at shape itself (URL in text overrides object URL)
322                 if ( aHelpText.Len() == 0 )
323                 {
324                     if( aVEvt.eEvent == SDREVENT_EXECUTEURL )
325                     {
326                         aHelpText = aVEvt.pURLField->GetURL();
327                         aPixRect = LogicToPixel(aVEvt.pObj->GetLogicRect());
328                     }
329                     else
330                     {
331                         SdrObject* pObj = 0;
332                         SdrPageView* pPV = 0;
333                         Point aMDPos = PixelToLogic( aPosPixel );
334                         if ( pDrView->PickObj(aMDPos, pDrView->getHitTolLog(), pObj, pPV, SDRSEARCH_ALSOONMASTER) )
335                         {
336                             if ( pObj->IsGroupObject() )
337                             {
338                                 SdrObject* pHit = 0;
339                                 if ( pDrView->PickObj(aMDPos, pDrView->getHitTolLog(), pHit, pPV, SDRSEARCH_DEEP ) )
340                                     pObj = pHit;
341                             }
342 #ifdef ISSUE66550_HLINK_FOR_SHAPES
343                             ScMacroInfo* pInfo = ScDrawLayer::GetMacroInfo( pObj );
344                             if ( pInfo && (pInfo->GetHlink().getLength() > 0) )
345                             {
346                                 aPixRect = LogicToPixel(aVEvt.pObj->GetLogicRect());
347                                 aHelpText = pInfo->GetHlink();
348                             }
349 #endif
350                     }
351                     }
352                 }
353             }
354         }
355 
356         if ( !aHelpText.Len() ) // Text-URL
357         {
358             String aUrl;
359             if ( GetEditUrl( aPosPixel, NULL, &aUrl, NULL ) )
360             {
361                 aHelpText = INetURLObject::decode( aUrl, INET_HEX_ESCAPE,
362                     INetURLObject::DECODE_UNAMBIGUOUS );
363 
364                 ScDocument* pDoc = pViewData->GetDocument();
365                 SCsCOL nPosX;
366                 SCsROW nPosY;
367                 SCTAB  nTab = pViewData->GetTabNo();
368                 pViewData->GetPosFromPixel( aPosPixel.X(), aPosPixel.Y(), eWhich, nPosX, nPosY );
369                 const ScPatternAttr* pPattern = pDoc->GetPattern( nPosX, nPosY, nTab );
370 
371                 ScHideTextCursor aHideCursor( pViewData, eWhich ); // MapMode is changed in GetEditArea
372 
373                 // bForceToTop = sal_False, use the cell's real position
374                 aPixRect = pViewData->GetEditArea( eWhich, nPosX, nPosY, this, pPattern, sal_False );
375             }
376         }
377 
378         if ( aHelpText.Len() )
379         {
380             Rectangle aScreenRect(OutputToScreenPixel(aPixRect.TopLeft()),
381                                     OutputToScreenPixel(aPixRect.BottomRight()));
382 
383             if ( rHEvt.GetMode() & HELPMODE_BALLOON )
384                 Help::ShowBalloon(this,rHEvt.GetMousePosPixel(), aScreenRect, aHelpText);
385             else if ( rHEvt.GetMode() & HELPMODE_QUICK )
386                 Help::ShowQuickHelp(this,aScreenRect, aHelpText);
387 
388             bDone = sal_True;
389         }
390     }
391 
392     // Basic-Controls
393 
394     if ( pDrView && bHelpEnabled && !bDone )
395     {
396         SdrPageView* pPV = pDrView->GetSdrPageView();
397         DBG_ASSERT( pPV, "SdrPageView* ist NULL" );
398         if (pPV)
399             bDone = ((ScDrawPage*)pPV->GetPage())->RequestHelp( this, pDrView, rHEvt );
400     }
401 
402     // Wenn QuickHelp fuer AutoFill angezeigt wird, nicht wieder wegnehmen lassen
403 
404     if ( nMouseStatus == SC_GM_TABDOWN && pViewData->GetRefType() == SC_REFTYPE_FILL &&
405             Help::IsQuickHelpEnabled() )
406         bDone = sal_True;
407 
408     if (!bDone)
409         Window::RequestHelp( rHEvt );
410 }
411 
IsMyModel(SdrEditView * pSdrView)412 sal_Bool ScGridWindow::IsMyModel(SdrEditView* pSdrView)
413 {
414     return pSdrView &&
415             pSdrView->GetModel() == pViewData->GetDocument()->GetDrawLayer();
416 }
417 
HideNoteMarker()418 void ScGridWindow::HideNoteMarker()
419 {
420     DELETEZ(pNoteMarker);
421 }
422 
423 com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
CreateAccessible()424     ScGridWindow::CreateAccessible()
425 {
426     com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > xAcc= GetAccessible(sal_False);
427     if (xAcc.is())
428     {
429         return xAcc;
430     }
431     ScAccessibleDocument* pAccessibleDocument =
432         new ScAccessibleDocument(GetAccessibleParentWindow()->GetAccessible(),
433             pViewData->GetViewShell(), eWhich);
434     xAcc = pAccessibleDocument;
435     SetAccessible(xAcc);
436 
437     pAccessibleDocument->Init();
438     return xAcc;
439 }
440 // MT: Removed Windows::SwitchView() introduced with IA2 CWS.
441 // There are other notifications for this when the active view has changed, so please update the code to use that event mechanism
SwitchView()442 void ScGridWindow::SwitchView()
443 {
444     if (!Application::IsAccessibilityEnabled())
445     {
446         return ;
447     }
448     ScAccessibleDocumentBase* pAccDoc = static_cast<ScAccessibleDocumentBase*>(GetAccessible(sal_False).get());
449     if (pAccDoc)
450     {
451         pAccDoc->SwitchViewFireFocus();
452     }
453 }
454