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