1 /************************************************************************* * 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2008 by Sun Microsystems, Inc. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * $RCSfile: $ 10 * $Revision: $ 11 * 12 * This file is part of OpenOffice.org. 13 * 14 * OpenOffice.org is free software: you can redistribute it and/or modify 15 * it under the terms of the GNU Lesser General Public License version 3 16 * only, as published by the Free Software Foundation. 17 * 18 * OpenOffice.org is distributed in the hope that it will be useful, 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 * GNU Lesser General Public License version 3 for more details 22 * (a copy is included in the LICENSE file that accompanied this code). 23 * 24 * You should have received a copy of the GNU Lesser General Public License 25 * version 3 along with OpenOffice.org. If not, see 26 * <http://www.openoffice.org/license.html> 27 * for a copy of the LGPLv3 License. 28 * 29 ************************************************************************/ 30 31 32 #include "precompiled_sw.hxx" 33 34 #include <SidebarTxtControl.hxx> 35 36 #include <SidebarTxtControlAcc.hxx> 37 38 #include <SidebarWin.hxx> 39 #include <PostItMgr.hxx> 40 41 #include <cmdid.h> 42 #include <docvw.hrc> 43 44 #include <unotools/securityoptions.hxx> 45 46 #include <sfx2/viewfrm.hxx> 47 #include <sfx2/bindings.hxx> 48 #include <sfx2/dispatch.hxx> 49 #include <sfx2/mnumgr.hxx> 50 51 #include <vcl/svapp.hxx> 52 #include <vcl/help.hxx> 53 #include <vcl/msgbox.hxx> 54 #include <vcl/gradient.hxx> 55 #include <vcl/scrbar.hxx> 56 57 #include <editeng/outliner.hxx> 58 #include <editeng/editeng.hxx> 59 #include <editeng/editview.hxx> 60 #include <editeng/flditem.hxx> 61 62 #include <uitool.hxx> 63 #include <view.hxx> 64 #include <wrtsh.hxx> 65 #include <shellres.hxx> 66 #include <SwRewriter.hxx> 67 68 namespace css = ::com::sun::star; 69 70 namespace sw { namespace sidebarwindows { 71 72 SidebarTxtControl::SidebarTxtControl( SwSidebarWin& rSidebarWin, 73 WinBits nBits, 74 SwView& rDocView, 75 SwPostItMgr& rPostItMgr ) 76 : Control( &rSidebarWin, nBits ) 77 , mrSidebarWin( rSidebarWin ) 78 , mrDocView( rDocView ) 79 , mrPostItMgr( rPostItMgr ) 80 , mbMouseOver( false ) 81 { 82 AddEventListener( LINK( &mrSidebarWin, SwSidebarWin, WindowEventListener ) ); 83 } 84 85 SidebarTxtControl::~SidebarTxtControl() 86 { 87 RemoveEventListener( LINK( &mrSidebarWin, SwSidebarWin, WindowEventListener ) ); 88 } 89 90 OutlinerView* SidebarTxtControl::GetTextView() const 91 { 92 return mrSidebarWin.GetOutlinerView(); 93 } 94 95 void SidebarTxtControl::GetFocus() 96 { 97 Window::GetFocus(); 98 if ( !mrSidebarWin.IsMouseOver() ) 99 { 100 Invalidate(); 101 } 102 } 103 104 void SidebarTxtControl::LoseFocus() 105 { 106 // write the visible text back into the SwField 107 mrSidebarWin.UpdateData(); 108 109 Window::LoseFocus(); 110 if ( !mrSidebarWin.IsMouseOver() ) 111 { 112 Invalidate(); 113 } 114 } 115 116 void SidebarTxtControl::RequestHelp(const HelpEvent &rEvt) 117 { 118 sal_uInt16 nResId = 0; 119 switch( mrSidebarWin.GetLayoutStatus() ) 120 { 121 case SwPostItHelper::INSERTED: nResId = STR_REDLINE_INSERT; break; 122 case SwPostItHelper::DELETED: nResId = STR_REDLINE_DELETE; break; 123 default: nResId = 0; 124 } 125 126 SwContentAtPos aCntntAtPos( SwContentAtPos::SW_REDLINE ); 127 if ( nResId && 128 mrDocView.GetWrtShell().GetContentAtPos( mrSidebarWin.GetAnchorPos(), aCntntAtPos ) ) 129 { 130 String sTxt; 131 sTxt = SW_RESSTR( nResId ); 132 sTxt.AppendAscii( RTL_CONSTASCII_STRINGPARAM(": " )); 133 sTxt += aCntntAtPos.aFnd.pRedl->GetAuthorString(); 134 sTxt.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " - " )); 135 sTxt += GetAppLangDateTimeString( aCntntAtPos.aFnd.pRedl->GetTimeStamp() ); 136 Help::ShowQuickHelp( this,PixelToLogic(Rectangle(rEvt.GetMousePosPixel(),Size(50,10))),sTxt); 137 } 138 } 139 140 void SidebarTxtControl::Paint( const Rectangle& rRect) 141 { 142 if ( !Application::GetSettings().GetStyleSettings().GetHighContrastMode() ) 143 { 144 if ( mrSidebarWin.IsMouseOverSidebarWin() || 145 HasFocus() ) 146 { 147 DrawGradient( Rectangle( Point(0,0), PixelToLogic(GetSizePixel()) ), 148 Gradient( GRADIENT_LINEAR, 149 mrSidebarWin.ColorDark(), 150 mrSidebarWin.ColorDark() ) ); 151 } 152 else 153 { 154 DrawGradient( Rectangle( Point(0,0), PixelToLogic(GetSizePixel()) ), 155 Gradient( GRADIENT_LINEAR, 156 mrSidebarWin.ColorLight(), 157 mrSidebarWin.ColorDark())); 158 } 159 } 160 161 if ( GetTextView() ) 162 { 163 GetTextView()->Paint( rRect ); 164 } 165 166 if ( mrSidebarWin.GetLayoutStatus()==SwPostItHelper::DELETED ) 167 { 168 SetLineColor(mrSidebarWin.GetChangeColor()); 169 DrawLine( PixelToLogic( GetPosPixel() ), 170 PixelToLogic( GetPosPixel() + 171 Point( GetSizePixel().Width(), 172 GetSizePixel().Height() ) ) ); 173 DrawLine( PixelToLogic( GetPosPixel() + 174 Point( GetSizePixel().Width(),0) ), 175 PixelToLogic( GetPosPixel() + 176 Point( 0, GetSizePixel().Height() ) ) ); 177 } 178 } 179 180 void SidebarTxtControl::KeyInput( const KeyEvent& rKeyEvt ) 181 { 182 const KeyCode& rKeyCode = rKeyEvt.GetKeyCode(); 183 sal_uInt16 nKey = rKeyCode.GetCode(); 184 if ( ( rKeyCode.IsMod1() && rKeyCode.IsMod2() ) && 185 ( (nKey == KEY_PAGEUP) || (nKey == KEY_PAGEDOWN) ) ) 186 { 187 mrSidebarWin.SwitchToPostIt(nKey); 188 } 189 else if ( nKey == KEY_ESCAPE || 190 ( rKeyCode.IsMod1() && 191 ( nKey == KEY_PAGEUP || 192 nKey == KEY_PAGEDOWN ) ) ) 193 { 194 mrSidebarWin.SwitchToFieldPos(); 195 } 196 else if ( nKey == KEY_INSERT ) 197 { 198 if ( !rKeyCode.IsMod1() && !rKeyCode.IsMod2() ) 199 { 200 mrSidebarWin.ToggleInsMode(); 201 } 202 } 203 else 204 { 205 //let's make sure we see our note 206 mrPostItMgr.MakeVisible(&mrSidebarWin); 207 208 long aOldHeight = mrSidebarWin.GetPostItTextHeight(); 209 bool bDone = false; 210 211 /// HACK: need to switch off processing of Undo/Redo in Outliner 212 if ( !( (nKey == KEY_Z || nKey == KEY_Y) && rKeyCode.IsMod1()) ) 213 { 214 bool bIsProtected = mrSidebarWin.IsProtected(); 215 if ( !bIsProtected || 216 ( bIsProtected && 217 !mrSidebarWin.GetOutlinerView()->GetOutliner()->GetEditEngine().DoesKeyChangeText(rKeyEvt)) ) 218 { 219 bDone = GetTextView() && GetTextView()->PostKeyEvent( rKeyEvt ); 220 } 221 else 222 { 223 InfoBox( this, SW_RES( MSG_READONLY_CONTENT )).Execute(); 224 } 225 } 226 if (bDone) 227 mrSidebarWin.ResizeIfNeccessary( aOldHeight, mrSidebarWin.GetPostItTextHeight() ); 228 else 229 { 230 // write back data first when showing navigator 231 if ( nKey==KEY_F5 ) 232 mrSidebarWin.UpdateData(); 233 if (!mrDocView.KeyInput(rKeyEvt)) 234 Window::KeyInput(rKeyEvt); 235 } 236 } 237 238 mrDocView.GetViewFrame()->GetBindings().InvalidateAll(sal_False); 239 } 240 241 void SidebarTxtControl::MouseMove( const MouseEvent& rMEvt ) 242 { 243 if ( GetTextView() ) 244 { 245 OutlinerView* pOutlinerView( GetTextView() ); 246 pOutlinerView->MouseMove( rMEvt ); 247 // mba: why does OutlinerView not handle the modifier setting?! 248 // this forces the postit to handle *all* pointer types 249 SetPointer( pOutlinerView->GetPointer( rMEvt.GetPosPixel() ) ); 250 251 const EditView& aEV = pOutlinerView->GetEditView(); 252 const SvxFieldItem* pItem = aEV.GetFieldUnderMousePointer(); 253 if ( pItem ) 254 { 255 const SvxFieldData* pFld = pItem->GetField(); 256 const SvxURLField* pURL = PTR_CAST( SvxURLField, pFld ); 257 if ( pURL ) 258 { 259 String sURL( pURL->GetURL() ); 260 SvtSecurityOptions aSecOpts; 261 if ( aSecOpts.IsOptionSet( SvtSecurityOptions::E_CTRLCLICK_HYPERLINK) ) 262 { 263 sURL.InsertAscii( ": ", 0 ); 264 sURL.Insert( ViewShell::GetShellRes()->aHyperlinkClick, 0 ); 265 } 266 Help::ShowQuickHelp( this,PixelToLogic(Rectangle(GetPosPixel(),Size(50,10))),sURL); 267 } 268 } 269 } 270 } 271 272 void SidebarTxtControl::MouseButtonDown( const MouseEvent& rMEvt ) 273 { 274 if ( GetTextView() ) 275 { 276 SvtSecurityOptions aSecOpts; 277 bool bExecuteMod = aSecOpts.IsOptionSet( SvtSecurityOptions::E_CTRLCLICK_HYPERLINK); 278 279 if ( !bExecuteMod || (bExecuteMod && rMEvt.GetModifier() == KEY_MOD1)) 280 { 281 const EditView& aEV = GetTextView()->GetEditView(); 282 const SvxFieldItem* pItem = aEV.GetFieldUnderMousePointer(); 283 if ( pItem ) 284 { 285 const SvxFieldData* pFld = pItem->GetField(); 286 const SvxURLField* pURL = PTR_CAST( SvxURLField, pFld ); 287 if ( pURL ) 288 { 289 GetTextView()->MouseButtonDown( rMEvt ); 290 SwWrtShell &rSh = mrDocView.GetWrtShell(); 291 String sURL( pURL->GetURL() ); 292 String sTarget( pURL->GetTargetFrame() ); 293 ::LoadURL( sURL, &rSh, URLLOAD_NOFILTER, &sTarget); 294 return; 295 } 296 } 297 } 298 } 299 300 GrabFocus(); 301 if ( GetTextView() ) 302 { 303 GetTextView()->MouseButtonDown( rMEvt ); 304 } 305 mrDocView.GetViewFrame()->GetBindings().InvalidateAll(sal_False); 306 } 307 308 void SidebarTxtControl::MouseButtonUp( const MouseEvent& rMEvt ) 309 { 310 if ( GetTextView() ) 311 GetTextView()->MouseButtonUp( rMEvt ); 312 } 313 314 IMPL_LINK( SidebarTxtControl, OnlineSpellCallback, SpellCallbackInfo*, pInfo ) 315 { 316 if ( pInfo->nCommand == SPELLCMD_STARTSPELLDLG ) 317 { 318 mrDocView.GetViewFrame()->GetDispatcher()->Execute( FN_SPELL_GRAMMAR_DIALOG, SFX_CALLMODE_ASYNCHRON); 319 } 320 return 0; 321 } 322 323 IMPL_LINK( SidebarTxtControl, Select, Menu*, pSelMenu ) 324 { 325 mrSidebarWin.ExecuteCommand( pSelMenu->GetCurItemId() ); 326 return 0; 327 } 328 329 void SidebarTxtControl::Command( const CommandEvent& rCEvt ) 330 { 331 if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU ) 332 { 333 if ( !mrSidebarWin.IsProtected() && 334 GetTextView() && 335 GetTextView()->IsWrongSpelledWordAtPos( rCEvt.GetMousePosPixel(),sal_True )) 336 { 337 Link aLink = LINK(this, SidebarTxtControl, OnlineSpellCallback); 338 GetTextView()->ExecuteSpellPopup(rCEvt.GetMousePosPixel(),&aLink); 339 } 340 else 341 { 342 SfxPopupMenuManager* pMgr = mrDocView.GetViewFrame()->GetDispatcher()->Popup(0, this,&rCEvt.GetMousePosPixel()); 343 ((PopupMenu*)pMgr->GetSVMenu())->SetSelectHdl( LINK(this, SidebarTxtControl, Select) ); 344 345 { 346 XubString aText = ((PopupMenu*)pMgr->GetSVMenu())->GetItemText( FN_DELETE_NOTE_AUTHOR ); 347 SwRewriter aRewriter; 348 aRewriter.AddRule(UNDO_ARG1, mrSidebarWin.GetAuthor()); 349 aText = aRewriter.Apply(aText); 350 ((PopupMenu*)pMgr->GetSVMenu())->SetItemText(FN_DELETE_NOTE_AUTHOR,aText); 351 } 352 353 Point aPos; 354 if (rCEvt.IsMouseEvent()) 355 aPos = rCEvt.GetMousePosPixel(); 356 else 357 { 358 const Size aSize = GetSizePixel(); 359 aPos = Point( aSize.getWidth()/2, aSize.getHeight()/2 ); 360 } 361 362 //!! call different Execute function to get rid of the new thesaurus sub menu 363 //!! pointer created in the call to Popup. 364 //!! Otherwise we would have a memory leak (see also #i107205#) 365 //((PopupMenu*)pMgr->GetSVMenu())->Execute( this, aPos ); 366 pMgr->Execute( aPos, this ); 367 delete pMgr; 368 } 369 } 370 else 371 if (rCEvt.GetCommand() == COMMAND_WHEEL) 372 { 373 if (mrSidebarWin.IsScrollbarVisible()) 374 { 375 const CommandWheelData* pData = rCEvt.GetWheelData(); 376 if (pData->IsShift() || pData->IsMod1() || pData->IsMod2()) 377 { 378 mrDocView.HandleWheelCommands(rCEvt); 379 } 380 else 381 { 382 HandleScrollCommand( rCEvt, 0 , mrSidebarWin.Scrollbar()); 383 } 384 } 385 else 386 { 387 mrDocView.HandleWheelCommands(rCEvt); 388 } 389 } 390 else 391 { 392 if ( GetTextView() ) 393 GetTextView()->Command( rCEvt ); 394 else 395 Window::Command(rCEvt); 396 } 397 } 398 399 XubString SidebarTxtControl::GetSurroundingText() const 400 { 401 if( GetTextView() ) 402 return GetTextView()->GetSurroundingText(); 403 else 404 return XubString::EmptyString(); 405 } 406 407 Selection SidebarTxtControl::GetSurroundingTextSelection() const 408 { 409 if( GetTextView() ) 410 return GetTextView()->GetSurroundingTextSelection(); 411 else 412 return Selection( 0, 0 ); 413 } 414 415 css::uno::Reference< css::accessibility::XAccessible > SidebarTxtControl::CreateAccessible() 416 { 417 418 SidebarTxtControlAccessible* pAcc( new SidebarTxtControlAccessible( *this ) ); 419 css::uno::Reference< css::awt::XWindowPeer > xWinPeer( pAcc ); 420 SetWindowPeer( xWinPeer, pAcc ); 421 422 css::uno::Reference< css::accessibility::XAccessible > xAcc( xWinPeer, css::uno::UNO_QUERY ); 423 return xAcc; 424 } 425 426 } } // end of namespace sw::sidebarwindows 427 428