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