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