Bug Summary

File:home/maarten/src/libreoffice/core/include/rtl/ref.hxx
Warning:line 192, column 9
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name editsh.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /usr/include/libxml2 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D SC_DLLIMPLEMENTATION -D SC_INFO_OSVERSION="LINUX" -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/liborcus/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/mdds/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/external/clew/source/include -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/sc/source/core/inc -I /home/maarten/src/libreoffice/core/sc/source/filter/inc -I /home/maarten/src/libreoffice/core/sc/source/ui/inc -I /home/maarten/src/libreoffice/core/sc/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sc/sdi -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/oovbaapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/sc/source/ui/view/editsh.cxx

/home/maarten/src/libreoffice/core/sc/source/ui/view/editsh.cxx

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 <comphelper/string.hxx>
21#include <scitems.hxx>
22#include <editeng/eeitem.hxx>
23#include <i18nutil/unicode.hxx>
24
25#include <svx/clipfmtitem.hxx>
26#include <svx/svxdlg.hxx>
27#include <editeng/contouritem.hxx>
28#include <editeng/outliner.hxx>
29#include <editeng/crossedoutitem.hxx>
30#include <editeng/editeng.hxx>
31#include <editeng/editview.hxx>
32#include <editeng/escapementitem.hxx>
33#include <editeng/flditem.hxx>
34#include <editeng/flstitem.hxx>
35#include <editeng/fontitem.hxx>
36#include <editeng/urlfieldhelper.hxx>
37#include <svx/hlnkitem.hxx>
38#include <vcl/EnumContext.hxx>
39#include <editeng/postitem.hxx>
40#include <editeng/scripttypeitem.hxx>
41#include <editeng/shdditem.hxx>
42#include <editeng/udlnitem.hxx>
43#include <editeng/wghtitem.hxx>
44#include <sfx2/bindings.hxx>
45#include <sfx2/dispatch.hxx>
46#include <sfx2/msg.hxx>
47#include <sfx2/objface.hxx>
48#include <sfx2/objsh.hxx>
49#include <sfx2/request.hxx>
50#include <sfx2/viewfrm.hxx>
51#include <svtools/cliplistener.hxx>
52#include <svl/whiter.hxx>
53#include <sot/formats.hxx>
54#include <vcl/transfer.hxx>
55#include <vcl/unohelp2.hxx>
56#include <svl/stritem.hxx>
57#include <editeng/colritem.hxx>
58
59#include <editsh.hxx>
60#include <global.hxx>
61#include <sc.hrc>
62#include <scmod.hxx>
63#include <inputhdl.hxx>
64#include <viewutil.hxx>
65#include <viewdata.hxx>
66#include <document.hxx>
67#include <reffind.hxx>
68#include <tabvwsh.hxx>
69#include <editutil.hxx>
70#include <globstr.hrc>
71#include <scresid.hxx>
72#include <gridwin.hxx>
73
74#define ShellClass_ScEditShell
75#include <scslots.hxx>
76
77#include <scui_def.hxx>
78#include <scabstdlg.hxx>
79#include <memory>
80
81using namespace ::com::sun::star;
82
83
84SFX_IMPL_INTERFACE(ScEditShell, SfxShell)SfxInterface* ScEditShell::pInterface = nullptr; SfxInterface
* ScEditShell::GetStaticInterface() { if ( !pInterface ) { pInterface
= new SfxInterface( "ScEditShell", false, GetInterfaceId(), SfxShell
::GetStaticInterface(), aScEditShellSlots_Impl[0], sal_uInt16
(sizeof(aScEditShellSlots_Impl) / sizeof(SfxSlot) ) ); InitInterface_Impl
(); } return pInterface; } SfxInterface* ScEditShell::GetInterface
() const { return GetStaticInterface(); } void ScEditShell::RegisterInterface
(const SfxModule* pMod) { GetStaticInterface()->Register(pMod
); }
85
86void ScEditShell::InitInterface_Impl()
87{
88 GetStaticInterface()->RegisterPopupMenu("celledit");
89}
90
91ScEditShell::ScEditShell(EditView* pView, ScViewData& rData) :
92 pEditView (pView),
93 rViewData (rData),
94 bPastePossible (false),
95 bIsInsertMode (true)
96{
97 SetPool( pEditView->GetEditEngine()->GetEmptyItemSet().GetPool() );
98 SetUndoManager( &pEditView->GetEditEngine()->GetUndoManager() );
99 SetName("EditCell");
100 SfxShell::SetContextName(vcl::EnumContext::GetContextName(vcl::EnumContext::Context::EditCell));
101}
102
103ScEditShell::~ScEditShell()
104{
105 if ( mxClipEvtLstnr.is() )
106 {
107 mxClipEvtLstnr->RemoveListener( rViewData.GetActiveWin() );
108
109 // The listener may just now be waiting for the SolarMutex and call the link
110 // afterwards, in spite of RemoveListener. So the link has to be reset, too.
111 mxClipEvtLstnr->ClearCallbackLink();
112 }
113}
114
115ScInputHandler* ScEditShell::GetMyInputHdl()
116{
117 return SC_MOD()( static_cast<ScModule*>(SfxApplication::GetModule(SfxToolsModule
::Calc)) )
->GetInputHdl( rViewData.GetViewShell() );
118}
119
120void ScEditShell::SetEditView(EditView* pView)
121{
122 pEditView = pView;
123 pEditView->SetInsertMode( bIsInsertMode );
124 SetPool( pEditView->GetEditEngine()->GetEmptyItemSet().GetPool() );
125 SetUndoManager( &pEditView->GetEditEngine()->GetUndoManager() );
126}
127
128static void lcl_RemoveAttribs( EditView& rEditView )
129{
130 ScEditEngineDefaulter* pEngine = static_cast<ScEditEngineDefaulter*>(rEditView.GetEditEngine());
131
132 bool bOld = pEngine->GetUpdateMode();
133 pEngine->SetUpdateMode(false);
134
135 OUString aName = ScResId( STR_UNDO_DELETECONTENTSreinterpret_cast<char const *>("STR_UNDO_DELETECONTENTS"
"\004" u8"Delete")
);
136 ViewShellId nViewShellId(-1);
137 if (ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell())
138 nViewShellId = pViewSh->GetViewShellId();
139 pEngine->GetUndoManager().EnterListAction( aName, aName, 0, nViewShellId );
140
141 rEditView.RemoveAttribs(true);
142 pEngine->RepeatDefaults(); // paragraph attributes from cell formats must be preserved
143
144 pEngine->GetUndoManager().LeaveListAction();
145
146 pEngine->SetUpdateMode(bOld);
147}
148
149static void lclInsertCharacter( EditView* pTableView, EditView* pTopView, sal_Unicode cChar )
150{
151 OUString aString( cChar );
152 if( pTableView )
153 pTableView->InsertText( aString );
154 if( pTopView )
155 pTopView->InsertText( aString );
156}
157
158void ScEditShell::Execute( SfxRequest& rReq )
159{
160 const SfxItemSet* pReqArgs = rReq.GetArgs();
161 sal_uInt16 nSlot = rReq.GetSlot();
162 SfxBindings& rBindings = rViewData.GetBindings();
163
164 ScInputHandler* pHdl = GetMyInputHdl();
165 OSL_ENSURE(pHdl,"no ScInputHandler")do { if (true && (!(pHdl))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/view/editsh.cxx"
":" "165" ": "), "%s", "no ScInputHandler"); } } while (false
)
;
1
Assuming 'pHdl' is non-null
2
Taking false branch
3
Loop condition is false. Exiting loop
166
167 EditView* pTopView = pHdl->GetTopView(); // Has thee input cell the focus?
168 EditView* pTableView = pHdl->GetTableView();
169
170 OSL_ENSURE(pTableView,"no EditView :-(")do { if (true && (!(pTableView))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/view/editsh.cxx"
":" "170" ": "), "%s", "no EditView :-("); } } while (false)
;
4
Assuming 'pTableView' is non-null
5
Taking false branch
6
Loop condition is false. Exiting loop
171 /* #i91683# No EditView if spell-check dialog is active and positioned on
172 * an error and user immediately (without double click or F2) selected a
173 * text portion of that cell with the mouse and wanted to modify it. */
174 /* FIXME: Bailing out only cures the symptom and prevents a crash, no edit
175 * action is possible. A real fix somehow would need to create a valid
176 * EditView from the spell-check view. */
177 if (!pTableView
6.1
'pTableView' is non-null
6.1
'pTableView' is non-null
6.1
'pTableView' is non-null
6.1
'pTableView' is non-null
)
7
Taking false branch
178 return;
179
180 EditEngine* pEngine = pTableView->GetEditEngine();
181
182 pHdl->DataChanging();
183 bool bSetSelIsRef = false;
184 bool bSetModified = true;
185
186 switch ( nSlot )
8
Control jumps to 'case 5311:' at line 269
187 {
188 case SID_ATTR_INSERTTypedWhichId<SfxBoolItem>( 10000 + 221 ):
189 case FID_INS_CELL_CONTENTS((((((((26000 + 200) + 20)) + 20)) + 20)) + 5): // Insert taste, while defined as Acc
190 bIsInsertMode = !pTableView->IsInsertMode();
191 pTableView->SetInsertMode( bIsInsertMode );
192 if (pTopView)
193 pTopView->SetInsertMode( bIsInsertMode );
194 rBindings.Invalidate( SID_ATTR_INSERTTypedWhichId<SfxBoolItem>( 10000 + 221 ) );
195 break;
196
197 case SID_THES(5000 + 698):
198 {
199 OUString aReplaceText;
200 const SfxStringItem* pItem2 = rReq.GetArg<SfxStringItem>(SID_THES(5000 + 698));
201 if (pItem2)
202 aReplaceText = pItem2->GetValue();
203 if (!aReplaceText.isEmpty())
204 ReplaceTextWithSynonym( *pEditView, aReplaceText );
205 }
206 break;
207
208 case SID_COPY(5000 + 711):
209 pTableView->Copy();
210 bSetModified = false;
211 break;
212
213 case SID_CUT(5000 + 710):
214 pTableView->Cut();
215 if (pTopView)
216 pTopView->DeleteSelected();
217 break;
218
219 case SID_PASTE(5000 + 712):
220 {
221 EVControlBits nControl = pTableView->GetControlWord();
222 if (pTopView)
223 {
224 pTopView->Paste();
225 pTableView->SetControlWord(nControl | EVControlBits::SINGLELINEPASTE);
226 }
227
228 pTableView->PasteSpecial();
229 pTableView->SetControlWord(nControl);
230 }
231 break;
232
233 case SID_DELETE(5000 + 713):
234 pTableView->DeleteSelected();
235 if (pTopView)
236 pTopView->DeleteSelected();
237 break;
238
239 case SID_CELL_FORMAT_RESET((26000) + 67): // "Standard"
240 lcl_RemoveAttribs( *pTableView );
241 if ( pTopView )
242 lcl_RemoveAttribs( *pTopView );
243 break;
244
245 case SID_CLIPBOARD_FORMAT_ITEMS(5000 + 312):
246 {
247 SotClipboardFormatId nFormat = SotClipboardFormatId::NONE;
248 const SfxPoolItem* pItem;
249 if ( pReqArgs &&
250 pReqArgs->GetItemState(nSlot, true, &pItem) == SfxItemState::SET &&
251 dynamic_cast<const SfxUInt32Item*>( pItem) != nullptr )
252 {
253 nFormat = static_cast<SotClipboardFormatId>(static_cast<const SfxUInt32Item*>(pItem)->GetValue());
254 }
255
256 if ( nFormat != SotClipboardFormatId::NONE )
257 {
258 if (SotClipboardFormatId::STRING == nFormat)
259 pTableView->Paste();
260 else
261 pTableView->PasteSpecial();
262
263 if (pTopView)
264 pTopView->Paste();
265 }
266 }
267 break;
268
269 case SID_PASTE_SPECIAL(5000 + 311):
270 {
271 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
272 ScopedVclPtr<SfxAbstractPasteDialog> pDlg(pFact->CreatePasteDialog(rViewData.GetDialogParent()));
9
Calling constructor for 'ScopedVclPtr<SfxAbstractPasteDialog>'
16
Returning from constructor for 'ScopedVclPtr<SfxAbstractPasteDialog>'
17
Calling implicit destructor for 'VclPtr<SfxAbstractPasteDialog>'
18
Calling '~Reference'
25
Returning from '~Reference'
26
Returning from destructor for 'VclPtr<SfxAbstractPasteDialog>'
273 SotClipboardFormatId nFormat = SotClipboardFormatId::NONE;
274 pDlg->Insert( SotClipboardFormatId::STRING, EMPTY_OUSTRINGScGlobal::GetEmptyOUString() );
27
Calling 'VclPtr::operator->'
275 pDlg->Insert( SotClipboardFormatId::RTF, EMPTY_OUSTRINGScGlobal::GetEmptyOUString() );
276 pDlg->Insert( SotClipboardFormatId::RICHTEXT, EMPTY_OUSTRINGScGlobal::GetEmptyOUString() );
277 // Do not offer SotClipboardFormatId::STRING_TSVC for
278 // in-cell paste.
279
280 TransferableDataHelper aDataHelper(
281 TransferableDataHelper::CreateFromSystemClipboard( rViewData.GetActiveWin() ) );
282
283 nFormat = pDlg->GetFormat( aDataHelper.GetTransferable() );
284 pDlg.disposeAndClear();
285
286 // while the dialog was open, edit mode may have been stopped
287 if (!SC_MOD()( static_cast<ScModule*>(SfxApplication::GetModule(SfxToolsModule
::Calc)) )
->IsInputMode())
288 return;
289
290 if (nFormat != SotClipboardFormatId::NONE)
291 {
292 if (SotClipboardFormatId::STRING == nFormat)
293 pTableView->Paste();
294 else
295 pTableView->PasteSpecial();
296
297 if (pTopView)
298 pTopView->Paste();
299 }
300
301 if (pTopView)
302 pTopView->GetWindow()->GrabFocus();
303 }
304 break;
305
306 case SID_PASTE_UNFORMATTED(5000 + 314):
307 {
308 pTableView->Paste();
309
310 if (pTopView)
311 {
312 pTopView->Paste();
313 pTopView->GetWindow()->GrabFocus();
314 }
315 }
316 break;
317
318 case SID_SELECTALL(5000 + 723):
319 {
320 sal_Int32 nPar = pEngine->GetParagraphCount();
321 if (nPar)
322 {
323 sal_Int32 nLen = pEngine->GetTextLen(nPar-1);
324 pTableView->SetSelection(ESelection(0,0,nPar-1,nLen));
325 if (pTopView)
326 pTopView->SetSelection(ESelection(0,0,nPar-1,nLen));
327 rBindings.Invalidate( SID_ATTR_CHAR_FONT( 10000 + 7 ) );
328 rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT( 10000 + 15 ) );
329 rBindings.Invalidate( SID_ATTR_CHAR_WEIGHT( 10000 + 9 ) );
330 rBindings.Invalidate( SID_ATTR_CHAR_POSTURE( 10000 + 8 ) );
331 rBindings.Invalidate( SID_ATTR_CHAR_UNDERLINE( 10000 + 14 ) );
332 rBindings.Invalidate( SID_ATTR_CHAR_STRIKEOUT( 10000 + 13 ) );
333 rBindings.Invalidate( SID_ATTR_CHAR_SHADOWED( 10000 + 10 ) );
334 rBindings.Invalidate( SID_ATTR_CHAR_KERNING( 10000 + 18 ) );
335 rBindings.Invalidate( SID_ATTR_CHAR_COLOR( 10000 + 17 ) );
336 rBindings.Invalidate( SID_SET_SUPER_SCRIPT( 10000 + 294 ) );
337 rBindings.Invalidate( SID_SET_SUB_SCRIPT( 10000 + 295 ) );
338 }
339 }
340 return;
341 case SID_UNICODE_NOTATION_TOGGLE(5000 + 792):
342 {
343 EditView* pActiveView = pHdl->GetActiveView();
344 if( pActiveView )
345 {
346 OUString sInput = pEngine->GetText();
347 ESelection aSel( pActiveView->GetSelection() );
348 if( aSel.HasRange() )
349 sInput = pActiveView->GetSelected();
350
351 if( aSel.nStartPos > aSel.nEndPos )
352 aSel.nEndPos = aSel.nStartPos;
353
354 //calculate a valid end-position by reading logical characters
355 sal_Int32 nUtf16Pos=0;
356 while( (nUtf16Pos < sInput.getLength()) && (nUtf16Pos < aSel.nEndPos) )
357 {
358 sInput.iterateCodePoints(&nUtf16Pos);
359 if( nUtf16Pos > aSel.nEndPos )
360 aSel.nEndPos = nUtf16Pos;
361 }
362
363 ToggleUnicodeCodepoint aToggle;
364 while( nUtf16Pos && aToggle.AllowMoreInput( sInput[nUtf16Pos-1]) )
365 --nUtf16Pos;
366 OUString sReplacement = aToggle.ReplacementString();
367 if( !sReplacement.isEmpty() )
368 {
369 aSel.nStartPos = aSel.nEndPos - aToggle.StringToReplace().getLength();
370 pTableView->SetSelection( aSel );
371 pTableView->InsertText(sReplacement, true);
372 if( pTopView )
373 {
374 pTopView->SetSelection( aSel );
375 pTopView->InsertText(sReplacement, true);
376 }
377 }
378 }
379 }
380 break;
381
382 case SID_CHARMAP((10000 + 500) + 3):
383 {
384 SvtScriptType nScript = pTableView->GetSelectedScriptType();
385 sal_uInt16 nFontWhich = ( nScript == SvtScriptType::ASIAN ) ? EE_CHAR_FONTINFO_CJK :
386 ( ( nScript == SvtScriptType::COMPLEX ) ? EE_CHAR_FONTINFO_CTL :
387 EE_CHAR_FONTINFO );
388 const SvxFontItem& rItem = static_cast<const SvxFontItem&>(
389 pTableView->GetAttribs().Get(nFontWhich));
390
391 OUString aString;
392 std::shared_ptr<SvxFontItem> aNewItem(std::make_shared<SvxFontItem>(EE_CHAR_FONTINFO));
393
394 const SfxItemSet *pArgs = rReq.GetArgs();
395 const SfxPoolItem* pItem = nullptr;
396 if( pArgs )
397 pArgs->GetItemState(GetPool().GetWhich(SID_CHARMAP((10000 + 500) + 3)), false, &pItem);
398
399 if ( pItem )
400 {
401 aString = static_cast<const SfxStringItem*>(pItem)->GetValue();
402 const SfxPoolItem* pFtItem = nullptr;
403 pArgs->GetItemState( GetPool().GetWhich(SID_ATTR_SPECIALCHAR( 10000 + 1120 )), false, &pFtItem);
404 const SfxStringItem* pFontItem = dynamic_cast<const SfxStringItem*>( pFtItem );
405 if ( pFontItem )
406 {
407 const OUString& aFontName(pFontItem->GetValue());
408 vcl::Font aFont(aFontName, Size(1,1)); // Size just because CTOR
409 // tdf#125054 see comment in drtxob.cxx, same ID
410 aNewItem = std::make_shared<SvxFontItem>(
411 aFont.GetFamilyType(), aFont.GetFamilyName(),
412 aFont.GetStyleName(), aFont.GetPitch(),
413 aFont.GetCharSet(), ATTR_FONT);
414 }
415 else
416 {
417 aNewItem.reset(rItem.Clone());
418 }
419
420 // tdf#125054 force Item to correct intended ID
421 aNewItem->SetWhich(EE_CHAR_FONTINFO);
422 }
423 else
424 {
425 ScViewUtil::ExecuteCharMap( rItem, *rViewData.GetViewShell()->GetViewFrame() );
426
427 // while the dialog was open, edit mode may have been stopped
428 if (!SC_MOD()( static_cast<ScModule*>(SfxApplication::GetModule(SfxToolsModule
::Calc)) )
->IsInputMode())
429 return;
430 }
431
432 if ( !aString.isEmpty() )
433 {
434 // if string contains WEAK characters, set all fonts
435 SvtScriptType nSetScript;
436 ScDocument& rDoc = rViewData.GetDocument();
437 if ( rDoc.HasStringWeakCharacters( aString ) )
438 nSetScript = SvtScriptType::LATIN | SvtScriptType::ASIAN | SvtScriptType::COMPLEX;
439 else
440 nSetScript = rDoc.GetStringScriptType( aString );
441
442 SfxItemSet aSet( pTableView->GetEmptyItemSet() );
443 SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONT( 10000 + 7 ), GetPool() );
444 aSetItem.PutItemForScriptType( nSetScript, *aNewItem );
445 aSet.Put( aSetItem.GetItemSet(), false );
446
447 // SetAttribs on the View selects a word, when nothing is selected
448 pTableView->GetEditEngine()->QuickSetAttribs( aSet, pTableView->GetSelection() );
449 pTableView->InsertText(aString);
450 if (pTopView)
451 pTopView->InsertText(aString);
452
453 SfxStringItem aStringItem( SID_CHARMAP((10000 + 500) + 3), aString );
454 SfxStringItem aFontItem( SID_ATTR_SPECIALCHAR( 10000 + 1120 ), aNewItem->GetFamilyName() );
455 rReq.AppendItem( aFontItem );
456 rReq.AppendItem( aStringItem );
457 rReq.Done();
458
459 }
460
461 if (pTopView)
462 pTopView->GetWindow()->GrabFocus();
463 }
464 break;
465
466 case FID_INSERT_NAME((((((((26000 + 200) + 20)) + 20)) + 20)) + 12):
467 {
468 ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
469
470 ScopedVclPtr<AbstractScNamePasteDlg> pDlg(pFact->CreateScNamePasteDlg(rViewData.GetDialogParent(), rViewData.GetDocShell()));
471 short nRet = pDlg->Execute();
472 // pDlg is needed below
473
474 // while the dialog was open, edit mode may have been stopped
475 if (!SC_MOD()( static_cast<ScModule*>(SfxApplication::GetModule(SfxToolsModule
::Calc)) )
->IsInputMode())
476 return;
477
478 if ( nRet == BTN_PASTE_NAME100 )
479 {
480 std::vector<OUString> aNames = pDlg->GetSelectedNames();
481 if (!aNames.empty())
482 {
483 OUStringBuffer aBuffer;
484 for (const auto& rName : aNames)
485 {
486 aBuffer.append(rName).append(' ');
487 }
488 pTableView->InsertText(aBuffer.toString());
489 if (pTopView)
490 pTopView->InsertText(aBuffer.makeStringAndClear());
491 }
492 }
493 pDlg.disposeAndClear();
494
495 if (pTopView)
496 pTopView->GetWindow()->GrabFocus();
497 }
498 break;
499
500 case SID_CHAR_DLG_EFFECT( 10000 + 1133 ):
501 case SID_CHAR_DLG( 10000 + 296 ):
502 {
503 SfxItemSet aAttrs( pTableView->GetAttribs() );
504
505 SfxObjectShell* pObjSh = rViewData.GetSfxDocShell();
506
507 ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
508
509 ScopedVclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateScCharDlg(
510 rViewData.GetDialogParent(), &aAttrs, pObjSh, false));
511 if (nSlot == SID_CHAR_DLG_EFFECT( 10000 + 1133 ))
512 {
513 pDlg->SetCurPageId("fonteffects");
514 }
515 short nRet = pDlg->Execute();
516 // pDlg is needed below
517
518 // while the dialog was open, edit mode may have been stopped
519 if (!SC_MOD()( static_cast<ScModule*>(SfxApplication::GetModule(SfxToolsModule
::Calc)) )
->IsInputMode())
520 return;
521
522 if ( nRet == RET_OK )
523 {
524 const SfxItemSet* pOut = pDlg->GetOutputItemSet();
525 pTableView->SetAttribs( *pOut );
526 }
527 }
528 break;
529
530 case SID_TOGGLE_REL((((26000 + 521) + 50))+38):
531 {
532 if (pEngine->GetParagraphCount() == 1)
533 {
534 OUString aText = pEngine->GetText();
535 ESelection aSel = pEditView->GetSelection(); // current View
536
537 ScDocument& rDoc = rViewData.GetDocument();
538 ScRefFinder aFinder(aText, rViewData.GetCurPos(), rDoc, rDoc.GetAddressConvention());
539 aFinder.ToggleRel( aSel.nStartPos, aSel.nEndPos );
540 if (aFinder.GetFound())
541 {
542 const OUString& aNew = aFinder.GetText();
543 ESelection aNewSel( 0,aFinder.GetSelStart(), 0,aFinder.GetSelEnd() );
544 pEngine->SetText( aNew );
545 pTableView->SetSelection( aNewSel );
546 if ( pTopView )
547 {
548 pTopView->GetEditEngine()->SetText( aNew );
549 pTopView->SetSelection( aNewSel );
550 }
551
552 // reference is being selected -> do not overwrite when typing
553 bSetSelIsRef = true;
554 }
555 }
556 }
557 break;
558
559 case SID_HYPERLINK_SETLINKTypedWhichId<SvxHyperlinkItem>(10000 + 362):
560 if( pReqArgs )
561 {
562 const SfxPoolItem* pItem;
563 if ( pReqArgs->GetItemState( SID_HYPERLINK_SETLINKTypedWhichId<SvxHyperlinkItem>(10000 + 362), true, &pItem ) == SfxItemState::SET )
564 {
565 const SvxHyperlinkItem* pHyper = static_cast<const SvxHyperlinkItem*>(pItem);
566 const OUString& rName = pHyper->GetName();
567 const OUString& rURL = pHyper->GetURL();
568 const OUString& rTarget = pHyper->GetTargetFrame();
569 SvxLinkInsertMode eMode = pHyper->GetInsertMode();
570
571 bool bDone = false;
572 if ( eMode == HLINK_DEFAULT || eMode == HLINK_FIELD )
573 {
574 const SvxURLField* pURLField = GetURLField();
575 if ( pURLField )
576 {
577 // select old field
578
579 ESelection aSel = pTableView->GetSelection();
580 aSel.Adjust();
581 aSel.nEndPara = aSel.nStartPara;
582 aSel.nEndPos = aSel.nStartPos + 1;
583 pTableView->SetSelection( aSel );
584
585 // insert new field
586
587 SvxURLField aURLField( rURL, rName, SvxURLFormat::Repr );
588 aURLField.SetTargetFrame( rTarget );
589 SvxFieldItem aURLItem( aURLField, EE_FEATURE_FIELD );
590 pTableView->InsertField( aURLItem );
591 pTableView->SetSelection( aSel ); // select inserted field
592
593 // now also fields in the Top-View
594
595 if ( pTopView )
596 {
597 aSel = pTopView->GetSelection();
598 aSel.nEndPara = aSel.nStartPara;
599 aSel.nEndPos = aSel.nStartPos + 1;
600 pTopView->SetSelection( aSel );
601 pTopView->InsertField( aURLItem );
602 pTopView->SetSelection( aSel ); // select inserted field
603 }
604
605 bDone = true;
606 }
607 }
608
609 if (!bDone)
610 {
611 rViewData.GetViewShell()->
612 InsertURL( rName, rURL, rTarget, static_cast<sal_uInt16>(eMode) );
613
614 // when "Button", the InsertURL in ViewShell turns the EditShell off
615 // thus the immediate return statement
616 return;
617 }
618 }
619 }
620 break;
621
622 case SID_OPEN_HYPERLINK( 10000 + 955 ):
623 {
624 const SvxURLField* pURLField = GetURLField();
625 if ( pURLField )
626 ScGlobal::OpenURL( pURLField->GetURL(), pURLField->GetTargetFrame(), true );
627 return;
628 }
629 case SID_EDIT_HYPERLINK( 10000 + 978 ):
630 {
631 // Ensure the field is selected first
632 pEditView->SelectFieldAtCursor();
633 rViewData.GetViewShell()->GetViewFrame()->GetDispatcher()->Execute(
634 SID_HYPERLINK_DIALOG(5000 + 678));
635 }
636 break;
637 case SID_COPY_HYPERLINK_LOCATION( 10000 + 1193 ):
638 {
639 const SvxFieldData* pField = pEditView->GetFieldAtCursor();
640 if (const SvxURLField* pURLField = dynamic_cast<const SvxURLField*>(pField))
641 {
642 uno::Reference<datatransfer::clipboard::XClipboard> xClipboard
643 = pEditView->GetWindow()->GetClipboard();
644
645 if (comphelper::LibreOfficeKit::isActive())
646 {
647 std::function<void (int, const char*)> callback = [&] (int callbackType, const char* text) { rViewData.GetViewShell()->libreOfficeKitViewCallback(callbackType, text); } ;
648 vcl::unohelper::TextDataObject::CopyStringTo(pURLField->GetURL(), xClipboard, &callback);
649 }
650 else
651 vcl::unohelper::TextDataObject::CopyStringTo(pURLField->GetURL(), xClipboard, nullptr);
652 }
653 }
654 break;
655 case SID_REMOVE_HYPERLINK( 10000 + 459 ):
656 {
657 URLFieldHelper::RemoveURLField(*pEditView);
658 }
659 break;
660
661 case FN_INSERT_SOFT_HYPHEN((20000 + 300) + 43):
662 lclInsertCharacter( pTableView, pTopView, CHAR_SHY );
663 break;
664 case FN_INSERT_HARDHYPHEN((20000 + 300) + 85):
665 lclInsertCharacter( pTableView, pTopView, CHAR_NBHY );
666 break;
667 case FN_INSERT_HARD_SPACE((20000 + 300) + 44):
668 lclInsertCharacter( pTableView, pTopView, CHAR_NBSP );
669 break;
670 case FN_INSERT_NNBSP((20000 + 300) + 45):
671 lclInsertCharacter( pTableView, pTopView, CHAR_NNBSP );
672 break;
673 case SID_INSERT_RLM( 10000 + 1056 ):
674 lclInsertCharacter( pTableView, pTopView, CHAR_RLM );
675 break;
676 case SID_INSERT_LRM( 10000 + 1057 ):
677 lclInsertCharacter( pTableView, pTopView, CHAR_LRM );
678 break;
679 case SID_INSERT_ZWSP( 10000 + 1058 ):
680 lclInsertCharacter( pTableView, pTopView, CHAR_ZWSP );
681 break;
682 case SID_INSERT_ZWNBSP( 10000 + 1059 ):
683 lclInsertCharacter( pTableView, pTopView, CHAR_ZWNBSP );
684 break;
685 case SID_INSERT_FIELD_SHEET((((26000 + 521) + 50))+97):
686 {
687 SvxTableField aField(rViewData.GetTabNo());
688 SvxFieldItem aItem(aField, EE_FEATURE_FIELD);
689 pTableView->InsertField(aItem);
690 }
691 break;
692 case SID_INSERT_FIELD_TITLE((((26000 + 521) + 50))+98):
693 {
694 SvxFileField aField;
695 SvxFieldItem aItem(aField, EE_FEATURE_FIELD);
696 pTableView->InsertField(aItem);
697 }
698 break;
699 case SID_INSERT_FIELD_DATE_VAR((((26000 + 521) + 50))+99):
700 {
701 SvxDateField aField;
702 SvxFieldItem aItem(aField, EE_FEATURE_FIELD);
703 pTableView->InsertField(aItem);
704 }
705 break;
706 }
707
708 pHdl->DataChanged(false, bSetModified);
709 if (bSetSelIsRef)
710 pHdl->SetSelIsRef(true);
711}
712
713static void lcl_DisableAll( SfxItemSet& rSet ) // disable all slots
714{
715 SfxWhichIter aIter( rSet );
716 sal_uInt16 nWhich = aIter.FirstWhich();
717 while (nWhich)
718 {
719 rSet.DisableItem( nWhich );
720 nWhich = aIter.NextWhich();
721 }
722}
723
724void ScEditShell::GetState( SfxItemSet& rSet )
725{
726 // When deactivating the view, edit mode is stopped, but the EditShell is left active
727 // (a shell can't be removed from within Deactivate). In that state, the EditView isn't inserted
728 // into the EditEngine, so it can have an invalid selection and must not be used.
729 if ( !rViewData.HasEditView( rViewData.GetActivePart() ) )
730 {
731 lcl_DisableAll( rSet );
732 return;
733 }
734
735 ScInputHandler* pHdl = GetMyInputHdl();
736 EditView* pActiveView = pHdl ? pHdl->GetActiveView() : pEditView;
737
738 SfxWhichIter aIter( rSet );
739 sal_uInt16 nWhich = aIter.FirstWhich();
740 while (nWhich)
741 {
742 switch (nWhich)
743 {
744 case SID_ATTR_INSERTTypedWhichId<SfxBoolItem>( 10000 + 221 ): // Status row
745 {
746 if ( pActiveView )
747 rSet.Put( SfxBoolItem( nWhich, pActiveView->IsInsertMode() ) );
748 else
749 {
750 // Here the code used to pass the value 42 and it used
751 // to "work" without warnings because the SfxBoolItem
752 // was based on 'sal_Bool', which is actually 'unsigned
753 // char'. But now it uses actual 'bool', and passing 42
754 // for a 'bool' parameter causes a warning at least with
755 // MSVC. So use 'true'. I really really hope there is
756 // not code somewhere that retrieves this "boolean" item
757 // and checks it value for the magic value 42...
758 rSet.Put( SfxBoolItem( nWhich, true) );
759 }
760 }
761 break;
762
763 case SID_HYPERLINK_GETLINK(10000 + 361):
764 {
765 SvxHyperlinkItem aHLinkItem;
766 const SvxURLField* pURLField = GetURLField();
767 if ( pURLField )
768 {
769 aHLinkItem.SetName( pURLField->GetRepresentation() );
770 aHLinkItem.SetURL( pURLField->GetURL() );
771 aHLinkItem.SetTargetFrame( pURLField->GetTargetFrame() );
772 }
773 else if ( pActiveView )
774 {
775 // use selected text as name for urls
776 OUString sReturn = pActiveView->GetSelected();
777 sReturn = sReturn.copy(0, std::min(sReturn.getLength(), static_cast<sal_Int32>(255)));
778 aHLinkItem.SetName(comphelper::string::stripEnd(sReturn, ' '));
779 }
780 rSet.Put(aHLinkItem);
781 }
782 break;
783
784 case SID_OPEN_HYPERLINK( 10000 + 955 ):
785 case SID_EDIT_HYPERLINK( 10000 + 978 ):
786 case SID_COPY_HYPERLINK_LOCATION( 10000 + 1193 ):
787 case SID_REMOVE_HYPERLINK( 10000 + 459 ):
788 {
789 if (!URLFieldHelper::IsCursorAtURLField(*pEditView))
790 rSet.DisableItem (nWhich);
791 }
792 break;
793
794 case SID_TRANSLITERATE_HALFWIDTH( 10000 + 914 ):
795 case SID_TRANSLITERATE_FULLWIDTH( 10000 + 915 ):
796 case SID_TRANSLITERATE_HIRAGANA( 10000 + 916 ):
797 case SID_TRANSLITERATE_KATAKANA( 10000 + 917 ):
798 case SID_INSERT_RLM( 10000 + 1056 ):
799 case SID_INSERT_LRM( 10000 + 1057 ):
800 ScViewUtil::HideDisabledSlot( rSet, rViewData.GetBindings(), nWhich );
801 break;
802
803 case SID_THES(5000 + 698):
804 {
805 OUString aStatusVal;
806 LanguageType nLang = LANGUAGE_NONELanguageType(0x00FF);
807 bool bIsLookUpWord = pActiveView &&
808 GetStatusValueForThesaurusFromContext(aStatusVal, nLang, *pActiveView);
809 rSet.Put( SfxStringItem( SID_THES(5000 + 698), aStatusVal ) );
810
811 // disable thesaurus context menu entry if there is nothing to look up
812 bool bCanDoThesaurus = ScModule::HasThesaurusLanguage( nLang );
813 if (!bIsLookUpWord || !bCanDoThesaurus)
814 rSet.DisableItem( SID_THES(5000 + 698) );
815 }
816 break;
817 case SID_INSERT_FIELD_SHEET((((26000 + 521) + 50))+97):
818 case SID_INSERT_FIELD_TITLE((((26000 + 521) + 50))+98):
819 case SID_INSERT_FIELD_DATE_VAR((((26000 + 521) + 50))+99):
820 break;
821 case SID_COPY(5000 + 711):
822 case SID_CUT(5000 + 710):
823 if (GetObjectShell() && GetObjectShell()->isContentExtractionLocked())
824 {
825 rSet.DisableItem(SID_COPY(5000 + 711));
826 rSet.DisableItem(SID_CUT(5000 + 710));
827 }
828 break;
829
830 }
831 nWhich = aIter.NextWhich();
832 }
833}
834
835const SvxURLField* ScEditShell::GetURLField()
836{
837 ScInputHandler* pHdl = GetMyInputHdl();
838 EditView* pActiveView = pHdl ? pHdl->GetActiveView() : pEditView;
839 if (!pActiveView)
840 return nullptr;
841
842 const SvxFieldData* pField = pActiveView->GetFieldAtCursor();
843 if (auto pURLField = dynamic_cast<const SvxURLField*>(pField))
844 return pURLField;
845
846 return nullptr;
847}
848
849IMPL_LINK( ScEditShell, ClipboardChanged, TransferableDataHelper*, pDataHelper, void )void ScEditShell::LinkStubClipboardChanged(void * instance, TransferableDataHelper
* data) { return static_cast<ScEditShell *>(instance)->
ClipboardChanged(data); } void ScEditShell::ClipboardChanged(
TransferableDataHelper* pDataHelper)
850{
851 bPastePossible = ( pDataHelper->HasFormat( SotClipboardFormatId::STRING )
852 || pDataHelper->HasFormat( SotClipboardFormatId::RTF )
853 || pDataHelper->HasFormat( SotClipboardFormatId::RICHTEXT ));
854
855 SfxBindings& rBindings = rViewData.GetBindings();
856 rBindings.Invalidate( SID_PASTE(5000 + 712) );
857 rBindings.Invalidate( SID_PASTE_SPECIAL(5000 + 311) );
858 rBindings.Invalidate( SID_PASTE_UNFORMATTED(5000 + 314) );
859 rBindings.Invalidate( SID_CLIPBOARD_FORMAT_ITEMS(5000 + 312) );
860}
861
862void ScEditShell::GetClipState( SfxItemSet& rSet )
863{
864 // Do not offer SotClipboardFormatId::STRING_TSVC for in-cell paste.
865
866 if ( !mxClipEvtLstnr.is() )
867 {
868 // create listener
869 mxClipEvtLstnr = new TransferableClipboardListener( LINK( this, ScEditShell, ClipboardChanged )::tools::detail::makeLink( ::tools::detail::castTo<ScEditShell
*>(this), &ScEditShell::LinkStubClipboardChanged)
);
870 vcl::Window* pWin = rViewData.GetActiveWin();
871 mxClipEvtLstnr->AddListener( pWin );
872
873 // get initial state
874 TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( rViewData.GetActiveWin() ) );
875 bPastePossible = ( aDataHelper.HasFormat( SotClipboardFormatId::STRING )
876 || aDataHelper.HasFormat( SotClipboardFormatId::RTF )
877 || aDataHelper.HasFormat( SotClipboardFormatId::RICHTEXT ) );
878 }
879
880 SfxWhichIter aIter( rSet );
881 sal_uInt16 nWhich = aIter.FirstWhich();
882 while (nWhich)
883 {
884 switch (nWhich)
885 {
886 case SID_PASTE(5000 + 712):
887 case SID_PASTE_SPECIAL(5000 + 311):
888 case SID_PASTE_UNFORMATTED(5000 + 314):
889 if( !bPastePossible )
890 rSet.DisableItem( nWhich );
891 break;
892 case SID_CLIPBOARD_FORMAT_ITEMS(5000 + 312):
893 if( bPastePossible )
894 {
895 SvxClipboardFormatItem aFormats( SID_CLIPBOARD_FORMAT_ITEMS(5000 + 312) );
896 TransferableDataHelper aDataHelper(
897 TransferableDataHelper::CreateFromSystemClipboard( rViewData.GetActiveWin() ) );
898
899 if ( aDataHelper.HasFormat( SotClipboardFormatId::STRING ) )
900 aFormats.AddClipbrdFormat( SotClipboardFormatId::STRING );
901 if ( aDataHelper.HasFormat( SotClipboardFormatId::RTF ) )
902 aFormats.AddClipbrdFormat( SotClipboardFormatId::RTF );
903
904 rSet.Put( aFormats );
905 }
906 else
907 rSet.DisableItem( nWhich );
908 break;
909 }
910 nWhich = aIter.NextWhich();
911 }
912}
913
914static void lcl_InvalidateUnder( SfxBindings& rBindings )
915{
916 rBindings.Invalidate( SID_ATTR_CHAR_UNDERLINE( 10000 + 14 ) );
917 rBindings.Invalidate( SID_ULINE_VAL_NONE(10000 + 1195) );
918 rBindings.Invalidate( SID_ULINE_VAL_SINGLE(10000 + 1196) );
919 rBindings.Invalidate( SID_ULINE_VAL_DOUBLE(10000 + 1197) );
920 rBindings.Invalidate( SID_ULINE_VAL_DOTTED(10000 + 1198) );
921}
922
923void ScEditShell::ExecuteAttr(SfxRequest& rReq)
924{
925 SfxItemSet aSet( pEditView->GetEmptyItemSet() );
926 SfxBindings& rBindings = rViewData.GetBindings();
927 const SfxItemSet* pArgs = rReq.GetArgs();
928 sal_uInt16 nSlot = rReq.GetSlot();
929
930 switch ( nSlot )
931 {
932 case SID_ATTR_CHAR_FONTHEIGHT( 10000 + 15 ):
933 case SID_ATTR_CHAR_FONT( 10000 + 7 ):
934 {
935 if (pArgs)
936 {
937 // #i78017 establish the same behaviour as in Writer
938 SvtScriptType nScript = SvtScriptType::LATIN | SvtScriptType::ASIAN | SvtScriptType::COMPLEX;
939 if (nSlot == SID_ATTR_CHAR_FONT( 10000 + 7 ))
940 {
941 nScript = pEditView->GetSelectedScriptType();
942 if (nScript == SvtScriptType::NONE) nScript = ScGlobal::GetDefaultScriptType();
943 }
944
945 SfxItemPool& rPool = GetPool();
946 SvxScriptSetItem aSetItem( nSlot, rPool );
947 sal_uInt16 nWhich = rPool.GetWhich( nSlot );
948 aSetItem.PutItemForScriptType( nScript, pArgs->Get( nWhich ) );
949
950 aSet.Put( aSetItem.GetItemSet(), false );
951 }
952 }
953 break;
954
955 case SID_ATTR_CHAR_COLOR( 10000 + 17 ):
956 {
957 if (pArgs)
958 {
959 const SfxPoolItem* pColorStringItem = nullptr;
960
961 if ( pArgs && SfxItemState::SET == pArgs->GetItemState( SID_ATTR_COLOR_STR(10000 + 540), false, &pColorStringItem ) )
962 {
963 Color aColor;
964 OUString sColor = static_cast<const SfxStringItem*>( pColorStringItem )->GetValue();
965 if ( sColor == "transparent" )
966 aColor = COL_TRANSPARENT;
967 else
968 aColor = Color( sColor.toInt32( 16 ) );
969
970 aSet.Put( SvxColorItem( aColor, EE_CHAR_COLOR ) );
971 }
972 else
973 {
974 aSet.Put( pArgs->Get( pArgs->GetPool()->GetWhich( nSlot ) ) );
975 }
976 rBindings.Invalidate( nSlot );
977 }
978 }
979 break;
980
981 // Toggles
982
983 case SID_ATTR_CHAR_WEIGHT( 10000 + 9 ):
984 {
985 // #i78017 establish the same behaviour as in Writer
986 SvtScriptType nScript = SvtScriptType::LATIN | SvtScriptType::ASIAN | SvtScriptType::COMPLEX;
987
988 SfxItemPool& rPool = GetPool();
989
990 bool bOld = false;
991 SvxScriptSetItem aOldSetItem( nSlot, rPool );
992 aOldSetItem.GetItemSet().Put( pEditView->GetAttribs(), false );
993 const SfxPoolItem* pCore = aOldSetItem.GetItemOfScript( nScript );
994 if ( pCore && static_cast<const SvxWeightItem*>(pCore)->GetWeight() > WEIGHT_NORMAL )
995 bOld = true;
996
997 SvxScriptSetItem aSetItem( nSlot, rPool );
998 aSetItem.PutItemForScriptType( nScript,
999 SvxWeightItem( bOld ? WEIGHT_NORMAL : WEIGHT_BOLD, EE_CHAR_WEIGHT ) );
1000 aSet.Put( aSetItem.GetItemSet(), false );
1001
1002 rBindings.Invalidate( nSlot );
1003 }
1004 break;
1005
1006 case SID_ATTR_CHAR_POSTURE( 10000 + 8 ):
1007 {
1008 // #i78017 establish the same behaviour as in Writer
1009 SvtScriptType nScript = SvtScriptType::LATIN | SvtScriptType::ASIAN | SvtScriptType::COMPLEX;
1010
1011 SfxItemPool& rPool = GetPool();
1012
1013 bool bOld = false;
1014 SvxScriptSetItem aOldSetItem( nSlot, rPool );
1015 aOldSetItem.GetItemSet().Put( pEditView->GetAttribs(), false );
1016 const SfxPoolItem* pCore = aOldSetItem.GetItemOfScript( nScript );
1017 if ( pCore && static_cast<const SvxPostureItem*>(pCore)->GetValue() != ITALIC_NONE )
1018 bOld = true;
1019
1020 SvxScriptSetItem aSetItem( nSlot, rPool );
1021 aSetItem.PutItemForScriptType( nScript,
1022 SvxPostureItem( bOld ? ITALIC_NONE : ITALIC_NORMAL, EE_CHAR_ITALIC ) );
1023 aSet.Put( aSetItem.GetItemSet(), false );
1024
1025 rBindings.Invalidate( nSlot );
1026 }
1027 break;
1028
1029 case SID_ULINE_VAL_NONE(10000 + 1195):
1030 aSet.Put( SvxUnderlineItem( LINESTYLE_NONE, EE_CHAR_UNDERLINE ) );
1031 lcl_InvalidateUnder( rBindings );
1032 break;
1033
1034 case SID_ATTR_CHAR_UNDERLINE( 10000 + 14 ):
1035 case SID_ULINE_VAL_SINGLE(10000 + 1196):
1036 case SID_ULINE_VAL_DOUBLE(10000 + 1197):
1037 case SID_ULINE_VAL_DOTTED(10000 + 1198):
1038 {
1039 FontLineStyle eOld = pEditView->GetAttribs().Get(EE_CHAR_UNDERLINE).GetLineStyle();
1040 FontLineStyle eNew = eOld;
1041 switch (nSlot)
1042 {
1043 case SID_ATTR_CHAR_UNDERLINE( 10000 + 14 ):
1044 if ( pArgs )
1045 {
1046 const SvxTextLineItem& rTextLineItem = static_cast< const SvxTextLineItem& >( pArgs->Get( pArgs->GetPool()->GetWhich(nSlot) ) );
1047 eNew = rTextLineItem.GetLineStyle();
1048 }
1049 else
1050 {
1051 eNew = ( eOld != LINESTYLE_NONE ) ? LINESTYLE_NONE : LINESTYLE_SINGLE;
1052 }
1053 break;
1054 case SID_ULINE_VAL_SINGLE(10000 + 1196):
1055 eNew = ( eOld == LINESTYLE_SINGLE ) ? LINESTYLE_NONE : LINESTYLE_SINGLE;
1056 break;
1057 case SID_ULINE_VAL_DOUBLE(10000 + 1197):
1058 eNew = ( eOld == LINESTYLE_DOUBLE ) ? LINESTYLE_NONE : LINESTYLE_DOUBLE;
1059 break;
1060 case SID_ULINE_VAL_DOTTED(10000 + 1198):
1061 eNew = ( eOld == LINESTYLE_DOTTED ) ? LINESTYLE_NONE : LINESTYLE_DOTTED;
1062 break;
1063 }
1064 aSet.Put( SvxUnderlineItem( eNew, EE_CHAR_UNDERLINE ) );
1065 lcl_InvalidateUnder( rBindings );
1066 }
1067 break;
1068
1069 case SID_ATTR_CHAR_OVERLINE( ((10000 + 1499) + 1) + 68 ):
1070 {
1071 FontLineStyle eOld = pEditView->GetAttribs().Get(EE_CHAR_OVERLINE).GetLineStyle();
1072 FontLineStyle eNew = ( eOld != LINESTYLE_NONE ) ? LINESTYLE_NONE : LINESTYLE_SINGLE;
1073 aSet.Put( SvxOverlineItem( eNew, EE_CHAR_OVERLINE ) );
1074 rBindings.Invalidate( nSlot );
1075 }
1076 break;
1077
1078 case SID_ATTR_CHAR_STRIKEOUT( 10000 + 13 ):
1079 {
1080 bool bOld = pEditView->GetAttribs().Get(EE_CHAR_STRIKEOUT).GetValue() != STRIKEOUT_NONE;
1081 aSet.Put( SvxCrossedOutItem( bOld ? STRIKEOUT_NONE : STRIKEOUT_SINGLE, EE_CHAR_STRIKEOUT ) );
1082 rBindings.Invalidate( nSlot );
1083 }
1084 break;
1085
1086 case SID_ATTR_CHAR_SHADOWED( 10000 + 10 ):
1087 {
1088 bool bOld = pEditView->GetAttribs().Get(EE_CHAR_SHADOW).GetValue();
1089 aSet.Put( SvxShadowedItem( !bOld, EE_CHAR_SHADOW ) );
1090 rBindings.Invalidate( nSlot );
1091 }
1092 break;
1093
1094 case SID_ATTR_CHAR_CONTOUR( 10000 + 12 ):
1095 {
1096 bool bOld = pEditView->GetAttribs().Get(EE_CHAR_OUTLINE).GetValue();
1097 aSet.Put( SvxContourItem( !bOld, EE_CHAR_OUTLINE ) );
1098 rBindings.Invalidate( nSlot );
1099 }
1100 break;
1101
1102 case SID_SET_SUPER_SCRIPT( 10000 + 294 ):
1103 {
1104 SvxEscapement eOld = static_cast<SvxEscapement>(pEditView->GetAttribs().Get(EE_CHAR_ESCAPEMENT).GetEnumValue());
1105 SvxEscapement eNew = (eOld == SvxEscapement::Superscript) ?
1106 SvxEscapement::Off : SvxEscapement::Superscript;
1107 aSet.Put( SvxEscapementItem( eNew, EE_CHAR_ESCAPEMENT ) );
1108 rBindings.Invalidate( nSlot );
1109 }
1110 break;
1111 case SID_SET_SUB_SCRIPT( 10000 + 295 ):
1112 {
1113 SvxEscapement eOld = static_cast<SvxEscapement>(pEditView->GetAttribs().Get(EE_CHAR_ESCAPEMENT).GetEnumValue());
1114 SvxEscapement eNew = (eOld == SvxEscapement::Subscript) ?
1115 SvxEscapement::Off : SvxEscapement::Subscript;
1116 aSet.Put( SvxEscapementItem( eNew, EE_CHAR_ESCAPEMENT ) );
1117 rBindings.Invalidate( nSlot );
1118 }
1119 break;
1120 case SID_ATTR_CHAR_KERNING( 10000 + 18 ):
1121 {
1122 if(pArgs)
1123 {
1124 aSet.Put ( pArgs->Get(pArgs->GetPool()->GetWhich(nSlot)));
1125 rBindings.Invalidate( nSlot );
1126 }
1127 }
1128 break;
1129
1130 case SID_GROW_FONT_SIZE( 10000 + 1042 ):
1131 case SID_SHRINK_FONT_SIZE( 10000 + 1043 ):
1132 {
1133 const SvxFontListItem* pFontListItem = static_cast< const SvxFontListItem* >
1134 ( SfxObjectShell::Current()->GetItem( SID_ATTR_CHAR_FONTLIST( 10000 + 22 ) ) );
1135 const FontList* pFontList = pFontListItem ? pFontListItem->GetFontList() : nullptr;
1136 pEditView->ChangeFontSize( nSlot == SID_GROW_FONT_SIZE( 10000 + 1042 ), pFontList );
1137 rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT( 10000 + 15 ) );
1138 }
1139 break;
1140 }
1141
1142 // apply
1143
1144 EditEngine* pEngine = pEditView->GetEditEngine();
1145 bool bOld = pEngine->GetUpdateMode();
1146 pEngine->SetUpdateMode(false);
1147
1148 pEditView->SetAttribs( aSet );
1149
1150 pEngine->SetUpdateMode(bOld);
1151 pEditView->Invalidate();
1152
1153 ScInputHandler* pHdl = GetMyInputHdl();
1154 pHdl->SetModified();
1155
1156 rReq.Done();
1157}
1158
1159void ScEditShell::GetAttrState(SfxItemSet &rSet)
1160{
1161 if ( !rViewData.HasEditView( rViewData.GetActivePart() ) )
1162 {
1163 lcl_DisableAll( rSet );
1164 return;
1165 }
1166
1167 SfxItemSet aAttribs = pEditView->GetAttribs();
1168 rSet.Put( aAttribs );
1169
1170 // choose font info according to selection script type
1171
1172 SvtScriptType nScript = pEditView->GetSelectedScriptType();
1173 if (nScript == SvtScriptType::NONE) nScript = ScGlobal::GetDefaultScriptType();
1174
1175 // #i55929# input-language-dependent script type (depends on input language if nothing selected)
1176 SvtScriptType nInputScript = nScript;
1177 if ( !pEditView->GetSelection().HasRange() )
1178 {
1179 LanguageType nInputLang = rViewData.GetActiveWin()->GetInputLanguage();
1180 if (nInputLang != LANGUAGE_DONTKNOWLanguageType(0x03FF) && nInputLang != LANGUAGE_SYSTEMLanguageType(0x0000))
1181 nInputScript = SvtLanguageOptions::GetScriptTypeOfLanguage( nInputLang );
1182 }
1183
1184 // #i55929# according to spec, nInputScript is used for font and font height only
1185 if ( rSet.GetItemState( EE_CHAR_FONTINFO ) != SfxItemState::UNKNOWN )
1186 ScViewUtil::PutItemScript( rSet, aAttribs, EE_CHAR_FONTINFO, nInputScript );
1187 if ( rSet.GetItemState( EE_CHAR_FONTHEIGHT ) != SfxItemState::UNKNOWN )
1188 ScViewUtil::PutItemScript( rSet, aAttribs, EE_CHAR_FONTHEIGHT, nInputScript );
1189 if ( rSet.GetItemState( EE_CHAR_WEIGHT ) != SfxItemState::UNKNOWN )
1190 ScViewUtil::PutItemScript( rSet, aAttribs, EE_CHAR_WEIGHT, nScript );
1191 if ( rSet.GetItemState( EE_CHAR_ITALIC ) != SfxItemState::UNKNOWN )
1192 ScViewUtil::PutItemScript( rSet, aAttribs, EE_CHAR_ITALIC, nScript );
1193
1194 // underline
1195 SfxItemState eState = aAttribs.GetItemState( EE_CHAR_UNDERLINE );
1196 if ( eState == SfxItemState::DONTCARE )
1197 {
1198 rSet.InvalidateItem( SID_ULINE_VAL_NONE(10000 + 1195) );
1199 rSet.InvalidateItem( SID_ULINE_VAL_SINGLE(10000 + 1196) );
1200 rSet.InvalidateItem( SID_ULINE_VAL_DOUBLE(10000 + 1197) );
1201 rSet.InvalidateItem( SID_ULINE_VAL_DOTTED(10000 + 1198) );
1202 }
1203 else
1204 {
1205 FontLineStyle eUnderline = aAttribs.Get(EE_CHAR_UNDERLINE).GetLineStyle();
1206 rSet.Put(SfxBoolItem(SID_ULINE_VAL_SINGLE(10000 + 1196), eUnderline == LINESTYLE_SINGLE));
1207 rSet.Put(SfxBoolItem(SID_ULINE_VAL_DOUBLE(10000 + 1197), eUnderline == LINESTYLE_DOUBLE));
1208 rSet.Put(SfxBoolItem(SID_ULINE_VAL_DOTTED(10000 + 1198), eUnderline == LINESTYLE_DOTTED));
1209 rSet.Put(SfxBoolItem(SID_ULINE_VAL_NONE(10000 + 1195), eUnderline == LINESTYLE_NONE));
1210 }
1211
1212 //! Testing whether brace highlighting is active !!!!
1213 ScInputHandler* pHdl = GetMyInputHdl();
1214 if ( pHdl && pHdl->IsFormulaMode() )
1215 rSet.ClearItem( EE_CHAR_WEIGHT ); // Highlighted brace not here
1216
1217 SvxEscapement eEsc = static_cast<SvxEscapement>(aAttribs.Get( EE_CHAR_ESCAPEMENT ).GetEnumValue());
1218 rSet.Put(SfxBoolItem(SID_SET_SUPER_SCRIPT( 10000 + 294 ), eEsc == SvxEscapement::Superscript));
1219 rSet.Put(SfxBoolItem(SID_SET_SUB_SCRIPT( 10000 + 295 ), eEsc == SvxEscapement::Subscript));
1220 rViewData.GetBindings().Invalidate( SID_SET_SUPER_SCRIPT( 10000 + 294 ) );
1221 rViewData.GetBindings().Invalidate( SID_SET_SUB_SCRIPT( 10000 + 295 ) );
1222
1223 eState = aAttribs.GetItemState( EE_CHAR_KERNING );
1224 rViewData.GetBindings().Invalidate( SID_ATTR_CHAR_KERNING( 10000 + 18 ) );
1225 if ( eState == SfxItemState::DONTCARE )
1226 {
1227 rSet.InvalidateItem(EE_CHAR_KERNING);
1228 }
1229}
1230
1231OUString ScEditShell::GetSelectionText( bool bWholeWord )
1232{
1233 OUString aStrSelection;
1234
1235 if ( rViewData.HasEditView( rViewData.GetActivePart() ) )
1236 {
1237 if ( bWholeWord )
1238 {
1239 EditEngine* pEngine = pEditView->GetEditEngine();
1240 ESelection aSel = pEditView->GetSelection();
1241 OUString aStrCurrentDelimiters = pEngine->GetWordDelimiters();
1242
1243 pEngine->SetWordDelimiters(" .,;\"'");
1244 aStrSelection = pEngine->GetWord( aSel.nEndPara, aSel.nEndPos );
1245 pEngine->SetWordDelimiters( aStrCurrentDelimiters );
1246 }
1247 else
1248 {
1249 aStrSelection = pEditView->GetSelected();
1250 }
1251 }
1252
1253 return aStrSelection;
1254}
1255
1256void ScEditShell::ExecuteUndo(const SfxRequest& rReq)
1257{
1258 // Undo must be handled here because it's called for both EditViews
1259
1260 ScInputHandler* pHdl = GetMyInputHdl();
1261 OSL_ENSURE(pHdl,"no ScInputHandler")do { if (true && (!(pHdl))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/view/editsh.cxx"
":" "1261" ": "), "%s", "no ScInputHandler"); } } while (false
)
;
1262 EditView* pTopView = pHdl->GetTopView();
1263 EditView* pTableView = pHdl->GetTableView();
1264 OSL_ENSURE(pTableView,"no EditView")do { if (true && (!(pTableView))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/view/editsh.cxx"
":" "1264" ": "), "%s", "no EditView"); } } while (false)
;
1265
1266 pHdl->DataChanging();
1267
1268 const SfxItemSet* pReqArgs = rReq.GetArgs();
1269 sal_uInt16 nSlot = rReq.GetSlot();
1270 switch ( nSlot )
1271 {
1272 case SID_UNDO(5000 + 701):
1273 case SID_REDO(5000 + 700):
1274 {
1275 bool bIsUndo = ( nSlot == SID_UNDO(5000 + 701) );
1276
1277 sal_uInt16 nCount = 1;
1278 const SfxPoolItem* pItem;
1279 if ( pReqArgs && pReqArgs->GetItemState( nSlot, true, &pItem ) == SfxItemState::SET )
1280 nCount = static_cast<const SfxUInt16Item*>(pItem)->GetValue();
1281
1282 for (sal_uInt16 i=0; i<nCount; i++)
1283 {
1284 if ( bIsUndo )
1285 {
1286 pTableView->Undo();
1287 if (pTopView)
1288 pTopView->Undo();
1289 }
1290 else
1291 {
1292 pTableView->Redo();
1293 if (pTopView)
1294 pTopView->Redo();
1295 }
1296 }
1297 }
1298 break;
1299 }
1300 rViewData.GetBindings().InvalidateAll(false);
1301
1302 pHdl->DataChanged();
1303}
1304
1305void ScEditShell::GetUndoState(SfxItemSet &rSet)
1306{
1307 // Undo state is taken from normal ViewFrame state function
1308
1309 SfxViewFrame* pViewFrm = rViewData.GetViewShell()->GetViewFrame();
1310 if ( pViewFrm && GetUndoManager() )
1311 {
1312 SfxWhichIter aIter(rSet);
1313 sal_uInt16 nWhich = aIter.FirstWhich();
1314 while( nWhich )
1315 {
1316 pViewFrm->GetSlotState( nWhich, nullptr, &rSet );
1317 nWhich = aIter.NextWhich();
1318 }
1319 }
1320
1321 // disable if no action in input line EditView
1322
1323 ScInputHandler* pHdl = GetMyInputHdl();
1324 OSL_ENSURE(pHdl,"no ScInputHandler")do { if (true && (!(pHdl))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/view/editsh.cxx"
":" "1324" ": "), "%s", "no ScInputHandler"); } } while (false
)
;
1325 EditView* pTopView = pHdl->GetTopView();
1326 if (pTopView)
1327 {
1328 SfxUndoManager& rTopMgr = pTopView->GetEditEngine()->GetUndoManager();
1329 if ( rTopMgr.GetUndoActionCount() == 0 )
1330 rSet.DisableItem( SID_UNDO(5000 + 701) );
1331 if ( rTopMgr.GetRedoActionCount() == 0 )
1332 rSet.DisableItem( SID_REDO(5000 + 700) );
1333 }
1334}
1335
1336void ScEditShell::ExecuteTrans( const SfxRequest& rReq )
1337{
1338 TransliterationFlags nType = ScViewUtil::GetTransliterationType( rReq.GetSlot() );
1339 if ( nType == TransliterationFlags::NONE )
1340 return;
1341
1342 ScInputHandler* pHdl = GetMyInputHdl();
1343 assert(pHdl && "no ScInputHandler")(static_cast <bool> (pHdl && "no ScInputHandler"
) ? void (0) : __assert_fail ("pHdl && \"no ScInputHandler\""
, "/home/maarten/src/libreoffice/core/sc/source/ui/view/editsh.cxx"
, 1343, __extension__ __PRETTY_FUNCTION__))
;
1344
1345 EditView* pTopView = pHdl->GetTopView();
1346 EditView* pTableView = pHdl->GetTableView();
1347 assert(pTableView && "no EditView")(static_cast <bool> (pTableView && "no EditView"
) ? void (0) : __assert_fail ("pTableView && \"no EditView\""
, "/home/maarten/src/libreoffice/core/sc/source/ui/view/editsh.cxx"
, 1347, __extension__ __PRETTY_FUNCTION__))
;
1348
1349 pHdl->DataChanging();
1350
1351 pTableView->TransliterateText( nType );
1352 if (pTopView)
1353 pTopView->TransliterateText( nType );
1354
1355 pHdl->DataChanged();
1356}
1357
1358/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx

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#ifndef INCLUDED_VCL_PTR_HXX
21#define INCLUDED_VCL_PTR_HXX
22
23#include <sal/config.h>
24
25#include <rtl/ref.hxx>
26
27#include <utility>
28#include <type_traits>
29
30#ifdef DBG_UTIL
31#ifndef _WIN32
32#include <vcl/vclmain.hxx>
33#endif
34#endif
35
36class VclReferenceBase;
37
38namespace vcl::detail {
39
40template<typename>
41constexpr bool isIncompleteOrDerivedFromVclReferenceBase(...) { return true; }
42
43template<typename T> constexpr bool isIncompleteOrDerivedFromVclReferenceBase(
44 int (*)[sizeof(T)])
45{ return std::is_base_of<VclReferenceBase, T>::value; }
46
47} // namespace vcl::detail
48
49/**
50 * A thin wrapper around rtl::Reference to implement the acquire and dispose semantics we want for references to vcl::Window subclasses.
51 *
52 * For more details on the design please see vcl/README.lifecycle
53 *
54 * @param reference_type must be a subclass of vcl::Window
55 */
56template <class reference_type>
57class VclPtr
58{
59 static_assert(
60 vcl::detail::isIncompleteOrDerivedFromVclReferenceBase<reference_type>(
61 nullptr),
62 "template argument type must be derived from VclReferenceBase");
63
64 ::rtl::Reference<reference_type> m_rInnerRef;
65
66public:
67 /** Constructor...
68 */
69 VclPtr()
70 : m_rInnerRef()
71 {}
72
73 /** Constructor...
74 */
75 VclPtr (reference_type * pBody)
76 : m_rInnerRef(pBody)
77 {}
78
79 /** Constructor... that doesn't take a ref.
80 */
81 VclPtr (reference_type * pBody, __sal_NoAcquire)
82 : m_rInnerRef(pBody, SAL_NO_ACQUIRE)
83 {}
84
85 /** Up-casting conversion constructor: Copies interface reference.
86
87 Does not work for up-casts to ambiguous bases. For the special case of
88 up-casting to Reference< XInterface >, see the corresponding conversion
89 operator.
90
91 @param rRef another reference
92 */
93 template< class derived_type >
94 VclPtr(
95 const VclPtr< derived_type > & rRef,
96 typename std::enable_if<
97 std::is_base_of<reference_type, derived_type>::value, int>::type
98 = 0 )
99 : m_rInnerRef( static_cast<reference_type*>(rRef) )
100 {
101 }
102
103#if defined(DBG_UTIL) && !defined(_WIN32)
104 virtual ~VclPtr()
105 {
106 assert(m_rInnerRef.get() == nullptr || vclmain::isAlive())(static_cast <bool> (m_rInnerRef.get() == nullptr || vclmain
::isAlive()) ? void (0) : __assert_fail ("m_rInnerRef.get() == nullptr || vclmain::isAlive()"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 106, __extension__ __PRETTY_FUNCTION__))
;
107 // We can be one of the intermediate counts, but if we are the last
108 // VclPtr keeping this object alive, then something forgot to call dispose().
109 assert((!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1)(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
110 && "someone forgot to call dispose()")(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
;
111 }
112 VclPtr(VclPtr const &) = default;
113 VclPtr(VclPtr &&) = default;
114 VclPtr & operator =(VclPtr const &) = default;
115 VclPtr & operator =(VclPtr &&) = default;
116#endif
117
118 /**
119 * A construction helper for VclPtr. Since VclPtr types are created
120 * with a reference-count of one - to help fit into the existing
121 * code-flow; this helps us to construct them easily.
122 *
123 * For more details on the design please see vcl/README.lifecycle
124 *
125 * @tparam reference_type must be a subclass of vcl::Window
126 */
127 template<typename... Arg> [[nodiscard]] static VclPtr< reference_type > Create(Arg &&... arg)
128 {
129 return VclPtr< reference_type >( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE );
130 }
131
132 /** Probably most common used: handle->someBodyOp().
133 */
134 reference_type * operator->() const
135 {
136 return m_rInnerRef.get();
28
Calling 'Reference::get'
137 }
138
139 /** Get the body. Can be used instead of operator->().
140 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
141 are the same.
142 */
143 reference_type * get() const
144 {
145 return m_rInnerRef.get();
146 }
147
148 void set(reference_type *pBody)
149 {
150 m_rInnerRef.set(pBody);
151 }
152
153 void reset(reference_type *pBody)
154 {
155 m_rInnerRef.set(pBody);
156 }
157
158 /** Up-casting copy assignment operator.
159
160 Does not work for up-casts to ambiguous bases.
161
162 @param rRef another reference
163 */
164 template<typename derived_type>
165 typename std::enable_if<
166 std::is_base_of<reference_type, derived_type>::value,
167 VclPtr &>::type
168 operator =(VclPtr<derived_type> const & rRef)
169 {
170 m_rInnerRef.set(rRef.get());
171 return *this;
172 }
173
174 VclPtr & operator =(reference_type * pBody)
175 {
176 m_rInnerRef.set(pBody);
177 return *this;
178 }
179
180 operator reference_type * () const
181 {
182 return m_rInnerRef.get();
183 }
184
185 explicit operator bool () const
186 {
187 return m_rInnerRef.get() != nullptr;
188 }
189
190 void clear()
191 {
192 m_rInnerRef.clear();
193 }
194
195 void reset()
196 {
197 m_rInnerRef.clear();
198 }
199
200 void disposeAndClear()
201 {
202 // hold it alive for the lifetime of this method
203 ::rtl::Reference<reference_type> aTmp(m_rInnerRef);
204 m_rInnerRef.clear(); // we should use some 'swap' method ideally ;-)
205 if (aTmp.get()) {
206 aTmp->disposeOnce();
207 }
208 }
209
210 /** Needed to place VclPtr's into STL collection.
211 */
212 bool operator< (const VclPtr<reference_type> & handle) const
213 {
214 return (m_rInnerRef < handle.m_rInnerRef);
215 }
216}; // class VclPtr
217
218template<typename T1, typename T2>
219inline bool operator ==(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
220 return p1.get() == p2.get();
221}
222
223template<typename T> inline bool operator ==(VclPtr<T> const & p1, T const * p2)
224{
225 return p1.get() == p2;
226}
227
228template<typename T> inline bool operator ==(VclPtr<T> const & p1, T * p2) {
229 return p1.get() == p2;
230}
231
232template<typename T> inline bool operator ==(T const * p1, VclPtr<T> const & p2)
233{
234 return p1 == p2.get();
235}
236
237template<typename T> inline bool operator ==(T * p1, VclPtr<T> const & p2) {
238 return p1 == p2.get();
239}
240
241template<typename T1, typename T2>
242inline bool operator !=(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
243 return !(p1 == p2);
244}
245
246template<typename T> inline bool operator !=(VclPtr<T> const & p1, T const * p2)
247{
248 return !(p1 == p2);
249}
250
251template<typename T> inline bool operator !=(VclPtr<T> const & p1, T * p2) {
252 return !(p1 == p2);
253}
254
255template<typename T> inline bool operator !=(T const * p1, VclPtr<T> const & p2)
256{
257 return !(p1 == p2);
258}
259
260template<typename T> inline bool operator !=(T * p1, VclPtr<T> const & p2) {
261 return !(p1 == p2);
262}
263
264/**
265 * A construction helper for a temporary VclPtr. Since VclPtr types
266 * are created with a reference-count of one - to help fit into
267 * the existing code-flow; this helps us to construct them easily.
268 * see also VclPtr::Create and ScopedVclPtr
269 *
270 * For more details on the design please see vcl/README.lifecycle
271 *
272 * @param reference_type must be a subclass of vcl::Window
273 */
274template <class reference_type>
275class SAL_WARN_UNUSED__attribute__((warn_unused)) VclPtrInstance final : public VclPtr<reference_type>
276{
277public:
278 template<typename... Arg> VclPtrInstance(Arg &&... arg)
279 : VclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
280 {
281 }
282
283 /**
284 * Override and disallow this, to prevent people accidentally calling it and actually
285 * getting VclPtr::Create and getting a naked VclPtr<> instance
286 */
287 template<typename... Arg> static VclPtrInstance< reference_type > Create(Arg &&... ) = delete;
288};
289
290template <class reference_type>
291class ScopedVclPtr : public VclPtr<reference_type>
292{
293public:
294 /** Constructor...
295 */
296 ScopedVclPtr()
297 : VclPtr<reference_type>()
298 {}
299
300 /** Constructor
301 */
302 ScopedVclPtr (reference_type * pBody)
303 : VclPtr<reference_type>(pBody)
304 {}
305
306 /** Copy constructor...
307 */
308 ScopedVclPtr (const VclPtr<reference_type> & handle)
309 : VclPtr<reference_type>(handle)
10
Calling implicit copy constructor for 'VclPtr<SfxAbstractPasteDialog>'
11
Calling copy constructor for 'Reference<SfxAbstractPasteDialog>'
14
Returning from copy constructor for 'Reference<SfxAbstractPasteDialog>'
15
Returning from copy constructor for 'VclPtr<SfxAbstractPasteDialog>'
310 {}
311
312 /**
313 Assignment that releases the last reference.
314 */
315 void disposeAndReset(reference_type *pBody)
316 {
317 if (pBody != this->get()) {
318 VclPtr<reference_type>::disposeAndClear();
319 VclPtr<reference_type>::set(pBody);
320 }
321 }
322
323 /**
324 Assignment that releases the last reference.
325 */
326 ScopedVclPtr<reference_type>& operator = (reference_type * pBody)
327 {
328 disposeAndReset(pBody);
329 return *this;
330 }
331
332 /** Up-casting conversion constructor: Copies interface reference.
333
334 Does not work for up-casts to ambiguous bases. For the special case of
335 up-casting to Reference< XInterface >, see the corresponding conversion
336 operator.
337
338 @param rRef another reference
339 */
340 template< class derived_type >
341 ScopedVclPtr(
342 const VclPtr< derived_type > & rRef,
343 typename std::enable_if<
344 std::is_base_of<reference_type, derived_type>::value, int>::type
345 = 0 )
346 : VclPtr<reference_type>( rRef )
347 {
348 }
349
350 /** Up-casting assignment operator.
351
352 Does not work for up-casts to ambiguous bases.
353
354 @param rRef another VclPtr
355 */
356 template<typename derived_type>
357 typename std::enable_if<
358 std::is_base_of<reference_type, derived_type>::value,
359 ScopedVclPtr &>::type
360 operator =(VclPtr<derived_type> const & rRef)
361 {
362 disposeAndReset(rRef.get());
363 return *this;
364 }
365
366 /**
367 * Override and disallow this, to prevent people accidentally calling it and actually
368 * getting VclPtr::Create and getting a naked VclPtr<> instance
369 */
370 template<typename... Arg> static ScopedVclPtr< reference_type > Create(Arg &&... ) = delete;
371
372 ~ScopedVclPtr()
373 {
374 VclPtr<reference_type>::disposeAndClear();
375 assert(VclPtr<reference_type>::get() == nullptr)(static_cast <bool> (VclPtr<reference_type>::get(
) == nullptr) ? void (0) : __assert_fail ("VclPtr<reference_type>::get() == nullptr"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 375, __extension__ __PRETTY_FUNCTION__))
; // make sure there are no lingering references
376 }
377
378private:
379 // Most likely we don't want this default copy-constructor.
380 ScopedVclPtr (const ScopedVclPtr<reference_type> &) = delete;
381 // And certainly we don't want a default assignment operator.
382 ScopedVclPtr<reference_type>& operator = (const ScopedVclPtr<reference_type> &) = delete;
383 // And disallow reset as that doesn't call disposeAndClear on the original reference
384 void reset() = delete;
385 void reset(reference_type *pBody) = delete;
386
387protected:
388 ScopedVclPtr (reference_type * pBody, __sal_NoAcquire)
389 : VclPtr<reference_type>(pBody, SAL_NO_ACQUIRE)
390 {}
391};
392
393/**
394 * A construction helper for ScopedVclPtr. Since VclPtr types are created
395 * with a reference-count of one - to help fit into the existing
396 * code-flow; this helps us to construct them easily.
397 *
398 * For more details on the design please see vcl/README.lifecycle
399 *
400 * @param reference_type must be a subclass of vcl::Window
401 */
402#if defined _MSC_VER
403#pragma warning(push)
404#pragma warning(disable: 4521) // " multiple copy constructors specified"
405#endif
406template <class reference_type>
407class SAL_WARN_UNUSED__attribute__((warn_unused)) ScopedVclPtrInstance final : public ScopedVclPtr<reference_type>
408{
409public:
410 template<typename... Arg> ScopedVclPtrInstance(Arg &&... arg)
411 : ScopedVclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
412 {
413 }
414
415 /**
416 * Override and disallow this, to prevent people accidentally calling it and actually
417 * getting VclPtr::Create and getting a naked VclPtr<> instance
418 */
419 template<typename... Arg> static ScopedVclPtrInstance< reference_type > Create(Arg &&...) = delete;
420
421private:
422 // Prevent the above perfect forwarding ctor from hijacking (accidental)
423 // attempts at ScopedVclPtrInstance copy construction (where the hijacking
424 // would typically lead to somewhat obscure error messages); both non-const
425 // and const variants are needed here, as the ScopedVclPtr base class has a
426 // const--variant copy ctor, so the implicitly declared copy ctor for
427 // ScopedVclPtrInstance would also be the const variant, so non-const copy
428 // construction attempts would be hijacked by the perfect forwarding ctor;
429 // but if we only declared a non-const variant here, the const variant would
430 // no longer be implicitly declared (as there would already be an explicitly
431 // declared copy ctor), so const copy construction attempts would then be
432 // hijacked by the perfect forwarding ctor:
433 ScopedVclPtrInstance(ScopedVclPtrInstance &) = delete;
434 ScopedVclPtrInstance(ScopedVclPtrInstance const &) = delete;
435};
436#if defined _MSC_VER
437#pragma warning(pop)
438#endif
439
440#endif // INCLUDED_VCL_PTR_HXX
441
442/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/rtl/ref.hxx

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#ifndef INCLUDED_RTL_REF_HXX
21#define INCLUDED_RTL_REF_HXX
22
23#include "sal/config.h"
24
25#include <cassert>
26#include <cstddef>
27#include <functional>
28#ifdef LIBO_INTERNAL_ONLY1
29#include <type_traits>
30#endif
31
32#include "sal/types.h"
33
34namespace rtl
35{
36
37/** Template reference class for reference type.
38*/
39template <class reference_type>
40class Reference
41{
42 /** The <b>reference_type</b> body pointer.
43 */
44 reference_type * m_pBody;
45
46
47public:
48 /** Constructor...
49 */
50 Reference()
51 : m_pBody (NULL__null)
52 {}
53
54
55 /** Constructor...
56 */
57 Reference (reference_type * pBody, __sal_NoAcquire)
58 : m_pBody (pBody)
59 {
60 }
61
62 /** Constructor...
63 */
64 Reference (reference_type * pBody)
65 : m_pBody (pBody)
66 {
67 if (m_pBody)
68 m_pBody->acquire();
69 }
70
71 /** Copy constructor...
72 */
73 Reference (const Reference<reference_type> & handle)
74 : m_pBody (handle.m_pBody)
75 {
76 if (m_pBody)
12
Assuming field 'm_pBody' is non-null
13
Taking true branch
77 m_pBody->acquire();
78 }
79
80#ifdef LIBO_INTERNAL_ONLY1
81 /** Move constructor...
82 */
83 Reference (Reference<reference_type> && handle) noexcept
84 : m_pBody (handle.m_pBody)
85 {
86 handle.m_pBody = nullptr;
87 }
88#endif
89
90#if defined LIBO_INTERNAL_ONLY1
91 /** Up-casting conversion constructor: Copies interface reference.
92
93 Does not work for up-casts to ambiguous bases.
94
95 @param rRef another reference
96 */
97 template< class derived_type >
98 inline Reference(
99 const Reference< derived_type > & rRef,
100 std::enable_if_t<std::is_base_of_v<reference_type, derived_type>, int> = 0 )
101 : m_pBody (rRef.get())
102 {
103 if (m_pBody)
104 m_pBody->acquire();
105 }
106#endif
107
108 /** Destructor...
109 */
110 ~Reference() COVERITY_NOEXCEPT_FALSE
111 {
112 if (m_pBody
18.1
Field 'm_pBody' is non-null
18.1
Field 'm_pBody' is non-null
18.1
Field 'm_pBody' is non-null
18.1
Field 'm_pBody' is non-null
)
19
Taking true branch
113 m_pBody->release();
20
Calling 'VclReferenceBase::release'
24
Returning; memory was released
114 }
115
116 /** Set...
117 Similar to assignment.
118 */
119 Reference<reference_type> &
120 SAL_CALL set (reference_type * pBody)
121 {
122 if (pBody)
123 pBody->acquire();
124 reference_type * const pOld = m_pBody;
125 m_pBody = pBody;
126 if (pOld)
127 pOld->release();
128 return *this;
129 }
130
131 /** Assignment.
132 Unbinds this instance from its body (if bound) and
133 bind it to the body represented by the handle.
134 */
135 Reference<reference_type> &
136 SAL_CALL operator= (const Reference<reference_type> & handle)
137 {
138 return set( handle.m_pBody );
139 }
140
141#ifdef LIBO_INTERNAL_ONLY1
142 /** Assignment.
143 * Unbinds this instance from its body (if bound),
144 * bind it to the body represented by the handle, and
145 * set the body represented by the handle to nullptr.
146 */
147 Reference<reference_type> &
148 operator= (Reference<reference_type> && handle)
149 {
150 // self-movement guts ourself
151 if (m_pBody)
152 m_pBody->release();
153 m_pBody = handle.m_pBody;
154 handle.m_pBody = nullptr;
155 return *this;
156 }
157#endif
158
159 /** Assignment...
160 */
161 Reference<reference_type> &
162 SAL_CALL operator= (reference_type * pBody)
163 {
164 return set( pBody );
165 }
166
167 /** Unbind the body from this handle.
168 Note that for a handle representing a large body,
169 "handle.clear().set(new body());" _might_
170 perform a little bit better than "handle.set(new body());",
171 since in the second case two large objects exist in memory
172 (the old body and the new body).
173 */
174 Reference<reference_type> & SAL_CALL clear()
175 {
176 if (m_pBody)
177 {
178 reference_type * const pOld = m_pBody;
179 m_pBody = NULL__null;
180 pOld->release();
181 }
182 return *this;
183 }
184
185
186 /** Get the body. Can be used instead of operator->().
187 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
188 are the same.
189 */
190 reference_type * SAL_CALL get() const
191 {
192 return m_pBody;
29
Use of memory after it is freed
193 }
194
195
196 /** Probably most common used: handle->someBodyOp().
197 */
198 reference_type * SAL_CALL operator->() const
199 {
200 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 200, __extension__ __PRETTY_FUNCTION__))
;
201 return m_pBody;
202 }
203
204
205 /** Allows (*handle).someBodyOp().
206 */
207 reference_type & SAL_CALL operator*() const
208 {
209 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 209, __extension__ __PRETTY_FUNCTION__))
;
210 return *m_pBody;
211 }
212
213
214 /** Returns True if the handle does point to a valid body.
215 */
216 bool SAL_CALL is() const
217 {
218 return (m_pBody != NULL__null);
219 }
220
221#if defined LIBO_INTERNAL_ONLY1
222 /** Returns True if the handle does point to a valid body.
223 */
224 explicit operator bool() const
225 {
226 return is();
227 }
228#endif
229
230 /** Returns True if this points to pBody.
231 */
232 bool SAL_CALL operator== (const reference_type * pBody) const
233 {
234 return (m_pBody == pBody);
235 }
236
237
238 /** Returns True if handle points to the same body.
239 */
240 bool
241 SAL_CALL operator== (const Reference<reference_type> & handle) const
242 {
243 return (m_pBody == handle.m_pBody);
244 }
245
246
247 /** Needed to place References into STL collection.
248 */
249 bool
250 SAL_CALL operator!= (const Reference<reference_type> & handle) const
251 {
252 return (m_pBody != handle.m_pBody);
253 }
254
255
256 /** Needed to place References into STL collection.
257 */
258 bool
259 SAL_CALL operator< (const Reference<reference_type> & handle) const
260 {
261 return (m_pBody < handle.m_pBody);
262 }
263
264
265 /** Needed to place References into STL collection.
266 */
267 bool
268 SAL_CALL operator> (const Reference<reference_type> & handle) const
269 {
270 return (m_pBody > handle.m_pBody);
271 }
272};
273
274} // namespace rtl
275
276#if defined LIBO_INTERNAL_ONLY1
277namespace std
278{
279
280/// @cond INTERNAL
281/**
282 Make rtl::Reference hashable by default for use in STL containers.
283
284 @since LibreOffice 6.3
285*/
286template<typename T>
287struct hash<::rtl::Reference<T>>
288{
289 std::size_t operator()(::rtl::Reference<T> const & s) const
290 { return std::size_t(s.get()); }
291};
292/// @endcond
293
294}
295
296#endif
297
298#endif /* ! INCLUDED_RTL_REF_HXX */
299
300/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclreferencebase.hxx

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#ifndef INCLUDED_VCL_Reference_HXX
20#define INCLUDED_VCL_Reference_HXX
21
22#include <vcl/dllapi.h>
23#include <osl/interlck.h>
24
25class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclReferenceBase
26{
27 mutable oslInterlockedCount mnRefCnt;
28
29 template<typename T> friend class VclPtr;
30
31public:
32 void acquire() const
33 {
34 osl_atomic_increment(&mnRefCnt)__sync_add_and_fetch((&mnRefCnt), 1);
35 }
36
37 void release() const
38 {
39 if (osl_atomic_decrement(&mnRefCnt)__sync_sub_and_fetch((&mnRefCnt), 1) == 0)
21
Assuming the condition is true
22
Taking true branch
40 delete this;
23
Memory is released
41 }
42#ifdef DBG_UTIL
43#ifndef _WIN32
44 sal_Int32 getRefCount() const { return mnRefCnt; }
45#endif
46#endif
47
48
49private:
50 VclReferenceBase(const VclReferenceBase&) = delete;
51 VclReferenceBase& operator=(const VclReferenceBase&) = delete;
52
53 bool mbDisposed : 1;
54
55protected:
56 VclReferenceBase();
57protected:
58 virtual ~VclReferenceBase();
59
60protected:
61 virtual void dispose();
62
63public:
64 void disposeOnce();
65 bool isDisposed() const { return mbDisposed; }
66
67};
68#endif