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