xref: /trunk/main/sc/source/ui/drawfunc/drtxtob.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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