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