1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sc.hxx" 30 31 32 33 //------------------------------------------------------------------------- 34 35 #include <com/sun/star/linguistic2/XThesaurus.hpp> 36 #include <com/sun/star/lang/Locale.hpp> 37 38 #include "scitems.hxx" 39 40 #include <editeng/adjitem.hxx> 41 #include <svx/clipfmtitem.hxx> 42 #include <editeng/cntritem.hxx> 43 #include <editeng/crsditem.hxx> 44 #include <editeng/editeng.hxx> 45 #include <editeng/escpitem.hxx> 46 #include <editeng/flditem.hxx> 47 #include <editeng/fontitem.hxx> 48 #include <editeng/frmdiritem.hxx> 49 #include <svx/hlnkitem.hxx> 50 #include <editeng/lspcitem.hxx> 51 #include <svx/svdoutl.hxx> 52 #include <editeng/unolingu.hxx> 53 #include <editeng/outlobj.hxx> 54 #include <editeng/postitem.hxx> 55 #include <editeng/scripttypeitem.hxx> 56 #include <editeng/shdditem.hxx> 57 #include <svl/srchitem.hxx> 58 #include <editeng/udlnitem.hxx> 59 #include <editeng/wghtitem.hxx> 60 #include <editeng/writingmodeitem.hxx> 61 #include <sfx2/app.hxx> 62 #include <sfx2/dispatch.hxx> 63 #include <sfx2/objface.hxx> 64 #include <sfx2/objsh.hxx> 65 #include <sfx2/request.hxx> 66 #include <sfx2/viewfrm.hxx> 67 #include <svtools/cliplistener.hxx> 68 #include <svtools/transfer.hxx> 69 #include <svl/whiter.hxx> 70 #include <svl/languageoptions.hxx> 71 #include <vcl/msgbox.hxx> 72 73 #include <svx/svxdlg.hxx> 74 #include <svx/dialogs.hrc> 75 76 #include "sc.hrc" 77 #include "globstr.hrc" 78 #include "scmod.hxx" 79 #include "drtxtob.hxx" 80 #include "fudraw.hxx" 81 #include "viewdata.hxx" 82 #include "document.hxx" 83 #include "drawview.hxx" 84 #include "viewutil.hxx" 85 #include "scresid.hxx" 86 #include "tabvwsh.hxx" 87 88 #define ScDrawTextObjectBar 89 #include "scslots.hxx" 90 91 92 using namespace ::com::sun::star; 93 94 95 SFX_IMPL_INTERFACE( ScDrawTextObjectBar, SfxShell, ScResId(SCSTR_DRAWTEXTSHELL) ) 96 { 97 SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_OBJECT|SFX_VISIBILITY_STANDARD|SFX_VISIBILITY_SERVER, 98 ScResId(RID_TEXT_TOOLBOX) ); 99 SFX_POPUPMENU_REGISTRATION( ScResId(RID_POPUP_DRAWTEXT) ); 100 SFX_CHILDWINDOW_REGISTRATION( ScGetFontWorkId() ); 101 } 102 103 TYPEINIT1( ScDrawTextObjectBar, SfxShell ); 104 105 106 107 // abschalten der nicht erwuenschten Acceleratoren: 108 109 void ScDrawTextObjectBar::StateDisableItems( SfxItemSet &rSet ) 110 { 111 SfxWhichIter aIter(rSet); 112 sal_uInt16 nWhich = aIter.FirstWhich(); 113 114 while (nWhich) 115 { 116 rSet.DisableItem( nWhich ); 117 nWhich = aIter.NextWhich(); 118 } 119 } 120 121 ScDrawTextObjectBar::ScDrawTextObjectBar(ScViewData* pData) : 122 SfxShell(pData->GetViewShell()), 123 pViewData(pData), 124 pClipEvtLstnr(NULL), 125 bPastePossible(sal_False) 126 { 127 SetPool( pViewData->GetScDrawView()->GetDefaultAttr().GetPool() ); 128 129 // UndoManager wird beim Umschalten in den Edit-Modus umgesetzt... 130 ::svl::IUndoManager* pMgr = pViewData->GetSfxDocShell()->GetUndoManager(); 131 SetUndoManager( pMgr ); 132 if ( !pViewData->GetDocument()->IsUndoEnabled() ) 133 { 134 pMgr->SetMaxUndoActionCount( 0 ); 135 } 136 137 SetHelpId( HID_SCSHELL_DRTXTOB ); 138 SetName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("DrawText"))); 139 } 140 141 __EXPORT ScDrawTextObjectBar::~ScDrawTextObjectBar() 142 { 143 if ( pClipEvtLstnr ) 144 { 145 pClipEvtLstnr->AddRemoveListener( pViewData->GetActiveWin(), sal_False ); 146 147 // #122057# The listener may just now be waiting for the SolarMutex and call the link 148 // afterwards, in spite of RemoveListener. So the link has to be reset, too. 149 pClipEvtLstnr->ClearCallbackLink(); 150 151 pClipEvtLstnr->release(); 152 } 153 } 154 155 //======================================================================== 156 // 157 // Funktionen 158 // 159 //======================================================================== 160 161 void __EXPORT ScDrawTextObjectBar::Execute( SfxRequest &rReq ) 162 { 163 ScDrawView* pView = pViewData->GetScDrawView(); 164 OutlinerView* pOutView = pView->GetTextEditOutlinerView(); 165 Outliner* pOutliner = pView->GetTextEditOutliner(); 166 167 if (!pOutView || !pOutliner) 168 { 169 ExecuteGlobal( rReq ); // auf ganze Objekte 170 return; 171 } 172 173 const SfxItemSet* pReqArgs = rReq.GetArgs(); 174 sal_uInt16 nSlot = rReq.GetSlot(); 175 switch ( nSlot ) 176 { 177 case SID_COPY: 178 pOutView->Copy(); 179 break; 180 181 case SID_CUT: 182 pOutView->Cut(); 183 break; 184 185 case SID_PASTE: 186 pOutView->PasteSpecial(); 187 break; 188 189 case SID_CLIPBOARD_FORMAT_ITEMS: 190 { 191 sal_uLong nFormat = 0; 192 const SfxPoolItem* pItem; 193 if ( pReqArgs && 194 pReqArgs->GetItemState(nSlot, sal_True, &pItem) == SFX_ITEM_SET && 195 pItem->ISA(SfxUInt32Item) ) 196 { 197 nFormat = ((const SfxUInt32Item*)pItem)->GetValue(); 198 } 199 200 if ( nFormat ) 201 { 202 if (nFormat == SOT_FORMAT_STRING) 203 pOutView->Paste(); 204 else 205 pOutView->PasteSpecial(); 206 } 207 } 208 break; 209 210 case SID_PASTE_SPECIAL: 211 ExecutePasteContents( rReq ); 212 break; 213 214 case SID_SELECTALL: 215 { 216 sal_uLong nCount = pOutliner->GetParagraphCount(); 217 ESelection aSel( 0,0,(sal_uInt16)nCount,0 ); 218 pOutView->SetSelection( aSel ); 219 } 220 break; 221 222 case SID_CHARMAP: 223 { 224 const SvxFontItem& rItem = (const SvxFontItem&) 225 pOutView->GetAttribs().Get(EE_CHAR_FONTINFO); 226 227 String aString; 228 SvxFontItem aNewItem( EE_CHAR_FONTINFO ); 229 230 const SfxItemSet *pArgs = rReq.GetArgs(); 231 const SfxPoolItem* pItem = 0; 232 if( pArgs ) 233 pArgs->GetItemState(GetPool().GetWhich(SID_CHARMAP), sal_False, &pItem); 234 235 if ( pItem ) 236 { 237 aString = ((const SfxStringItem*)pItem)->GetValue(); 238 const SfxPoolItem* pFtItem = NULL; 239 pArgs->GetItemState( GetPool().GetWhich(SID_ATTR_SPECIALCHAR), sal_False, &pFtItem); 240 const SfxStringItem* pFontItem = PTR_CAST( SfxStringItem, pFtItem ); 241 if ( pFontItem ) 242 { 243 String aFontName(pFontItem->GetValue()); 244 Font aFont(aFontName, Size(1,1)); // Size nur wg. CTOR 245 aNewItem = SvxFontItem( aFont.GetFamily(), aFont.GetName(), 246 aFont.GetStyleName(), aFont.GetPitch(), 247 aFont.GetCharSet(), ATTR_FONT ); 248 } 249 else 250 aNewItem = rItem; 251 } 252 else 253 ScViewUtil::ExecuteCharMap( rItem, *pViewData->GetViewShell()->GetViewFrame(), aNewItem, aString ); 254 255 if ( aString.Len() ) 256 { 257 SfxItemSet aSet( pOutliner->GetEmptyItemSet() ); 258 aSet.Put( aNewItem ); 259 // SetAttribs an der View selektiert ein Wort, wenn nichts selektiert ist 260 pOutView->GetOutliner()->QuickSetAttribs( aSet, pOutView->GetSelection() ); 261 pOutView->InsertText(aString); 262 } 263 264 Invalidate( SID_ATTR_CHAR_FONT ); 265 } 266 break; 267 268 case SID_HYPERLINK_SETLINK: 269 if( pReqArgs ) 270 { 271 const SfxPoolItem* pItem; 272 if ( pReqArgs->GetItemState( SID_HYPERLINK_SETLINK, sal_True, &pItem ) == SFX_ITEM_SET ) 273 { 274 const SvxHyperlinkItem* pHyper = (const SvxHyperlinkItem*) pItem; 275 const String& rName = pHyper->GetName(); 276 const String& rURL = pHyper->GetURL(); 277 const String& rTarget = pHyper->GetTargetFrame(); 278 SvxLinkInsertMode eMode = pHyper->GetInsertMode(); 279 280 sal_Bool bDone = sal_False; 281 if ( pOutView && ( eMode == HLINK_DEFAULT || eMode == HLINK_FIELD ) ) 282 { 283 const SvxFieldItem* pFieldItem = pOutView->GetFieldAtSelection(); 284 if (pFieldItem) 285 { 286 const SvxFieldData* pField = pFieldItem->GetField(); 287 if ( pField && pField->ISA(SvxURLField) ) 288 { 289 // altes Feld selektieren 290 291 ESelection aSel = pOutView->GetSelection(); 292 aSel.Adjust(); 293 aSel.nEndPara = aSel.nStartPara; 294 aSel.nEndPos = aSel.nStartPos + 1; 295 pOutView->SetSelection( aSel ); 296 } 297 } 298 299 // neues Feld einfuegen 300 301 SvxURLField aURLField( rURL, rName, SVXURLFORMAT_REPR ); 302 aURLField.SetTargetFrame( rTarget ); 303 SvxFieldItem aURLItem( aURLField, EE_FEATURE_FIELD ); 304 pOutView->InsertField( aURLItem ); 305 306 // select new field 307 308 ESelection aSel = pOutView->GetSelection(); 309 if ( aSel.nStartPos == aSel.nEndPos && aSel.nStartPos > 0 ) 310 { 311 // Cursor is behind the inserted field -> extend selection to the left 312 313 --aSel.nStartPos; 314 pOutView->SetSelection( aSel ); 315 } 316 317 bDone = sal_True; 318 } 319 320 if (!bDone) 321 ExecuteGlobal( rReq ); // normal an der View 322 323 // InsertURL an der ViewShell schaltet bei "Text" die DrawShell ab !!! 324 } 325 } 326 break; 327 328 case SID_OPEN_HYPERLINK: 329 { 330 if ( pOutView ) 331 { 332 const SvxFieldItem* pFieldItem = pOutView->GetFieldAtSelection(); 333 if ( pFieldItem ) 334 { 335 const SvxFieldData* pField = pFieldItem->GetField(); 336 if( pField && pField->ISA( SvxURLField ) ) 337 { 338 const SvxURLField* pURLField = static_cast< const SvxURLField* >( pField ); 339 ScGlobal::OpenURL( pURLField->GetURL(), pURLField->GetTargetFrame() ); 340 } 341 } 342 } 343 } 344 break; 345 346 case SID_ENABLE_HYPHENATION: 347 case SID_TEXTDIRECTION_LEFT_TO_RIGHT: 348 case SID_TEXTDIRECTION_TOP_TO_BOTTOM: 349 #if 0 // DR 350 if (IsNoteEdit()) 351 { 352 pView->CaptionTextDirection( rReq.GetSlot()); // process Notes before we end the text edit. 353 ExecuteGlobal( rReq ); 354 pViewData->GetDispatcher().Execute(pViewData->GetView()->GetDrawFuncPtr()->GetSlotID(), SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD); 355 } 356 else 357 #endif 358 { 359 pView->ScEndTextEdit(); // end text edit before switching direction 360 ExecuteGlobal( rReq ); 361 // restore consistent state between shells and functions: 362 pViewData->GetDispatcher().Execute(SID_OBJECT_SELECT, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD); 363 } 364 break; 365 366 #if 0 367 // Hyphenation is handled above - text edit is ended 368 case SID_ENABLE_HYPHENATION: 369 // force loading of hyphenator (object is skipped in repaint) 370 ((ScDrawLayer*)pView->GetModel())->UseHyphenator(); 371 pOutliner->SetHyphenator( LinguMgr::GetHyphenator() ); 372 ExecuteGlobal( rReq ); 373 break; 374 #endif 375 376 case SID_THES: 377 { 378 String aReplaceText; 379 SFX_REQUEST_ARG( rReq, pItem2, SfxStringItem, SID_THES, sal_False ); 380 if (pItem2) 381 aReplaceText = pItem2->GetValue(); 382 if (aReplaceText.Len() > 0) 383 ReplaceTextWithSynonym( pOutView->GetEditView(), aReplaceText ); 384 } 385 break; 386 387 case SID_THESAURUS: 388 { 389 pOutView->StartThesaurus(); 390 } 391 break; 392 393 } 394 } 395 396 void __EXPORT ScDrawTextObjectBar::GetState( SfxItemSet& rSet ) 397 { 398 SfxViewFrame* pViewFrm = pViewData->GetViewShell()->GetViewFrame(); 399 sal_Bool bHasFontWork = pViewFrm->HasChildWindow(SID_FONTWORK); 400 sal_Bool bDisableFontWork = sal_False; 401 402 if (IsNoteEdit()) 403 { 404 // #i21255# notes now support rich text formatting (#i74140# but not fontwork) 405 bDisableFontWork = sal_True; 406 } 407 408 if ( bDisableFontWork ) 409 rSet.DisableItem( SID_FONTWORK ); 410 else 411 rSet.Put(SfxBoolItem(SID_FONTWORK, bHasFontWork)); 412 413 if ( rSet.GetItemState( SID_HYPERLINK_GETLINK ) != SFX_ITEM_UNKNOWN ) 414 { 415 SvxHyperlinkItem aHLinkItem; 416 SdrView* pView = pViewData->GetScDrawView(); 417 OutlinerView* pOutView = pView->GetTextEditOutlinerView(); 418 if ( pOutView ) 419 { 420 sal_Bool bField = sal_False; 421 const SvxFieldItem* pFieldItem = pOutView->GetFieldAtSelection(); 422 if (pFieldItem) 423 { 424 const SvxFieldData* pField = pFieldItem->GetField(); 425 if ( pField && pField->ISA(SvxURLField) ) 426 { 427 const SvxURLField* pURLField = (const SvxURLField*) pField; 428 aHLinkItem.SetName( pURLField->GetRepresentation() ); 429 aHLinkItem.SetURL( pURLField->GetURL() ); 430 aHLinkItem.SetTargetFrame( pURLField->GetTargetFrame() ); 431 bField = sal_True; 432 } 433 } 434 if (!bField) 435 { 436 // use selected text as name for urls 437 String sReturn = pOutView->GetSelected(); 438 sReturn.Erase(255); 439 sReturn.EraseTrailingChars(); 440 aHLinkItem.SetName(sReturn); 441 } 442 } 443 rSet.Put(aHLinkItem); 444 } 445 446 if ( rSet.GetItemState( SID_OPEN_HYPERLINK ) != SFX_ITEM_UNKNOWN ) 447 { 448 SdrView* pView = pViewData->GetScDrawView(); 449 OutlinerView* pOutView = pView->GetTextEditOutlinerView(); 450 bool bEnable = false; 451 if ( pOutView ) 452 { 453 const SvxFieldItem* pFieldItem = pOutView->GetFieldAtSelection(); 454 if ( pFieldItem ) 455 { 456 const SvxFieldData* pField = pFieldItem->GetField(); 457 bEnable = pField && pField->ISA( SvxURLField ); 458 } 459 } 460 if( !bEnable ) 461 rSet.DisableItem( SID_OPEN_HYPERLINK ); 462 } 463 464 if( rSet.GetItemState( SID_TRANSLITERATE_HALFWIDTH ) != SFX_ITEM_UNKNOWN ) 465 ScViewUtil::HideDisabledSlot( rSet, pViewFrm->GetBindings(), SID_TRANSLITERATE_HALFWIDTH ); 466 if( rSet.GetItemState( SID_TRANSLITERATE_FULLWIDTH ) != SFX_ITEM_UNKNOWN ) 467 ScViewUtil::HideDisabledSlot( rSet, pViewFrm->GetBindings(), SID_TRANSLITERATE_FULLWIDTH ); 468 if( rSet.GetItemState( SID_TRANSLITERATE_HIRAGANA ) != SFX_ITEM_UNKNOWN ) 469 ScViewUtil::HideDisabledSlot( rSet, pViewFrm->GetBindings(), SID_TRANSLITERATE_HIRAGANA ); 470 if( rSet.GetItemState( SID_TRANSLITERATE_KATAGANA ) != SFX_ITEM_UNKNOWN ) 471 ScViewUtil::HideDisabledSlot( rSet, pViewFrm->GetBindings(), SID_TRANSLITERATE_KATAGANA ); 472 473 if ( rSet.GetItemState( SID_ENABLE_HYPHENATION ) != SFX_ITEM_UNKNOWN ) 474 { 475 SdrView* pView = pViewData->GetScDrawView(); 476 SfxItemSet aAttrs( pView->GetModel()->GetItemPool() ); 477 pView->GetAttributes( aAttrs ); 478 if( aAttrs.GetItemState( EE_PARA_HYPHENATE ) >= SFX_ITEM_AVAILABLE ) 479 { 480 sal_Bool bValue = ( (const SfxBoolItem&) aAttrs.Get( EE_PARA_HYPHENATE ) ).GetValue(); 481 rSet.Put( SfxBoolItem( SID_ENABLE_HYPHENATION, bValue ) ); 482 } 483 } 484 485 if ( rSet.GetItemState( SID_THES ) != SFX_ITEM_UNKNOWN || 486 rSet.GetItemState( SID_THESAURUS ) != SFX_ITEM_UNKNOWN ) 487 { 488 SdrView * pView = pViewData->GetScDrawView(); 489 OutlinerView* pOutView = pView->GetTextEditOutlinerView(); 490 491 String aStatusVal; 492 LanguageType nLang = LANGUAGE_NONE; 493 bool bIsLookUpWord = false; 494 if ( pOutView ) 495 { 496 EditView& rEditView = pOutView->GetEditView(); 497 bIsLookUpWord = GetStatusValueForThesaurusFromContext( aStatusVal, nLang, rEditView ); 498 } 499 rSet.Put( SfxStringItem( SID_THES, aStatusVal ) ); 500 501 // disable thesaurus main menu and context menu entry if there is nothing to look up 502 sal_Bool bCanDoThesaurus = ScModule::HasThesaurusLanguage( nLang ); 503 if (!bIsLookUpWord || !bCanDoThesaurus) 504 rSet.DisableItem( SID_THES ); 505 if (!bCanDoThesaurus) 506 rSet.DisableItem( SID_THESAURUS ); 507 } 508 } 509 510 IMPL_LINK( ScDrawTextObjectBar, ClipboardChanged, TransferableDataHelper*, pDataHelper ) 511 { 512 if ( pDataHelper ) 513 { 514 bPastePossible = ( pDataHelper->HasFormat( SOT_FORMAT_STRING ) || pDataHelper->HasFormat( SOT_FORMAT_RTF ) ); 515 516 SfxBindings& rBindings = pViewData->GetBindings(); 517 rBindings.Invalidate( SID_PASTE ); 518 rBindings.Invalidate( SID_PASTE_SPECIAL ); 519 rBindings.Invalidate( SID_CLIPBOARD_FORMAT_ITEMS ); 520 } 521 return 0; 522 } 523 524 void __EXPORT ScDrawTextObjectBar::GetClipState( SfxItemSet& rSet ) 525 { 526 SdrView* pView = pViewData->GetScDrawView(); 527 if ( !pView->GetTextEditOutlinerView() ) 528 { 529 GetGlobalClipState( rSet ); 530 return; 531 } 532 533 if ( !pClipEvtLstnr ) 534 { 535 // create listener 536 pClipEvtLstnr = new TransferableClipboardListener( LINK( this, ScDrawTextObjectBar, ClipboardChanged ) ); 537 pClipEvtLstnr->acquire(); 538 Window* pWin = pViewData->GetActiveWin(); 539 pClipEvtLstnr->AddRemoveListener( pWin, sal_True ); 540 541 // get initial state 542 TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pViewData->GetActiveWin() ) ); 543 bPastePossible = ( aDataHelper.HasFormat( SOT_FORMAT_STRING ) || aDataHelper.HasFormat( SOT_FORMAT_RTF ) ); 544 } 545 546 SfxWhichIter aIter( rSet ); 547 sal_uInt16 nWhich = aIter.FirstWhich(); 548 while (nWhich) 549 { 550 switch (nWhich) 551 { 552 case SID_PASTE: 553 case SID_PASTE_SPECIAL: 554 if( !bPastePossible ) 555 rSet.DisableItem( nWhich ); 556 break; 557 case SID_CLIPBOARD_FORMAT_ITEMS: 558 if ( bPastePossible ) 559 { 560 SvxClipboardFmtItem aFormats( SID_CLIPBOARD_FORMAT_ITEMS ); 561 TransferableDataHelper aDataHelper( 562 TransferableDataHelper::CreateFromSystemClipboard( pViewData->GetActiveWin() ) ); 563 564 if ( aDataHelper.HasFormat( SOT_FORMAT_STRING ) ) 565 aFormats.AddClipbrdFormat( SOT_FORMAT_STRING ); 566 if ( aDataHelper.HasFormat( SOT_FORMAT_RTF ) ) 567 aFormats.AddClipbrdFormat( SOT_FORMAT_RTF ); 568 569 rSet.Put( aFormats ); 570 } 571 else 572 rSet.DisableItem( nWhich ); 573 break; 574 } 575 nWhich = aIter.NextWhich(); 576 } 577 } 578 579 //======================================================================== 580 // 581 // Attribute 582 // 583 //======================================================================== 584 585 void __EXPORT ScDrawTextObjectBar::ExecuteToggle( SfxRequest &rReq ) 586 { 587 // Unterstreichung 588 589 SdrView* pView = pViewData->GetScDrawView(); 590 591 sal_uInt16 nSlot = rReq.GetSlot(); 592 593 SfxItemSet aSet( pView->GetDefaultAttr() ); 594 595 SfxItemSet aViewAttr(pView->GetModel()->GetItemPool()); 596 pView->GetAttributes(aViewAttr); 597 598 // Unterstreichung 599 FontUnderline eOld = ((const SvxUnderlineItem&) aViewAttr. 600 Get(EE_CHAR_UNDERLINE)).GetLineStyle(); 601 FontUnderline eNew = eOld; 602 switch (nSlot) 603 { 604 case SID_ULINE_VAL_NONE: 605 eNew = UNDERLINE_NONE; 606 break; 607 case SID_ULINE_VAL_SINGLE: 608 eNew = ( eOld == UNDERLINE_SINGLE ) ? UNDERLINE_NONE : UNDERLINE_SINGLE; 609 break; 610 case SID_ULINE_VAL_DOUBLE: 611 eNew = ( eOld == UNDERLINE_DOUBLE ) ? UNDERLINE_NONE : UNDERLINE_DOUBLE; 612 break; 613 case SID_ULINE_VAL_DOTTED: 614 eNew = ( eOld == UNDERLINE_DOTTED ) ? UNDERLINE_NONE : UNDERLINE_DOTTED; 615 break; 616 default: 617 break; 618 } 619 aSet.Put( SvxUnderlineItem( eNew, EE_CHAR_UNDERLINE ) ); 620 621 pView->SetAttributes( aSet ); 622 rReq.Done(); 623 pViewData->GetScDrawView()->InvalidateDrawTextAttrs(); 624 } 625 626 void lcl_RemoveFields( OutlinerView& rOutView ) 627 { 628 //! Outliner should have RemoveFields with a selection 629 630 Outliner* pOutliner = rOutView.GetOutliner(); 631 if (!pOutliner) return; 632 633 ESelection aOldSel = rOutView.GetSelection(); 634 ESelection aSel = aOldSel; 635 aSel.Adjust(); 636 xub_StrLen nNewEnd = aSel.nEndPos; 637 638 sal_Bool bUpdate = pOutliner->GetUpdateMode(); 639 sal_Bool bChanged = sal_False; 640 641 //! GetPortions and GetAttribs should be const! 642 EditEngine& rEditEng = (EditEngine&)pOutliner->GetEditEngine(); 643 644 sal_uLong nParCount = pOutliner->GetParagraphCount(); 645 for (sal_uLong nPar=0; nPar<nParCount; nPar++) 646 if ( nPar >= aSel.nStartPara && nPar <= aSel.nEndPara ) 647 { 648 SvUShorts aPortions; 649 rEditEng.GetPortions( (sal_uInt16)nPar, aPortions ); 650 //! GetPortions should use xub_StrLen instead of USHORT 651 652 for ( sal_uInt16 nPos = aPortions.Count(); nPos; ) 653 { 654 --nPos; 655 sal_uInt16 nEnd = aPortions.GetObject( nPos ); 656 sal_uInt16 nStart = nPos ? aPortions.GetObject( nPos - 1 ) : 0; 657 // fields are single characters 658 if ( nEnd == nStart+1 && 659 ( nPar > aSel.nStartPara || nStart >= aSel.nStartPos ) && 660 ( nPar < aSel.nEndPara || nEnd <= aSel.nEndPos ) ) 661 { 662 ESelection aFieldSel( (sal_uInt16)nPar, nStart, (sal_uInt16)nPar, nEnd ); 663 SfxItemSet aSet = rEditEng.GetAttribs( aFieldSel ); 664 if ( aSet.GetItemState( EE_FEATURE_FIELD ) == SFX_ITEM_ON ) 665 { 666 if (!bChanged) 667 { 668 if (bUpdate) 669 pOutliner->SetUpdateMode( sal_False ); 670 String aName = ScGlobal::GetRscString( STR_UNDO_DELETECONTENTS ); 671 pOutliner->GetUndoManager().EnterListAction( aName, aName ); 672 bChanged = sal_True; 673 } 674 675 String aFieldText = rEditEng.GetText( aFieldSel ); 676 pOutliner->QuickInsertText( aFieldText, aFieldSel ); 677 if ( nPar == aSel.nEndPara ) 678 { 679 nNewEnd = sal::static_int_cast<xub_StrLen>( nNewEnd + aFieldText.Len() ); 680 --nNewEnd; 681 } 682 } 683 } 684 } 685 } 686 687 if (bUpdate && bChanged) 688 { 689 pOutliner->GetUndoManager().LeaveListAction(); 690 pOutliner->SetUpdateMode( sal_True ); 691 } 692 693 if ( aOldSel.IsEqual( aSel ) ) // aSel is adjusted 694 aOldSel.nEndPos = nNewEnd; 695 else 696 aOldSel.nStartPos = nNewEnd; // if aOldSel is backwards 697 rOutView.SetSelection( aOldSel ); 698 } 699 700 void __EXPORT ScDrawTextObjectBar::ExecuteAttr( SfxRequest &rReq ) 701 { 702 SdrView* pView = pViewData->GetScDrawView(); 703 const SfxItemSet* pArgs = rReq.GetArgs(); 704 sal_uInt16 nSlot = rReq.GetSlot(); 705 706 sal_Bool bArgsInReq = ( pArgs != NULL ); 707 if ( !bArgsInReq ) 708 { 709 SfxItemSet aEditAttr(pView->GetModel()->GetItemPool()); 710 pView->GetAttributes(aEditAttr); 711 SfxItemSet aNewAttr( *aEditAttr.GetPool(), aEditAttr.GetRanges() ); 712 sal_Bool bDone = sal_True; 713 714 switch ( nSlot ) 715 { 716 case SID_TEXT_STANDARD: // Harte Textattributierung loeschen 717 { 718 OutlinerView* pOutView = pView->IsTextEdit() ? 719 pView->GetTextEditOutlinerView() : NULL; 720 if ( pOutView ) 721 pOutView->Paint( Rectangle() ); 722 723 SfxItemSet aEmptyAttr( *aEditAttr.GetPool(), EE_ITEMS_START, EE_ITEMS_END ); 724 pView->SetAttributes( aEmptyAttr, sal_True ); 725 726 if ( pOutView ) 727 { 728 lcl_RemoveFields( *pOutView ); 729 pOutView->ShowCursor(); 730 } 731 732 rReq.Done( aEmptyAttr ); 733 pViewData->GetScDrawView()->InvalidateDrawTextAttrs(); 734 bDone = sal_False; // bereits hier passiert 735 } 736 break; 737 738 case SID_CHAR_DLG: // Dialog-Button 739 case SID_ATTR_CHAR_FONT: // Controller nicht angezeigt 740 case SID_ATTR_CHAR_FONTHEIGHT: 741 bDone = ExecuteCharDlg( aEditAttr, aNewAttr ); 742 break; 743 744 case SID_PARA_DLG: 745 bDone = ExecuteParaDlg( aEditAttr, aNewAttr ); 746 break; 747 748 case SID_ATTR_CHAR_WEIGHT: 749 aNewAttr.Put( (const SvxWeightItem&)aEditAttr.Get( EE_CHAR_WEIGHT ) ); 750 break; 751 752 case SID_ATTR_CHAR_POSTURE: 753 aNewAttr.Put( (const SvxPostureItem&)aEditAttr.Get( EE_CHAR_ITALIC ) ); 754 break; 755 756 case SID_ATTR_CHAR_UNDERLINE: 757 aNewAttr.Put( (const SvxUnderlineItem&)aEditAttr.Get( EE_CHAR_UNDERLINE ) ); 758 break; 759 760 case SID_ATTR_CHAR_OVERLINE: 761 aNewAttr.Put( (const SvxOverlineItem&)aEditAttr.Get( EE_CHAR_OVERLINE ) ); 762 break; 763 764 case SID_ATTR_CHAR_CONTOUR: 765 aNewAttr.Put( (const SvxContourItem&)aEditAttr.Get( EE_CHAR_OUTLINE ) ); 766 break; 767 768 case SID_ATTR_CHAR_SHADOWED: 769 aNewAttr.Put( (const SvxShadowedItem&)aEditAttr.Get( EE_CHAR_SHADOW ) ); 770 break; 771 772 case SID_ATTR_CHAR_STRIKEOUT: 773 aNewAttr.Put( (const SvxCrossedOutItem&)aEditAttr.Get( EE_CHAR_STRIKEOUT ) ); 774 break; 775 776 case SID_ALIGNLEFT: 777 case SID_ALIGN_ANY_LEFT: 778 aNewAttr.Put( SvxAdjustItem( SVX_ADJUST_LEFT, EE_PARA_JUST ) ); 779 break; 780 781 case SID_ALIGNCENTERHOR: 782 case SID_ALIGN_ANY_HCENTER: 783 aNewAttr.Put( SvxAdjustItem( SVX_ADJUST_CENTER, EE_PARA_JUST ) ); 784 break; 785 786 case SID_ALIGNRIGHT: 787 case SID_ALIGN_ANY_RIGHT: 788 aNewAttr.Put( SvxAdjustItem( SVX_ADJUST_RIGHT, EE_PARA_JUST ) ); 789 break; 790 791 case SID_ALIGNBLOCK: 792 case SID_ALIGN_ANY_JUSTIFIED: 793 aNewAttr.Put( SvxAdjustItem( SVX_ADJUST_BLOCK, EE_PARA_JUST ) ); 794 break; 795 796 case SID_ATTR_PARA_LINESPACE_10: 797 { 798 SvxLineSpacingItem aItem( SVX_LINESPACE_ONE_LINE, EE_PARA_SBL ); 799 aItem.SetPropLineSpace( 100 ); 800 aNewAttr.Put( aItem ); 801 } 802 break; 803 804 case SID_ATTR_PARA_LINESPACE_15: 805 { 806 SvxLineSpacingItem aItem( SVX_LINESPACE_ONE_POINT_FIVE_LINES, EE_PARA_SBL ); 807 aItem.SetPropLineSpace( 150 ); 808 aNewAttr.Put( aItem ); 809 } 810 break; 811 812 case SID_ATTR_PARA_LINESPACE_20: 813 { 814 SvxLineSpacingItem aItem( SVX_LINESPACE_TWO_LINES, EE_PARA_SBL ); 815 aItem.SetPropLineSpace( 200 ); 816 aNewAttr.Put( aItem ); 817 } 818 break; 819 820 case SID_SET_SUPER_SCRIPT: 821 { 822 SvxEscapementItem aItem(EE_CHAR_ESCAPEMENT); 823 SvxEscapement eEsc = (SvxEscapement) ( (const SvxEscapementItem&) 824 aEditAttr.Get( EE_CHAR_ESCAPEMENT ) ).GetEnumValue(); 825 826 if( eEsc == SVX_ESCAPEMENT_SUPERSCRIPT ) 827 aItem.SetEscapement( SVX_ESCAPEMENT_OFF ); 828 else 829 aItem.SetEscapement( SVX_ESCAPEMENT_SUPERSCRIPT ); 830 aNewAttr.Put( aItem ); 831 } 832 break; 833 case SID_SET_SUB_SCRIPT: 834 { 835 SvxEscapementItem aItem(EE_CHAR_ESCAPEMENT); 836 SvxEscapement eEsc = (SvxEscapement) ( (const SvxEscapementItem&) 837 aEditAttr.Get( EE_CHAR_ESCAPEMENT ) ).GetEnumValue(); 838 839 if( eEsc == SVX_ESCAPEMENT_SUBSCRIPT ) 840 aItem.SetEscapement( SVX_ESCAPEMENT_OFF ); 841 else 842 aItem.SetEscapement( SVX_ESCAPEMENT_SUBSCRIPT ); 843 aNewAttr.Put( aItem ); 844 } 845 break; 846 847 case SID_DRAWTEXT_ATTR_DLG: 848 { 849 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); 850 SfxAbstractTabDialog *pDlg = pFact->CreateTextTabDialog( pViewData->GetDialogParent(), &aEditAttr, pView ); 851 852 bDone = ( RET_OK == pDlg->Execute() ); 853 854 if ( bDone ) 855 aNewAttr.Put( *pDlg->GetOutputItemSet() ); 856 857 delete pDlg; 858 } 859 break; 860 } 861 862 if ( bDone ) // wurden Attribute geaendert? 863 { 864 rReq.Done( aNewAttr ); 865 pArgs = rReq.GetArgs(); 866 } 867 } 868 869 if ( pArgs ) 870 { 871 if ( bArgsInReq && 872 ( nSlot == SID_ATTR_CHAR_FONT || nSlot == SID_ATTR_CHAR_FONTHEIGHT || 873 nSlot == SID_ATTR_CHAR_WEIGHT || nSlot == SID_ATTR_CHAR_POSTURE ) ) 874 { 875 // font items from toolbox controller have to be applied for the right script type 876 877 // #i78017 establish the same behaviour as in Writer 878 sal_uInt16 nScript = SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | SCRIPTTYPE_COMPLEX; 879 if (nSlot == SID_ATTR_CHAR_FONT) 880 nScript = pView->GetScriptType(); 881 882 SfxItemPool& rPool = GetPool(); 883 SvxScriptSetItem aSetItem( nSlot, rPool ); 884 sal_uInt16 nWhich = rPool.GetWhich( nSlot ); 885 aSetItem.PutItemForScriptType( nScript, pArgs->Get( nWhich ) ); 886 887 pView->SetAttributes( aSetItem.GetItemSet() ); 888 } 889 else 890 { 891 // use args directly 892 893 pView->SetAttributes( *pArgs ); 894 } 895 pViewData->GetScDrawView()->InvalidateDrawTextAttrs(); 896 } 897 } 898 899 void __EXPORT ScDrawTextObjectBar::GetAttrState( SfxItemSet& rDestSet ) 900 { 901 if ( IsNoteEdit() ) 902 { 903 // issue 21255 - Notes now support rich text formatting. 904 } 905 906 SvtLanguageOptions aLangOpt; 907 sal_Bool bDisableCTLFont = !aLangOpt.IsCTLFontEnabled(); 908 sal_Bool bDisableVerticalText = !aLangOpt.IsVerticalTextEnabled(); 909 910 SdrView* pView = pViewData->GetScDrawView(); 911 SfxItemSet aAttrSet(pView->GetModel()->GetItemPool()); 912 pView->GetAttributes(aAttrSet); 913 914 // direkte Attribute 915 916 rDestSet.Put( aAttrSet ); 917 918 // choose font info according to selection script type 919 920 sal_uInt16 nScript = pView->GetScriptType(); 921 922 // #i55929# input-language-dependent script type (depends on input language if nothing selected) 923 sal_uInt16 nInputScript = nScript; 924 OutlinerView* pOutView = pView->GetTextEditOutlinerView(); 925 if (pOutView && !pOutView->GetSelection().HasRange()) 926 { 927 LanguageType nInputLang = pViewData->GetActiveWin()->GetInputLanguage(); 928 if (nInputLang != LANGUAGE_DONTKNOW && nInputLang != LANGUAGE_SYSTEM) 929 nInputScript = SvtLanguageOptions::GetScriptTypeOfLanguage( nInputLang ); 930 } 931 932 // #i55929# according to spec, nInputScript is used for font and font height only 933 if ( rDestSet.GetItemState( EE_CHAR_FONTINFO ) != SFX_ITEM_UNKNOWN ) 934 ScViewUtil::PutItemScript( rDestSet, aAttrSet, EE_CHAR_FONTINFO, nInputScript ); 935 if ( rDestSet.GetItemState( EE_CHAR_FONTHEIGHT ) != SFX_ITEM_UNKNOWN ) 936 ScViewUtil::PutItemScript( rDestSet, aAttrSet, EE_CHAR_FONTHEIGHT, nInputScript ); 937 if ( rDestSet.GetItemState( EE_CHAR_WEIGHT ) != SFX_ITEM_UNKNOWN ) 938 ScViewUtil::PutItemScript( rDestSet, aAttrSet, EE_CHAR_WEIGHT, nScript ); 939 if ( rDestSet.GetItemState( EE_CHAR_ITALIC ) != SFX_ITEM_UNKNOWN ) 940 ScViewUtil::PutItemScript( rDestSet, aAttrSet, EE_CHAR_ITALIC, nScript ); 941 942 // Ausrichtung 943 944 SvxAdjust eAdj = ((const SvxAdjustItem&)aAttrSet.Get(EE_PARA_JUST)).GetAdjust(); 945 switch( eAdj ) 946 { 947 case SVX_ADJUST_LEFT: 948 rDestSet.Put( SfxBoolItem( SID_ALIGNLEFT, sal_True ) ); 949 break; 950 case SVX_ADJUST_CENTER: 951 rDestSet.Put( SfxBoolItem( SID_ALIGNCENTERHOR, sal_True ) ); 952 break; 953 case SVX_ADJUST_RIGHT: 954 rDestSet.Put( SfxBoolItem( SID_ALIGNRIGHT, sal_True ) ); 955 break; 956 case SVX_ADJUST_BLOCK: 957 rDestSet.Put( SfxBoolItem( SID_ALIGNBLOCK, sal_True ) ); 958 break; 959 default: 960 { 961 // added to avoid warnings 962 } 963 } 964 // pseudo slots for Format menu 965 rDestSet.Put( SfxBoolItem( SID_ALIGN_ANY_LEFT, eAdj == SVX_ADJUST_LEFT ) ); 966 rDestSet.Put( SfxBoolItem( SID_ALIGN_ANY_HCENTER, eAdj == SVX_ADJUST_CENTER ) ); 967 rDestSet.Put( SfxBoolItem( SID_ALIGN_ANY_RIGHT, eAdj == SVX_ADJUST_RIGHT ) ); 968 rDestSet.Put( SfxBoolItem( SID_ALIGN_ANY_JUSTIFIED, eAdj == SVX_ADJUST_BLOCK ) ); 969 970 // Zeilenabstand 971 972 sal_uInt16 nLineSpace = (sal_uInt16) 973 ((const SvxLineSpacingItem&)aAttrSet. 974 Get( EE_PARA_SBL )).GetPropLineSpace(); 975 switch( nLineSpace ) 976 { 977 case 100: 978 rDestSet.Put( SfxBoolItem( SID_ATTR_PARA_LINESPACE_10, sal_True ) ); 979 break; 980 case 150: 981 rDestSet.Put( SfxBoolItem( SID_ATTR_PARA_LINESPACE_15, sal_True ) ); 982 break; 983 case 200: 984 rDestSet.Put( SfxBoolItem( SID_ATTR_PARA_LINESPACE_20, sal_True ) ); 985 break; 986 } 987 988 // hoch-/tiefgestellt 989 990 SvxEscapement eEsc = (SvxEscapement) ( (const SvxEscapementItem&) 991 aAttrSet.Get( EE_CHAR_ESCAPEMENT ) ).GetEnumValue(); 992 if( eEsc == SVX_ESCAPEMENT_SUPERSCRIPT ) 993 rDestSet.Put( SfxBoolItem( SID_SET_SUPER_SCRIPT, sal_True ) ); 994 else if( eEsc == SVX_ESCAPEMENT_SUBSCRIPT ) 995 rDestSet.Put( SfxBoolItem( SID_SET_SUB_SCRIPT, sal_True ) ); 996 997 // Unterstreichung 998 999 SfxItemState eState = aAttrSet.GetItemState( EE_CHAR_UNDERLINE, sal_True ); 1000 if ( eState == SFX_ITEM_DONTCARE ) 1001 { 1002 rDestSet.InvalidateItem( SID_ULINE_VAL_NONE ); 1003 rDestSet.InvalidateItem( SID_ULINE_VAL_SINGLE ); 1004 rDestSet.InvalidateItem( SID_ULINE_VAL_DOUBLE ); 1005 rDestSet.InvalidateItem( SID_ULINE_VAL_DOTTED ); 1006 } 1007 else 1008 { 1009 FontUnderline eUnderline = ((const SvxUnderlineItem&) 1010 aAttrSet.Get(EE_CHAR_UNDERLINE)).GetLineStyle(); 1011 sal_uInt16 nId = SID_ULINE_VAL_NONE; 1012 switch (eUnderline) 1013 { 1014 case UNDERLINE_SINGLE: nId = SID_ULINE_VAL_SINGLE; break; 1015 case UNDERLINE_DOUBLE: nId = SID_ULINE_VAL_DOUBLE; break; 1016 case UNDERLINE_DOTTED: nId = SID_ULINE_VAL_DOTTED; break; 1017 default: 1018 break; 1019 } 1020 rDestSet.Put( SfxBoolItem( nId, sal_True ) ); 1021 } 1022 1023 // horizontal / vertical 1024 1025 sal_Bool bLeftToRight = sal_True; 1026 1027 SdrOutliner* pOutl = pView->GetTextEditOutliner(); 1028 if( pOutl ) 1029 { 1030 if( pOutl->IsVertical() ) 1031 bLeftToRight = sal_False; 1032 } 1033 else 1034 bLeftToRight = ( (const SvxWritingModeItem&) aAttrSet.Get( SDRATTR_TEXTDIRECTION ) ).GetValue() == com::sun::star::text::WritingMode_LR_TB; 1035 1036 if ( bDisableVerticalText ) 1037 { 1038 rDestSet.DisableItem( SID_TEXTDIRECTION_LEFT_TO_RIGHT ); 1039 rDestSet.DisableItem( SID_TEXTDIRECTION_TOP_TO_BOTTOM ); 1040 } 1041 else 1042 { 1043 rDestSet.Put( SfxBoolItem( SID_TEXTDIRECTION_LEFT_TO_RIGHT, bLeftToRight ) ); 1044 rDestSet.Put( SfxBoolItem( SID_TEXTDIRECTION_TOP_TO_BOTTOM, !bLeftToRight ) ); 1045 } 1046 1047 // left-to-right or right-to-left 1048 1049 if ( !bLeftToRight || bDisableCTLFont ) 1050 { 1051 // disabled if vertical 1052 rDestSet.DisableItem( SID_ATTR_PARA_LEFT_TO_RIGHT ); 1053 rDestSet.DisableItem( SID_ATTR_PARA_RIGHT_TO_LEFT ); 1054 } 1055 else if ( aAttrSet.GetItemState( EE_PARA_WRITINGDIR ) == SFX_ITEM_DONTCARE ) 1056 { 1057 rDestSet.InvalidateItem( SID_ATTR_PARA_LEFT_TO_RIGHT ); 1058 rDestSet.InvalidateItem( SID_ATTR_PARA_RIGHT_TO_LEFT ); 1059 } 1060 else 1061 { 1062 SvxFrameDirection eAttrDir = (SvxFrameDirection)((const SvxFrameDirectionItem&) 1063 aAttrSet.Get( EE_PARA_WRITINGDIR )).GetValue(); 1064 if ( eAttrDir == FRMDIR_ENVIRONMENT ) 1065 { 1066 // get "environment" direction from page style 1067 if ( pViewData->GetDocument()->GetEditTextDirection( pViewData->GetTabNo() ) == EE_HTEXTDIR_R2L ) 1068 eAttrDir = FRMDIR_HORI_RIGHT_TOP; 1069 else 1070 eAttrDir = FRMDIR_HORI_LEFT_TOP; 1071 } 1072 rDestSet.Put( SfxBoolItem( SID_ATTR_PARA_LEFT_TO_RIGHT, ( eAttrDir == FRMDIR_HORI_LEFT_TOP ) ) ); 1073 rDestSet.Put( SfxBoolItem( SID_ATTR_PARA_RIGHT_TO_LEFT, ( eAttrDir == FRMDIR_HORI_RIGHT_TOP ) ) ); 1074 } 1075 } 1076 1077 void ScDrawTextObjectBar::ExecuteTrans( SfxRequest& rReq ) 1078 { 1079 sal_Int32 nType = ScViewUtil::GetTransliterationType( rReq.GetSlot() ); 1080 if ( nType ) 1081 { 1082 ScDrawView* pView = pViewData->GetScDrawView(); 1083 OutlinerView* pOutView = pView->GetTextEditOutlinerView(); 1084 if ( pOutView ) 1085 { 1086 // change selected text in object 1087 pOutView->TransliterateText( nType ); 1088 } 1089 else 1090 { 1091 //! apply to whole objects? 1092 } 1093 } 1094 } 1095 1096