Coverage Report

Created: 2025-12-31 10:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sd/source/ui/func/fubullet.cxx
Line
Count
Source
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 <editeng/editund2.hxx>
26
#include <svl/poolitem.hxx>
27
#include <editeng/fontitem.hxx>
28
#include <OutlineView.hxx>
29
#include <OutlineViewShell.hxx>
30
#include <DrawViewShell.hxx>
31
#include <ViewShellBase.hxx>
32
#include <Window.hxx>
33
#include <drawdoc.hxx>
34
#include <strings.hrc>
35
#include <sdresid.hxx>
36
#include <svx/svdoutl.hxx>
37
#include <sfx2/request.hxx>
38
#include <svl/ctloptions.hxx>
39
#include <svl/stritem.hxx>
40
#include <tools/debug.hxx>
41
#include <Outliner.hxx>
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_WJ           =   u'\x2060';
54
const sal_Unicode CHAR_NNBSP        =   u'\x202F'; //NARROW NO-BREAK SPACE
55
56
57
FuBullet::FuBullet (
58
    ViewShell& rViewSh,
59
    ::sd::Window* pWin,
60
    ::sd::View* _pView,
61
    SdDrawDocument& rDoc,
62
    SfxRequest& rReq)
63
0
    : FuPoor(rViewSh, pWin, _pView, rDoc, rReq)
