xref: /trunk/main/sc/source/ui/drawfunc/drtxtob.cxx (revision d9a8b508d8aa034253db7fbf48aa9812761b3d50)
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_EFFECT:
737             case SID_CHAR_DLG:                      // Dialog-Button
738             case SID_ATTR_CHAR_FONT:                // Controller nicht angezeigt
739             case SID_ATTR_CHAR_FONTHEIGHT:
740                 bDone = ExecuteCharDlg( aEditAttr, aNewAttr , nSlot);
741                 break;
742 
743             case SID_PARA_DLG:
744                 bDone = ExecuteParaDlg( aEditAttr, aNewAttr );
745                 break;
746 
747             case SID_ATTR_CHAR_WEIGHT:
748                 aNewAttr.Put( (const SvxWeightItem&)aEditAttr.Get( EE_CHAR_WEIGHT ) );
749                 break;
750 
751             case SID_ATTR_CHAR_POSTURE:
752                 aNewAttr.Put( (const SvxPostureItem&)aEditAttr.Get( EE_CHAR_ITALIC ) );
753                 break;
754 
755             case SID_ATTR_CHAR_UNDERLINE:
756                 aNewAttr.Put( (const SvxUnderlineItem&)aEditAttr.Get( EE_CHAR_UNDERLINE ) );
757                 break;
758 
759             case SID_ATTR_CHAR_OVERLINE:
760                 aNewAttr.Put( (const SvxOverlineItem&)aEditAttr.Get( EE_CHAR_OVERLINE ) );
761                 break;
762 
763             case SID_ATTR_CHAR_CONTOUR:
764                 aNewAttr.Put( (const SvxContourItem&)aEditAttr.Get( EE_CHAR_OUTLINE ) );
765                 break;
766 
767             case SID_ATTR_CHAR_SHADOWED:
768                 aNewAttr.Put( (const SvxShadowedItem&)aEditAttr.Get( EE_CHAR_SHADOW ) );
769                 break;
770 
771             case SID_ATTR_CHAR_STRIKEOUT:
772                 aNewAttr.Put( (const SvxCrossedOutItem&)aEditAttr.Get( EE_CHAR_STRIKEOUT ) );
773                 break;
774 
775             case SID_ALIGNLEFT:
776             case SID_ALIGN_ANY_LEFT:
777                 aNewAttr.Put( SvxAdjustItem( SVX_ADJUST_LEFT, EE_PARA_JUST ) );
778                 break;
779 
780             case SID_ALIGNCENTERHOR:
781             case SID_ALIGN_ANY_HCENTER:
782                 aNewAttr.Put( SvxAdjustItem( SVX_ADJUST_CENTER, EE_PARA_JUST ) );
783                 break;
784 
785             case SID_ALIGNRIGHT:
786             case SID_ALIGN_ANY_RIGHT:
787                 aNewAttr.Put( SvxAdjustItem( SVX_ADJUST_RIGHT, EE_PARA_JUST ) );
788                 break;
789 
790             case SID_ALIGNBLOCK:
791             case SID_ALIGN_ANY_JUSTIFIED:
792                 aNewAttr.Put( SvxAdjustItem( SVX_ADJUST_BLOCK, EE_PARA_JUST ) );
793                 break;
794 
795             case SID_ATTR_PARA_LINESPACE_10:
796                 {
797                     SvxLineSpacingItem aItem( SVX_LINESPACE_ONE_LINE, EE_PARA_SBL );
798                     aItem.SetPropLineSpace( 100 );
799                     aNewAttr.Put( aItem );
800                 }
801                 break;
802 
803             case SID_ATTR_PARA_LINESPACE_15:
804                 {
805                     SvxLineSpacingItem aItem( SVX_LINESPACE_ONE_POINT_FIVE_LINES, EE_PARA_SBL );
806                     aItem.SetPropLineSpace( 150 );
807                     aNewAttr.Put( aItem );
808                 }
809                 break;
810 
811             case SID_ATTR_PARA_LINESPACE_20:
812                 {
813                     SvxLineSpacingItem aItem( SVX_LINESPACE_TWO_LINES, EE_PARA_SBL );
814                     aItem.SetPropLineSpace( 200 );
815                     aNewAttr.Put( aItem );
816                 }
817                 break;
818 
819             case SID_SET_SUPER_SCRIPT:
820                 {
821                     SvxEscapementItem aItem(EE_CHAR_ESCAPEMENT);
822                     SvxEscapement eEsc = (SvxEscapement) ( (const SvxEscapementItem&)
823                                     aEditAttr.Get( EE_CHAR_ESCAPEMENT ) ).GetEnumValue();
824 
825                     if( eEsc == SVX_ESCAPEMENT_SUPERSCRIPT )
826                         aItem.SetEscapement( SVX_ESCAPEMENT_OFF );
827                     else
828                         aItem.SetEscapement( SVX_ESCAPEMENT_SUPERSCRIPT );
829                     aNewAttr.Put( aItem );
830                 }
831                 break;
832             case SID_SET_SUB_SCRIPT:
833                 {
834                     SvxEscapementItem aItem(EE_CHAR_ESCAPEMENT);
835                     SvxEscapement eEsc = (SvxEscapement) ( (const SvxEscapementItem&)
836                                     aEditAttr.Get( EE_CHAR_ESCAPEMENT ) ).GetEnumValue();
837 
838                     if( eEsc == SVX_ESCAPEMENT_SUBSCRIPT )
839                         aItem.SetEscapement( SVX_ESCAPEMENT_OFF );
840                     else
841                         aItem.SetEscapement( SVX_ESCAPEMENT_SUBSCRIPT );
842                     aNewAttr.Put( aItem );
843                 }
844                 break;
845 
846             case SID_DRAWTEXT_ATTR_DLG:
847                 {
848                     SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
849                     SfxAbstractTabDialog *pDlg = pFact->CreateTextTabDialog( pViewData->GetDialogParent(), &aEditAttr, pView );
850 
851                     bDone = ( RET_OK == pDlg->Execute() );
852 
853                     if ( bDone )
854                         aNewAttr.Put( *pDlg->GetOutputItemSet() );
855 
856                     delete pDlg;
857                 }
858                 break;
859         }
860 
861         if ( bDone ) // wurden Attribute geaendert?
862         {
863             rReq.Done( aNewAttr );
864             pArgs = rReq.GetArgs();
865         }
866     }
867 
868     if ( pArgs )
869     {
870         if ( bArgsInReq &&
871             ( nSlot == SID_ATTR_CHAR_FONT || nSlot == SID_ATTR_CHAR_FONTHEIGHT ||
872               nSlot == SID_ATTR_CHAR_WEIGHT || nSlot == SID_ATTR_CHAR_POSTURE ) )
873         {
874             // font items from toolbox controller have to be applied for the right script type
875 
876             // #i78017 establish the same behaviour as in Writer
877             sal_uInt16 nScript = SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | SCRIPTTYPE_COMPLEX;
878             if (nSlot == SID_ATTR_CHAR_FONT)
879                 nScript = pView->GetScriptType();
880 
881             SfxItemPool& rPool = GetPool();
882             SvxScriptSetItem aSetItem( nSlot, rPool );
883             sal_uInt16 nWhich = rPool.GetWhich( nSlot );
884             aSetItem.PutItemForScriptType( nScript, pArgs->Get( nWhich ) );
885 
886             pView->SetAttributes( aSetItem.GetItemSet() );
887         }
888         else
889         {
890             // use args directly
891 
892             pView->SetAttributes( *pArgs );
893         }
894         pViewData->GetScDrawView()->InvalidateDrawTextAttrs();
895     }
896 }
897 
898 void __EXPORT ScDrawTextObjectBar::GetAttrState( SfxItemSet& rDestSet )
899 {
900     if ( IsNoteEdit() )
901     {
902         // issue 21255 - Notes now support rich text formatting.
903     }
904 
905     SvtLanguageOptions  aLangOpt;
906     sal_Bool bDisableCTLFont = !aLangOpt.IsCTLFontEnabled();
907     sal_Bool bDisableVerticalText = !aLangOpt.IsVerticalTextEnabled();
908 
909     SdrView* pView = pViewData->GetScDrawView();
910     SfxItemSet aAttrSet(pView->GetModel()->GetItemPool());
911     pView->GetAttributes(aAttrSet);
912 
913     //  direkte Attribute
914 
915     rDestSet.Put( aAttrSet );
916 
917     //  choose font info according to selection script type
918 
919     sal_uInt16 nScript = pView->GetScriptType();
920 
921     // #i55929# input-language-dependent script type (depends on input language if nothing selected)
922     sal_uInt16 nInputScript = nScript;
923     OutlinerView* pOutView = pView->GetTextEditOutlinerView();
924     if (pOutView && !pOutView->GetSelection().HasRange())
925     {
926         LanguageType nInputLang = pViewData->GetActiveWin()->GetInputLanguage();
927         if (nInputLang != LANGUAGE_DONTKNOW && nInputLang != LANGUAGE_SYSTEM)
928             nInputScript = SvtLanguageOptions::GetScriptTypeOfLanguage( nInputLang );
929     }
930 
931     // #i55929# according to spec, nInputScript is used for font and font height only
932     if ( rDestSet.GetItemState( EE_CHAR_FONTINFO ) != SFX_ITEM_UNKNOWN )
933         ScViewUtil::PutItemScript( rDestSet, aAttrSet, EE_CHAR_FONTINFO, nInputScript );
934     if ( rDestSet.GetItemState( EE_CHAR_FONTHEIGHT ) != SFX_ITEM_UNKNOWN )
935         ScViewUtil::PutItemScript( rDestSet, aAttrSet, EE_CHAR_FONTHEIGHT, nInputScript );
936     if ( rDestSet.GetItemState( EE_CHAR_WEIGHT ) != SFX_ITEM_UNKNOWN )
937         ScViewUtil::PutItemScript( rDestSet, aAttrSet, EE_CHAR_WEIGHT, nScript );
938     if ( rDestSet.GetItemState( EE_CHAR_ITALIC ) != SFX_ITEM_UNKNOWN )
939         ScViewUtil::PutItemScript( rDestSet, aAttrSet, EE_CHAR_ITALIC, nScript );
940 
941     //  Ausrichtung
942 
943     SvxAdjust eAdj = ((const SvxAdjustItem&)aAttrSet.Get(EE_PARA_JUST)).GetAdjust();
944     switch( eAdj )
945     {
946         case SVX_ADJUST_LEFT:
947             rDestSet.Put( SfxBoolItem( SID_ALIGNLEFT, sal_True ) );
948             break;
949         case SVX_ADJUST_CENTER:
950             rDestSet.Put( SfxBoolItem( SID_ALIGNCENTERHOR, sal_True ) );
951             break;
952         case SVX_ADJUST_RIGHT:
953             rDestSet.Put( SfxBoolItem( SID_ALIGNRIGHT, sal_True ) );
954             break;
955         case SVX_ADJUST_BLOCK:
956             rDestSet.Put( SfxBoolItem( SID_ALIGNBLOCK, sal_True ) );
957             break;
958         default:
959         {
960             // added to avoid warnings
961         }
962     }
963     // pseudo slots for Format menu
964     rDestSet.Put( SfxBoolItem( SID_ALIGN_ANY_LEFT,      eAdj == SVX_ADJUST_LEFT ) );
965     rDestSet.Put( SfxBoolItem( SID_ALIGN_ANY_HCENTER,   eAdj == SVX_ADJUST_CENTER ) );
966     rDestSet.Put( SfxBoolItem( SID_ALIGN_ANY_RIGHT,     eAdj == SVX_ADJUST_RIGHT ) );
967     rDestSet.Put( SfxBoolItem( SID_ALIGN_ANY_JUSTIFIED, eAdj == SVX_ADJUST_BLOCK ) );
968 
969     //  Zeilenabstand
970 
971     sal_uInt16 nLineSpace = (sal_uInt16)
972                 ((const SvxLineSpacingItem&)aAttrSet.
973                         Get( EE_PARA_SBL )).GetPropLineSpace();
974     switch( nLineSpace )
975     {
976         case 100:
977             rDestSet.Put( SfxBoolItem( SID_ATTR_PARA_LINESPACE_10, sal_True ) );
978             break;
979         case 150:
980             rDestSet.Put( SfxBoolItem( SID_ATTR_PARA_LINESPACE_15, sal_True ) );
981             break;
982         case 200:
983             rDestSet.Put( SfxBoolItem( SID_ATTR_PARA_LINESPACE_20, sal_True ) );
984             break;
985     }
986 
987     //  hoch-/tiefgestellt
988 
989     SvxEscapement eEsc = (SvxEscapement) ( (const SvxEscapementItem&)
990                     aAttrSet.Get( EE_CHAR_ESCAPEMENT ) ).GetEnumValue();
991     if( eEsc == SVX_ESCAPEMENT_SUPERSCRIPT )
992         rDestSet.Put( SfxBoolItem( SID_SET_SUPER_SCRIPT, sal_True ) );
993     else if( eEsc == SVX_ESCAPEMENT_SUBSCRIPT )
994         rDestSet.Put( SfxBoolItem( SID_SET_SUB_SCRIPT, sal_True ) );
995 
996     //  Unterstreichung
997 
998     SfxItemState eState = aAttrSet.GetItemState( EE_CHAR_UNDERLINE, sal_True );
999     if ( eState == SFX_ITEM_DONTCARE )
1000     {
1001         rDestSet.InvalidateItem( SID_ULINE_VAL_NONE );
1002         rDestSet.InvalidateItem( SID_ULINE_VAL_SINGLE );
1003         rDestSet.InvalidateItem( SID_ULINE_VAL_DOUBLE );
1004         rDestSet.InvalidateItem( SID_ULINE_VAL_DOTTED );
1005     }
1006     else
1007     {
1008         FontUnderline eUnderline = ((const SvxUnderlineItem&)
1009                     aAttrSet.Get(EE_CHAR_UNDERLINE)).GetLineStyle();
1010         sal_uInt16 nId = SID_ULINE_VAL_NONE;
1011         switch (eUnderline)
1012         {
1013             case UNDERLINE_SINGLE:  nId = SID_ULINE_VAL_SINGLE; break;
1014             case UNDERLINE_DOUBLE:  nId = SID_ULINE_VAL_DOUBLE; break;
1015             case UNDERLINE_DOTTED:  nId = SID_ULINE_VAL_DOTTED; break;
1016             default:
1017                 break;
1018         }
1019         rDestSet.Put( SfxBoolItem( nId, sal_True ) );
1020     }
1021 
1022     //  horizontal / vertical
1023 
1024     sal_Bool bLeftToRight = sal_True;
1025 
1026     SdrOutliner* pOutl = pView->GetTextEditOutliner();
1027     if( pOutl )
1028     {
1029         if( pOutl->IsVertical() )
1030             bLeftToRight = sal_False;
1031     }
1032     else
1033         bLeftToRight = ( (const SvxWritingModeItem&) aAttrSet.Get( SDRATTR_TEXTDIRECTION ) ).GetValue() == com::sun::star::text::WritingMode_LR_TB;
1034 
1035     if ( bDisableVerticalText )
1036     {
1037         rDestSet.DisableItem( SID_TEXTDIRECTION_LEFT_TO_RIGHT );
1038         rDestSet.DisableItem( SID_TEXTDIRECTION_TOP_TO_BOTTOM );
1039     }
1040     else
1041     {
1042         rDestSet.Put( SfxBoolItem( SID_TEXTDIRECTION_LEFT_TO_RIGHT, bLeftToRight ) );
1043         rDestSet.Put( SfxBoolItem( SID_TEXTDIRECTION_TOP_TO_BOTTOM, !bLeftToRight ) );
1044     }
1045 
1046     //  left-to-right or right-to-left
1047 
1048     if ( !bLeftToRight || bDisableCTLFont )
1049     {
1050         //  disabled if vertical
1051         rDestSet.DisableItem( SID_ATTR_PARA_LEFT_TO_RIGHT );
1052         rDestSet.DisableItem( SID_ATTR_PARA_RIGHT_TO_LEFT );
1053     }
1054     else if ( aAttrSet.GetItemState( EE_PARA_WRITINGDIR ) == SFX_ITEM_DONTCARE )
1055     {
1056         rDestSet.InvalidateItem( SID_ATTR_PARA_LEFT_TO_RIGHT );
1057         rDestSet.InvalidateItem( SID_ATTR_PARA_RIGHT_TO_LEFT );
1058     }
1059     else
1060     {
1061         SvxFrameDirection eAttrDir = (SvxFrameDirection)((const SvxFrameDirectionItem&)
1062                                         aAttrSet.Get( EE_PARA_WRITINGDIR )).GetValue();
1063         if ( eAttrDir == FRMDIR_ENVIRONMENT )
1064         {
1065             //  get "environment" direction from page style
1066             if ( pViewData->GetDocument()->GetEditTextDirection( pViewData->GetTabNo() ) == EE_HTEXTDIR_R2L )
1067                 eAttrDir = FRMDIR_HORI_RIGHT_TOP;
1068             else
1069                 eAttrDir = FRMDIR_HORI_LEFT_TOP;
1070         }
1071         rDestSet.Put( SfxBoolItem( SID_ATTR_PARA_LEFT_TO_RIGHT, ( eAttrDir == FRMDIR_HORI_LEFT_TOP ) ) );
1072         rDestSet.Put( SfxBoolItem( SID_ATTR_PARA_RIGHT_TO_LEFT, ( eAttrDir == FRMDIR_HORI_RIGHT_TOP ) ) );
1073     }
1074 }
1075 
1076 void ScDrawTextObjectBar::ExecuteTrans( SfxRequest& rReq )
1077 {
1078     sal_Int32 nType = ScViewUtil::GetTransliterationType( rReq.GetSlot() );
1079     if ( nType )
1080     {
1081         ScDrawView* pView = pViewData->GetScDrawView();
1082         OutlinerView* pOutView = pView->GetTextEditOutlinerView();
1083         if ( pOutView )
1084         {
1085             //  change selected text in object
1086             pOutView->TransliterateText( nType );
1087         }
1088         else
1089         {
1090             //! apply to whole objects?
1091         }
1092     }
1093 }
1094