xref: /core/sd/source/ui/func/fubullet.cxx (revision 430b3f4d)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <fubullet.hxx>
21 
22 #include <sfx2/bindings.hxx>
23 #include <sfx2/viewfrm.hxx>
24 #include <editeng/eeitem.hxx>
25 #include <svl/poolitem.hxx>
26 #include <editeng/fontitem.hxx>
27 #include <OutlineView.hxx>
28 #include <OutlineViewShell.hxx>
29 #include <DrawViewShell.hxx>
30 #include <ViewShellBase.hxx>
31 #include <Window.hxx>
32 #include <drawdoc.hxx>
33 #include <strings.hrc>
34 #include <sdresid.hxx>
35 #include <svx/svdoutl.hxx>
36 #include <sfx2/request.hxx>
37 #include <svl/ctloptions.hxx>
38 #include <svl/itempool.hxx>
39 #include <svl/stritem.hxx>
40 #include <tools/debug.hxx>
41 
42 #include <svx/svxdlg.hxx>
43 #include <svx/svxids.hrc>
44 
45 namespace sd {
46 
47 const sal_Unicode CHAR_HARDBLANK    =   u'\x00A0';
48 const sal_Unicode CHAR_HARDHYPHEN   =   u'\x2011';
49 const sal_Unicode CHAR_SOFTHYPHEN   =   u'\x00AD';
50 const sal_Unicode CHAR_RLM          =   u'\x200F';
51 const sal_Unicode CHAR_LRM          =   u'\x200E';
52 const sal_Unicode CHAR_ZWSP         =   u'\x200B';
53 const sal_Unicode CHAR_ZWNBSP       =   u'\x2060';
54 const sal_Unicode CHAR_NNBSP        =   u'\x202F'; //NARROW NO-BREAK SPACE
55 
56 
57 FuBullet::FuBullet (
58     ViewShell* pViewSh,
59     ::sd::Window* pWin,
60     ::sd::View* _pView,
61     SdDrawDocument* pDoc,
62     SfxRequest& rReq)
63     : FuPoor(pViewSh, pWin, _pView, pDoc, rReq)
64 {
65 }
66 
67 rtl::Reference<FuPoor> FuBullet::Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq )
68 {
69     rtl::Reference<FuPoor> xFunc( new FuBullet( pViewSh, pWin, pView, pDoc, rReq ) );
70     xFunc->DoExecute(rReq);
71     return xFunc;
72 }
73 
74 void FuBullet::DoExecute( SfxRequest& rReq )
75 {
76     if( rReq.GetSlot() == SID_CHARMAP )
77         InsertSpecialCharacter(rReq);
78     else
79     {
80         sal_Unicode cMark = 0;
81         switch( rReq.GetSlot() )
82         {
83             case FN_INSERT_SOFT_HYPHEN: cMark = CHAR_SOFTHYPHEN ; break;
84             case FN_INSERT_HARDHYPHEN:  cMark = CHAR_HARDHYPHEN ; break;
85             case FN_INSERT_HARD_SPACE:  cMark = CHAR_HARDBLANK ; break;
86             case FN_INSERT_NNBSP:  cMark = CHAR_NNBSP ; break;
87             case SID_INSERT_RLM : cMark = CHAR_RLM ; break;
88             case SID_INSERT_LRM : cMark = CHAR_LRM ; break;
89             case SID_INSERT_ZWSP : cMark = CHAR_ZWSP ; break;
90             case SID_INSERT_ZWNBSP: cMark = CHAR_ZWNBSP; break;
91         }
92 
93         DBG_ASSERT( cMark != 0, "FuBullet::FuBullet(), illegal slot used!" );
94 
95         if( cMark )
96             InsertFormattingMark( cMark );
97     }
98 
99 }
100 
101 void FuBullet::InsertFormattingMark( sal_Unicode cMark )
102 {
103     OutlinerView* pOV = nullptr;
104     ::Outliner*   pOL = nullptr;
105 
106     // depending on ViewShell set Outliner and OutlinerView
107     if( dynamic_cast< const DrawViewShell *>( mpViewShell ) !=  nullptr)
108     {
109         pOV = mpView->GetTextEditOutlinerView();
110         if (pOV)
111             pOL = mpView->GetTextEditOutliner();
112     }
113     else if( dynamic_cast< const OutlineViewShell *>( mpViewShell ) !=  nullptr)
114     {
115         pOL = &static_cast<OutlineView*>(mpView)->GetOutliner();
116         pOV = static_cast<OutlineView*>(mpView)->GetViewByWindow(
117             mpViewShell->GetActiveWindow());
118     }
119 
120     // insert string
121     if(!(pOV && pOL))
122         return;
123 
124     // prevent flickering
125     pOV->HideCursor();
126     pOL->SetUpdateMode(false);
127 
128     // remove old selected text
129     pOV->InsertText( "" );
130 
131     // prepare undo
132     SfxUndoManager& rUndoMgr =  pOL->GetUndoManager();
133     rUndoMgr.EnterListAction(SdResId(STR_UNDO_INSERT_SPECCHAR),
134                                 "", 0, mpViewShell->GetViewShellBase().GetViewShellId() );
135 
136     // insert given text
137     OUString aStr( cMark );
138     pOV->InsertText( aStr, true);
139 
140     ESelection aSel = pOV->GetSelection();
141     aSel.nStartPara = aSel.nEndPara;
142     aSel.nStartPos = aSel.nEndPos;
143     pOV->SetSelection(aSel);
144 
145     rUndoMgr.LeaveListAction();
146 
147     // restart repainting
148     pOL->SetUpdateMode(true);
149     pOV->ShowCursor();
150 }
151 
152 void FuBullet::InsertSpecialCharacter( SfxRequest const & rReq )
153 {
154     const SfxItemSet *pArgs = rReq.GetArgs();
155     const SfxPoolItem* pItem = nullptr;
156     if( pArgs )
157         pArgs->GetItemState(mpDoc->GetPool().GetWhich(SID_CHARMAP), false, &pItem);
158 
159     OUString aChars;
160     vcl::Font aFont;
161     if ( pItem )
162     {
163         aChars = static_cast<const SfxStringItem*>(pItem)->GetValue();
164         const SfxPoolItem* pFtItem = nullptr;
165         pArgs->GetItemState( mpDoc->GetPool().GetWhich(SID_ATTR_SPECIALCHAR), false, &pFtItem);
166         const SfxStringItem* pFontItem = dynamic_cast<const SfxStringItem*>( pFtItem  );
167         if ( pFontItem )
168         {
169             const OUString& aFontName = pFontItem->GetValue();
170             aFont = vcl::Font( aFontName, Size(1,1) );
171         }
172         else
173         {
174             SfxItemSet aFontAttr( mpDoc->GetPool() );
175             mpView->GetAttributes( aFontAttr );
176             const SvxFontItem* pFItem = static_cast<const SvxFontItem*>(aFontAttr.GetItem( SID_ATTR_CHAR_FONT ));
177             if( pFItem )
178                 aFont = vcl::Font( pFItem->GetFamilyName(), pFItem->GetStyleName(), Size( 1, 1 ) );
179         }
180     }
181 
182     if (aChars.isEmpty())
183     {
184         SfxAllItemSet aSet( mpDoc->GetPool() );
185         aSet.Put( SfxBoolItem( FN_PARAM_1, false ) );
186 
187         SfxItemSet aFontAttr( mpDoc->GetPool() );
188         mpView->GetAttributes( aFontAttr );
189         const SvxFontItem* pFontItem = static_cast<const SvxFontItem*>(aFontAttr.GetItem( SID_ATTR_CHAR_FONT ));
190         if( pFontItem )
191             aSet.Put( *pFontItem );
192 
193         SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
194         auto xFrame = mpViewShell ? mpViewShell->GetFrame()->GetFrame().GetFrameInterface() : nullptr;
195         ScopedVclPtr<SfxAbstractDialog> pDlg( pFact->CreateCharMapDialog(mpView->GetViewShell()->GetFrameWeld(), aSet,
196             xFrame) );
197 
198         // If a character is selected, it can be shown
199         // pDLg->SetFont( );
200         // pDlg->SetChar( );
201         pDlg->Execute();
202         return;
203     }
204 
205     if (aChars.isEmpty())
206         return;
207 
208     OutlinerView* pOV = nullptr;
209     ::Outliner*   pOL = nullptr;
210 
211     // determine depending on ViewShell Outliner and OutlinerView
212     if(dynamic_cast< const DrawViewShell *>( mpViewShell ))
213     {
214         pOV = mpView->GetTextEditOutlinerView();
215         if (pOV)
216         {
217             pOL = mpView->GetTextEditOutliner();
218         }
219     }
220     else if(dynamic_cast< const OutlineViewShell *>( mpViewShell ))
221     {
222         pOL = &static_cast<OutlineView*>(mpView)->GetOutliner();
223         pOV = static_cast<OutlineView*>(mpView)->GetViewByWindow(
224             mpViewShell->GetActiveWindow());
225     }
226 
227     // insert special character
228     if (!pOV)
229         return;
230 
231     // prevent flicker
232     pOV->HideCursor();
233     pOL->SetUpdateMode(false);
234 
235     /* remember old attributes:
236        To do that, remove selected area before (it has to go anyway).
237        With that, we get unique attributes (and since there is no
238        DeleteSelected() in OutlinerView, it is deleted by inserting an
239        empty string). */
240     pOV->InsertText( "" );
241 
242     SfxItemSet aOldSet( mpDoc->GetPool(), svl::Items<EE_CHAR_FONTINFO, EE_CHAR_FONTINFO>{} );
243     aOldSet.Put( pOV->GetAttribs() );
244 
245     SfxUndoManager& rUndoMgr =  pOL->GetUndoManager();
246     ViewShellId nViewShellId = mpViewShell ? mpViewShell->GetViewShellBase().GetViewShellId() : ViewShellId(-1);
247     rUndoMgr.EnterListAction(SdResId(STR_UNDO_INSERT_SPECCHAR),
248                              "", 0, nViewShellId );
249     pOV->InsertText(aChars, true);
250 
251     // set attributes (set font)
252     SfxItemSet aSet(pOL->GetEmptyItemSet());
253     SvxFontItem aFontItem (aFont.GetFamilyType(), aFont.GetFamilyName(),
254                            aFont.GetStyleName(), aFont.GetPitch(),
255                            aFont.GetCharSet(),
256                            EE_CHAR_FONTINFO);
257     aSet.Put(aFontItem);
258     aFontItem.SetWhich(EE_CHAR_FONTINFO_CJK);
259     aSet.Put(aFontItem);
260     aFontItem.SetWhich(EE_CHAR_FONTINFO_CTL);
261     aSet.Put(aFontItem);
262     pOV->SetAttribs(aSet);
263 
264     ESelection aSel = pOV->GetSelection();
265     aSel.nStartPara = aSel.nEndPara;
266     aSel.nStartPos = aSel.nEndPos;
267     pOV->SetSelection(aSel);
268 
269     // do not go ahead with setting attributes of special characters
270     pOV->GetOutliner()->QuickSetAttribs(aOldSet, aSel);
271 
272     rUndoMgr.LeaveListAction();
273 
274     // show it again
275     pOL->SetUpdateMode(true);
276     pOV->ShowCursor();
277 }
278 
279 void FuBullet::GetSlotState( SfxItemSet& rSet, ViewShell const * pViewShell, SfxViewFrame* pViewFrame )
280 {
281     if( !(SfxItemState::DEFAULT == rSet.GetItemState( SID_CHARMAP ) ||
282         SfxItemState::DEFAULT == rSet.GetItemState( SID_CHARMAP_CONTROL ) ||
283         SfxItemState::DEFAULT == rSet.GetItemState( FN_INSERT_SOFT_HYPHEN ) ||
284         SfxItemState::DEFAULT == rSet.GetItemState( FN_INSERT_HARDHYPHEN ) ||
285         SfxItemState::DEFAULT == rSet.GetItemState( FN_INSERT_HARD_SPACE ) ||
286         SfxItemState::DEFAULT == rSet.GetItemState( FN_INSERT_NNBSP ) ||
287         SfxItemState::DEFAULT == rSet.GetItemState( SID_INSERT_RLM ) ||
288         SfxItemState::DEFAULT == rSet.GetItemState( SID_INSERT_LRM ) ||
289         SfxItemState::DEFAULT == rSet.GetItemState( SID_INSERT_ZWNBSP ) ||
290         SfxItemState::DEFAULT == rSet.GetItemState( SID_INSERT_ZWSP )))
291         return;
292 
293     ::sd::View* pView = pViewShell ? pViewShell->GetView() : nullptr;
294     OutlinerView* pOLV = pView ? pView->GetTextEditOutlinerView() : nullptr;
295 
296     const bool bTextEdit = pOLV;
297 
298     SvtCTLOptions aCTLOptions;
299     const bool bCtlEnabled = aCTLOptions.IsCTLFontEnabled();
300 
301     if(!bTextEdit )
302     {
303         rSet.DisableItem(FN_INSERT_SOFT_HYPHEN);
304         rSet.DisableItem(FN_INSERT_HARDHYPHEN);
305         rSet.DisableItem(FN_INSERT_HARD_SPACE);
306         rSet.DisableItem(FN_INSERT_NNBSP);
307         rSet.DisableItem(SID_INSERT_ZWNBSP);
308         rSet.DisableItem(SID_INSERT_ZWSP);
309     }
310 
311     if( !bTextEdit && (dynamic_cast<OutlineViewShell const *>( pViewShell ) == nullptr) )
312     {
313         rSet.DisableItem(SID_CHARMAP);
314         rSet.DisableItem(SID_CHARMAP_CONTROL);
315     }
316 
317     if(!bTextEdit || !bCtlEnabled )
318     {
319         rSet.DisableItem(SID_INSERT_RLM);
320         rSet.DisableItem(SID_INSERT_LRM);
321     }
322 
323     if( pViewFrame )
324     {
325         SfxBindings& rBindings = pViewFrame->GetBindings();
326 
327         rBindings.SetVisibleState( SID_INSERT_RLM, bCtlEnabled );
328         rBindings.SetVisibleState( SID_INSERT_LRM, bCtlEnabled );
329     }
330 }
331 } // end of namespace sd
332 
333 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
334