64
0
{
65
0
}
66
67
rtl::Reference<FuPoor> FuBullet::Create( ViewShell& rViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument& rDoc, SfxRequest& rReq )
68
0
{
69
0
    rtl::Reference<FuPoor> xFunc( new FuBullet( rViewSh, pWin, pView, rDoc, rReq ) );
70
0
    xFunc->DoExecute(rReq);
71
0
    return xFunc;
72
0
}
73
74
void FuBullet::DoExecute( SfxRequest& rReq )
75
0
{
76
0
    if( rReq.GetSlot() == SID_CHARMAP )
77
0
        InsertSpecialCharacter(rReq);
78
0
    else
79
0
    {
80
0
        sal_Unicode cMark = 0;
81
0
        switch( rReq.GetSlot() )
82
0
        {
83
0
            case FN_INSERT_SOFT_HYPHEN: cMark = CHAR_SOFTHYPHEN ; break;
84
0
            case FN_INSERT_HARDHYPHEN:  cMark = CHAR_HARDHYPHEN ; break;
85
0
            case FN_INSERT_HARD_SPACE:  cMark = CHAR_HARDBLANK ; break;
86
0
            case FN_INSERT_NNBSP:  cMark = CHAR_NNBSP ; break;
87
0
            case SID_INSERT_RLM : cMark = CHAR_RLM ; break;
88
0
            case SID_INSERT_LRM : cMark = CHAR_LRM ; break;
89
0
            case SID_INSERT_ZWSP : cMark = CHAR_ZWSP ; break;
90
0
            case SID_INSERT_WJ: cMark = CHAR_WJ; break;
91
0
        }
92
93
0
        DBG_ASSERT( cMark != 0, "FuBullet::FuBullet(), illegal slot used!" );
94
95
0
        if( cMark )
96
0
            InsertFormattingMark( cMark );
97
0
    }
98
99
0
}
100
101
void FuBullet::InsertFormattingMark( sal_Unicode cMark )
102
0
{
103
0
    OutlinerView* pOV = nullptr;
104
0
    ::Outliner*   pOL = nullptr;
105
106
    // depending on ViewShell set Outliner and OutlinerView
107
0
    if( dynamic_cast< const DrawViewShell *>( &mrViewShell ) !=  nullptr)
108
0
    {
109
0
        pOV = mpView->GetTextEditOutlinerView();
110
0
        if (pOV)
111
0
            pOL = mpView->GetTextEditOutliner();
112
0
    }
113
0
    else if( dynamic_cast< const OutlineViewShell *>( &mrViewShell ) !=  nullptr)
114
0
    {
115
0
        pOL = &static_cast<OutlineView*>(mpView)->GetOutliner();
116
0
        pOV = static_cast<OutlineView*>(mpView)->GetViewByWindow(
117
0
            mrViewShell.GetActiveWindow());
118
0
    }
119
120
    // insert string
121
0
    if(!(pOV && pOL))
122
0
        return;
123
124
    // prevent flickering
125
0
    pOV->HideCursor();
126
0
    pOL->SetUpdateLayout(false);
127
128
    // remove old selected text
129
0
    pOV->InsertText( u""_ustr );
130
131
    // prepare undo
132
0
    EditUndoManager& rUndoMgr =  pOL->GetUndoManager();
133
0
    rUndoMgr.EnterListAction(SdResId(STR_UNDO_INSERT_SPECCHAR),
134
0
                                u""_ustr, 0, mrViewShell.GetViewShellBase().GetViewShellId() );
135
136
    // insert given text
137
0
    OUString aStr( cMark );
138
0
    pOV->InsertText( aStr, true);
139
140
0
    ESelection aSel = pOV->GetSelection();
141
0
    aSel.CollapseToEnd();
142
0
    pOV->SetSelection(aSel);
143
144
0
    rUndoMgr.LeaveListAction();
145
146
    // restart repainting
147
0
    pOL->SetUpdateLayout(true);
148
0
    pOV->ShowCursor();
149
0
}
150
151
void FuBullet::InsertSpecialCharacter( SfxRequest const & rReq )
152
0
{
153
0
    const SfxItemSet *pArgs = rReq.GetArgs();
154
0
    const SfxStringItem* pItem = nullptr;
155
0
    if( pArgs )
156
0
        pItem = pArgs->GetItemIfSet(SID_CHARMAP, false);
157
158
0
    OUString aChars;
159
0
    vcl::Font aFont;
160
0
    if ( pItem )
161
0
    {
162
0
        aChars = pItem->GetValue();
163
0
        const SfxStringItem* pFontItem = pArgs->GetItemIfSet( SID_ATTR_SPECIALCHAR, false );
164
0
        if ( pFontItem )
165
0
        {
166
0
            const OUString& aFontName = pFontItem->GetValue();
167
0
            aFont = vcl::Font( aFontName, Size(1,1) );
168
0
        }
169
0
        else
170
0
        {
171
0
            SfxItemSet aFontAttr( mrDoc.GetPool() );
172
0
            mpView->GetAttributes( aFontAttr );
173
0
            const SvxFontItem* pFItem = aFontAttr.GetItem( SID_ATTR_CHAR_FONT );
174
0
            if( pFItem )
175
0
                aFont = vcl::Font( pFItem->GetFamilyName(), pFItem->GetStyleName(), Size( 1, 1 ) );
176
0
        }
177
0
    }
178
179
0
    if (aChars.isEmpty())
180
0
    {
181
0
        SfxAllItemSet aSet( mrDoc.GetPool() );
182
0
        aSet.Put( SfxBoolItem( FN_PARAM_1, false ) );
183
184
0
        SfxItemSet aFontAttr( mrDoc.GetPool() );
185
0
        mpView->GetAttributes( aFontAttr );
186
0
        const SvxFontItem* pFontItem = aFontAttr.GetItem( SID_ATTR_CHAR_FONT );
187
0
        if( pFontItem )
188
0
            aSet.Put( *pFontItem );
189
190
0
        SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
191
0
        css::uno::Reference<css::frame::XFrame> xFrame;
192
0
        if (SfxViewFrame* pFrame = mrViewShell.GetFrame())
193
0
            xFrame = pFrame->GetFrame().GetFrameInterface();
194
0
        VclPtr<SfxAbstractDialog> pDlg( pFact->CreateCharMapDialog(mpView->GetViewShell()->GetFrameWeld(), aSet,
195
0
            xFrame) );
196
197
        // If a character is selected, it can be shown
198
        // pDLg->SetFont( );
199
        // pDlg->SetChar( );
200
0
        pDlg->StartExecuteAsync(
201
0
            [pDlg] (sal_Int32 /*nResult*/)->void
202
0
            {
203
0
                pDlg->disposeOnce();
204
0
            }
205
0
        );
206
0
        return;
207
0
    }
208
209
0
    if (aChars.isEmpty())
210
0
        return;
211
212
0
    OutlinerView* pOV = nullptr;
213
0
    ::Outliner*   pOL = nullptr;
214
215
    // determine depending on ViewShell Outliner and OutlinerView
216
0
    if(dynamic_cast< const DrawViewShell *>( &mrViewShell ))
217
0
    {
218
0
        pOV = mpView->GetTextEditOutlinerView();
219
0
        if (pOV)
220
0
        {
221
0
            pOL = mpView->GetTextEditOutliner();
222
0
        }
223
0
    }
224
0
    else if(dynamic_cast< const OutlineViewShell *>( &mrViewShell ))
225
0
    {
226
0
        pOL = &static_cast<OutlineView*>(mpView)->GetOutliner();
227
0
        pOV = static_cast<OutlineView*>(mpView)->GetViewByWindow(
228
0
            mrViewShell.GetActiveWindow());
229
0
    }
230
231
    // insert special character
232
0
    if (!pOV)
233
0
        return;
234
235
    // prevent flicker
236
0
    pOV->HideCursor();
237
0
    pOL->SetUpdateLayout(false);
238
239
    /* remember old attributes:
240
       To do that, remove selected area before (it has to go anyway).
241
       With that, we get unique attributes (and since there is no
242
       DeleteSelected() in OutlinerView, it is deleted by inserting an
243
       empty string). */
244
0
    pOV->InsertText( u""_ustr );
245
246
0
    SfxItemSetFixed<EE_CHAR_FONTINFO, EE_CHAR_FONTINFO> aOldSet( mrDoc.GetPool() );
247
0
    aOldSet.Put( pOV->GetAttribs() );
248
249
0
    EditUndoManager& rUndoMgr = pOL->GetUndoManager();
250
0
    ViewShellId nViewShellId = mrViewShell.GetViewShellBase().GetViewShellId();
251
0
    rUndoMgr.EnterListAction(SdResId(STR_UNDO_INSERT_SPECCHAR),
252
0
                             u""_ustr, 0, nViewShellId );
253
0
    pOV->InsertText(aChars, true);
254
255
    // set attributes (set font)
256
0
    SfxItemSet aSet(pOL->GetEmptyItemSet());
257
0
    SvxFontItem aFontItem (aFont.GetFamilyTypeMaybeAskConfig(), aFont.GetFamilyName(),
258
0
                           aFont.GetStyleName(), aFont.GetPitchMaybeAskConfig(),
259
0
                           aFont.GetCharSet(),
260
0
                           EE_CHAR_FONTINFO);
261
0
    aSet.Put(aFontItem);
262
0
    aFontItem.SetWhich(EE_CHAR_FONTINFO_CJK);
263
0
    aSet.Put(aFontItem);
264
0
    aFontItem.SetWhich(EE_CHAR_FONTINFO_CTL);
265
0
    aSet.Put(aFontItem);
266
0
    pOV->SetAttribs(aSet);
267
268
0
    ESelection aSel = pOV->GetSelection();
269
0
    aSel.CollapseToEnd();
270
0
    pOV->SetSelection(aSel);
271
272
    // do not go ahead with setting attributes of special characters
273
0
    pOV->GetOutliner().QuickSetAttribs(aOldSet, aSel);
274
275
0
    rUndoMgr.LeaveListAction();
276
277
    // show it again
278
0
    pOL->SetUpdateLayout(true);
279
0
    pOV->ShowCursor();
280
0
}
281
282
void FuBullet::GetSlotState( SfxItemSet& rSet, ViewShell const * pViewShell, SfxViewFrame* pViewFrame )
283
0
{
284
0
    if( !(SfxItemState::DEFAULT == rSet.GetItemState( SID_CHARMAP ) ||
285
0
        SfxItemState::DEFAULT == rSet.GetItemState( SID_CHARMAP_CONTROL ) ||
286
0
        SfxItemState::DEFAULT == rSet.GetItemState( FN_INSERT_SOFT_HYPHEN ) ||
287
0
        SfxItemState::DEFAULT == rSet.GetItemState( FN_INSERT_HARDHYPHEN ) ||
288
0
        SfxItemState::DEFAULT == rSet.GetItemState( FN_INSERT_HARD_SPACE ) ||
289
0
        SfxItemState::DEFAULT == rSet.GetItemState( FN_INSERT_NNBSP ) ||
290
0
        SfxItemState::DEFAULT == rSet.GetItemState( SID_INSERT_RLM ) ||
291
0
        SfxItemState::DEFAULT == rSet.GetItemState( SID_INSERT_LRM ) ||
292
0
        SfxItemState::DEFAULT == rSet.GetItemState( SID_INSERT_WJ ) ||
293
0
        SfxItemState::DEFAULT == rSet.GetItemState( SID_INSERT_ZWSP )))
294
0
        return;
295
296
0
    ::sd::View* pView = pViewShell ? pViewShell->GetView() : nullptr;
297
0
    OutlinerView* pOLV = pView ? pView->GetTextEditOutlinerView() : nullptr;
298
299
0
    const bool bTextEdit = pOLV;
300
301
0
    const bool bCtlEnabled = SvtCTLOptions::IsCTLFontEnabled();
302
303
0
    if(!bTextEdit )
304
0
    {
305
0
        rSet.DisableItem(FN_INSERT_SOFT_HYPHEN);
306
0
        rSet.DisableItem(FN_INSERT_HARDHYPHEN);
307
0
        rSet.DisableItem(FN_INSERT_HARD_SPACE);
308
0
        rSet.DisableItem(FN_INSERT_NNBSP);
309
0
        rSet.DisableItem(SID_INSERT_WJ);
310
0
        rSet.DisableItem(SID_INSERT_ZWSP);
311
0
    }
312
313
0
    if( !bTextEdit && (dynamic_cast<OutlineViewShell const *>( pViewShell ) == nullptr) )
314
0
    {
315
0
        rSet.DisableItem(SID_CHARMAP);
316
0
        rSet.DisableItem(SID_CHARMAP_CONTROL);
317
0
    }
318
319
0
    if(!bTextEdit || !bCtlEnabled )
320
0
    {
321
0
        rSet.DisableItem(SID_INSERT_RLM);
322
0
        rSet.DisableItem(SID_INSERT_LRM);
323
0
    }
324
325
0
    if( pViewFrame )
326
0
    {
327
0
        SfxBindings& rBindings = pViewFrame->GetBindings();
328
329
0
        rBindings.SetVisibleState( SID_INSERT_RLM, bCtlEnabled );
330
0
        rBindings.SetVisibleState( SID_INSERT_LRM, bCtlEnabled );
331
0
    }
332
0
}
333
} // end of namespace sd
334
335
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */