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 baside3.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 -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 EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/basctl/inc -I /home/maarten/src/libreoffice/core/basctl/sdi -I /home/maarten/src/libreoffice/core/basctl/source/inc -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/SdiTarget/basctl/sdi -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 -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/basctl/source/basicide/baside3.cxx

/home/maarten/src/libreoffice/core/basctl/source/basicide/baside3.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 <strings.hrc>
21#include <helpids.h>
22#include <iderid.hxx>
23
24#include <accessibledialogwindow.hxx>
25#include <baside3.hxx>
26#include <basidesh.hxx>
27#include <bastype2.hxx>
28#include <basobj.hxx>
29#include <dlged.hxx>
30#include <dlgeddef.hxx>
31#include <dlgedmod.hxx>
32#include <dlgedview.hxx>
33#include <iderdll.hxx>
34#include <localizationmgr.hxx>
35#include <managelang.hxx>
36
37#include <com/sun/star/script/XLibraryContainer2.hpp>
38#include <com/sun/star/resource/StringResourceWithLocation.hpp>
39#include <com/sun/star/ucb/SimpleFileAccess.hpp>
40#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
41#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
42#include <com/sun/star/ui/dialogs/FilePicker.hpp>
43#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
44#include <comphelper/processfactory.hxx>
45#include <sfx2/dispatch.hxx>
46#include <sfx2/request.hxx>
47#include <sfx2/viewfrm.hxx>
48#include <svl/visitem.hxx>
49#include <svl/whiter.hxx>
50#include <svx/svdundo.hxx>
51#include <svx/svxids.hrc>
52#include <tools/diagnose_ex.h>
53#include <tools/urlobj.hxx>
54#include <vcl/commandevent.hxx>
55#include <vcl/weld.hxx>
56#include <vcl/settings.hxx>
57#include <vcl/stdtext.hxx>
58#include <vcl/svapp.hxx>
59#include <xmlscript/xmldlg_imexp.hxx>
60
61namespace basctl
62{
63
64using namespace ::com::sun::star;
65using namespace ::com::sun::star::uno;
66using namespace ::com::sun::star::ucb;
67using namespace ::com::sun::star::io;
68using namespace ::com::sun::star::resource;
69using namespace ::com::sun::star::ui::dialogs;
70
71#ifdef _WIN32
72char const FilterMask_All[] = "*.*";
73#else
74char const FilterMask_All[] = "*";
75#endif
76
77DialogWindow::DialogWindow(DialogWindowLayout* pParent, ScriptDocument const& rDocument,
78 const OUString& aLibName, const OUString& aName,
79 css::uno::Reference<css::container::XNameContainer> const& xDialogModel)
80 : BaseWindow(pParent, rDocument, aLibName, aName)
81 ,m_rLayout(*pParent)
82 ,m_pEditor(new DlgEditor(*this, m_rLayout, rDocument.isDocument()
83 ? rDocument.getDocument()
84 : Reference<frame::XModel>(), xDialogModel))
85 ,m_pUndoMgr(new SfxUndoManager)
86 ,m_nControlSlotId(SID_INSERT_SELECT( 10000 + 199 ))
87{
88 InitSettings();
89
90 m_pEditor->GetModel().SetNotifyUndoActionHdl(
91 &DialogWindow::NotifyUndoActionHdl
92 );
93
94 SetHelpId( HID_BASICIDE_DIALOGWINDOW"BASCTL_HID_BASICIDE_DIALOGWINDOW" );
95
96 // set readonly mode for readonly libraries
97 Reference< script::XLibraryContainer2 > xDlgLibContainer( GetDocument().getLibraryContainer( E_DIALOGS ), UNO_QUERY );
98 if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryReadOnly( aLibName ) )
99 SetReadOnly(true);
100
101 if ( rDocument.isDocument() && rDocument.isReadOnly() )
102 SetReadOnly(true);
103}
104
105void DialogWindow::dispose()
106{
107 m_pEditor.reset();
108 BaseWindow::dispose();
109}
110
111void DialogWindow::LoseFocus()
112{
113 if ( IsModified() )
114 StoreData();
115
116 Window::LoseFocus();
117}
118
119void DialogWindow::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
120{
121 m_pEditor->Paint(rRenderContext, rRect);
122}
123
124void DialogWindow::Resize()
125{
126 if (GetHScrollBar() && GetVScrollBar())
127 {
128 m_pEditor->SetScrollBars( GetHScrollBar(), GetVScrollBar() );
129 }
130}
131
132void DialogWindow::MouseButtonDown( const MouseEvent& rMEvt )
133{
134 m_pEditor->MouseButtonDown( rMEvt );
135
136 if (SfxBindings* pBindings = GetBindingsPtr())
137 pBindings->Invalidate( SID_SHOW_PROPERTYBROWSER( 10000 + 943 ) );
138}
139
140void DialogWindow::MouseButtonUp( const MouseEvent& rMEvt )
141{
142 m_pEditor->MouseButtonUp( rMEvt );
143 if( (m_pEditor->GetMode() == DlgEditor::INSERT) && !m_pEditor->IsCreateOK() )
144 {
145 m_nControlSlotId = SID_INSERT_SELECT( 10000 + 199 );
146 m_pEditor->SetMode( DlgEditor::SELECT );
147 Shell::InvalidateControlSlots();
148 }
149 if (SfxBindings* pBindings = GetBindingsPtr())
150 {
151 pBindings->Invalidate( SID_SHOW_PROPERTYBROWSER( 10000 + 943 ) );
152 pBindings->Invalidate( SID_DOC_MODIFIED(5000 + 584) );
153 pBindings->Invalidate( SID_SAVEDOC(5000 + 505) );
154 pBindings->Invalidate( SID_COPY(5000 + 711) );
155 pBindings->Invalidate( SID_CUT(5000 + 710) );
156 }
157}
158
159void DialogWindow::MouseMove( const MouseEvent& rMEvt )
160{
161 m_pEditor->MouseMove( rMEvt );
162}
163
164void DialogWindow::KeyInput( const KeyEvent& rKEvt )
165{
166 SfxBindings* pBindings = GetBindingsPtr();
167
168 if( rKEvt.GetKeyCode() == KEY_BACKSPACE )
169 {
170 if (SfxDispatcher* pDispatcher = GetDispatcher())
171 pDispatcher->Execute( SID_BACKSPACE(5000 + 714) );
172 }
173 else
174 {
175 if( pBindings && rKEvt.GetKeyCode() == KEY_TAB )
176 pBindings->Invalidate( SID_SHOW_PROPERTYBROWSER( 10000 + 943 ) );
177
178 if( !m_pEditor->KeyInput( rKEvt ) )
179 {
180 if( !SfxViewShell::Current()->KeyInput( rKEvt ) )
181 Window::KeyInput( rKEvt );
182 }
183 }
184
185 // may be KEY_TAB, KEY_BACKSPACE, KEY_ESCAPE
186 if( pBindings )
187 {
188 pBindings->Invalidate( SID_COPY(5000 + 711) );
189 pBindings->Invalidate( SID_CUT(5000 + 710) );
190 }
191}
192
193void DialogWindow::Command( const CommandEvent& rCEvt )
194{
195 if ( ( rCEvt.GetCommand() == CommandEventId::Wheel ) ||
196 ( rCEvt.GetCommand() == CommandEventId::StartAutoScroll ) ||
197 ( rCEvt.GetCommand() == CommandEventId::AutoScroll ) )
198 {
199 HandleScrollCommand( rCEvt, GetHScrollBar(), GetVScrollBar() );
200 }
201 else if ( rCEvt.GetCommand() == CommandEventId::ContextMenu )
202 {
203 if (GetDispatcher())
204 {
205 SdrView& rView = GetView();
206 if( !rCEvt.IsMouseEvent() && rView.AreObjectsMarked() )
207 {
208 tools::Rectangle aMarkedRect( rView.GetMarkedRect() );
209 Point MarkedCenter( aMarkedRect.Center() );
210 Point PosPixel( LogicToPixel( MarkedCenter ) );
211 SfxDispatcher::ExecutePopup( this, &PosPixel );
212 }
213 else
214 {
215 SfxDispatcher::ExecutePopup();
216 }
217
218 }
219 }
220 else
221 BaseWindow::Command( rCEvt );
222}
223
224
225void DialogWindow::NotifyUndoActionHdl( std::unique_ptr<SdrUndoAction> )
226{
227 // #i120515# pUndoAction needs to be deleted, this hand over is an ownership
228 // change. As long as it does not get added to the undo manager, it needs at
229 // least to be deleted.
230}
231
232void DialogWindow::DoInit()
233{
234 GetHScrollBar()->Show();
235 GetVScrollBar()->Show();
236 m_pEditor->SetScrollBars( GetHScrollBar(), GetVScrollBar() );
237}
238
239void DialogWindow::DoScroll( ScrollBar* )
240{
241 m_pEditor->DoScroll();
242}
243
244void DialogWindow::GetState( SfxItemSet& rSet )
245{
246 SfxWhichIter aIter(rSet);
247 bool bIsCalc = false;
248 if ( GetDocument().isDocument() )
249 {
250 Reference< frame::XModel > xModel= GetDocument().getDocument();
251 if ( xModel.is() )
252 {
253 Reference< lang::XServiceInfo > xServiceInfo ( xModel, UNO_QUERY );
254 if ( xServiceInfo.is() && xServiceInfo->supportsService( "com.sun.star.sheet.SpreadsheetDocument" ) )
255 bIsCalc = true;
256 }
257 }
258
259 for ( sal_uInt16 nWh = aIter.FirstWhich(); nWh != 0; nWh = aIter.NextWhich() )
260 {
261 switch ( nWh )
262 {
263 case SID_PASTE(5000 + 712):
264 {
265 if ( !IsPasteAllowed() )
266 rSet.DisableItem( nWh );
267
268 if ( IsReadOnly() )
269 rSet.DisableItem( nWh );
270 }
271 break;
272 case SID_COPY(5000 + 711):
273 {
274 // any object selected?
275 if ( !m_pEditor->GetView().AreObjectsMarked() )
276 rSet.DisableItem( nWh );
277 }
278 break;
279 case SID_CUT(5000 + 710):
280 case SID_DELETE(5000 + 713):
281 case SID_BACKSPACE(5000 + 714):
282 {
283 // any object selected?
284 if ( !m_pEditor->GetView().AreObjectsMarked() )
285 rSet.DisableItem( nWh );
286
287 if ( IsReadOnly() )
288 rSet.DisableItem( nWh );
289 }
290 break;
291 case SID_REDO(5000 + 700):
292 {
293 if ( !m_pUndoMgr->GetUndoActionCount() )
294 rSet.DisableItem( nWh );
295 }
296 break;
297
298 case SID_DIALOG_TESTMODE( 10000 + 200 ):
299 {
300 // is the IDE still active?
301 bool const bBool = GetShell()->GetFrame() &&
302 m_pEditor->GetMode() == DlgEditor::TEST;
303 rSet.Put(SfxBoolItem(SID_DIALOG_TESTMODE( 10000 + 200 ), bBool));
304 }
305 break;
306
307 case SID_CHOOSE_CONTROLS( 10000 + 144 ):
308 {
309 if ( IsReadOnly() )
310 rSet.DisableItem( nWh );
311 }
312 break;
313
314 case SID_SHOW_PROPERTYBROWSER( 10000 + 943 ):
315 {
316 Shell* pShell = GetShell();
317 SfxViewFrame* pViewFrame = pShell ? pShell->GetViewFrame() : nullptr;
318 if ( pViewFrame && !pViewFrame->HasChildWindow( SID_SHOW_PROPERTYBROWSER( 10000 + 943 ) ) && !m_pEditor->GetView().AreObjectsMarked() )
319 rSet.DisableItem( nWh );
320
321 if ( IsReadOnly() )
322 rSet.DisableItem( nWh );
323 }
324 break;
325 case SID_INSERT_FORM_RADIO( 10000 + 1106 ):
326 case SID_INSERT_FORM_CHECK( 10000 + 1107 ):
327 case SID_INSERT_FORM_LIST( 10000 + 1108 ):
328 case SID_INSERT_FORM_COMBO( 10000 + 1109 ):
329 case SID_INSERT_FORM_VSCROLL( 10000 + 1111 ):
330 case SID_INSERT_FORM_HSCROLL( 10000 + 1112 ):
331 case SID_INSERT_FORM_SPIN( 10000 + 1110 ):
332 {
333 if ( !bIsCalc || IsReadOnly() )
334 rSet.DisableItem( nWh );
335 else
336 rSet.Put( SfxBoolItem( nWh, m_nControlSlotId == nWh ) );
337 }
338 break;
339
340 case SID_INSERT_SELECT( 10000 + 199 ):
341 case SID_INSERT_PUSHBUTTON( 10000 + 146 ):
342 case SID_INSERT_RADIOBUTTON( 10000 + 147 ):
343 case SID_INSERT_CHECKBOX( 10000 + 148 ):
344 case SID_INSERT_LISTBOX( 10000 + 192 ):
345 case SID_INSERT_COMBOBOX( 10000 + 193 ):
346 case SID_INSERT_GROUPBOX( 10000 + 190 ):
347 case SID_INSERT_EDIT( 10000 + 191 ):
348 case SID_INSERT_FIXEDTEXT( 10000 + 189 ):
349 case SID_INSERT_IMAGECONTROL( 10000 + 926 ):
350 case SID_INSERT_PROGRESSBAR( 10000 + 927 ):
351 case SID_INSERT_HSCROLLBAR( 10000 + 195 ):
352 case SID_INSERT_VSCROLLBAR( 10000 + 196 ):
353 case SID_INSERT_HFIXEDLINE( 10000 + 928 ):
354 case SID_INSERT_VFIXEDLINE( 10000 + 929 ):
355 case SID_INSERT_DATEFIELD( 10000 + 936 ):
356 case SID_INSERT_TIMEFIELD( 10000 + 937 ):
357 case SID_INSERT_NUMERICFIELD( 10000 + 938 ):
358 case SID_INSERT_CURRENCYFIELD( 10000 + 939 ):
359 case SID_INSERT_FORMATTEDFIELD( 10000 + 940 ):
360 case SID_INSERT_PATTERNFIELD( 10000 + 941 ):
361 case SID_INSERT_FILECONTROL( 10000 + 942 ):
362 case SID_INSERT_SPINBUTTON( 10000 + 194 ):
363 case SID_INSERT_GRIDCONTROL( 10000 + 753 ):
364 case SID_INSERT_HYPERLINKCONTROL( 10000 + 1037 ):
365 case SID_INSERT_TREECONTROL( 10000 + 1063 ):
366 {
367 if ( IsReadOnly() )
368 rSet.DisableItem( nWh );
369 else
370 rSet.Put( SfxBoolItem( nWh, m_nControlSlotId == nWh ) );
371 }
372 break;
373 case SID_SHOWLINES(5000 + 1725):
374 {
375 // if this is not a module window hide the
376 // setting, doesn't make sense for example if the
377 // dialog editor is open
378 rSet.DisableItem(nWh);
379 rSet.Put(SfxVisibilityItem(nWh, false));
380 break;
381 }
382 case SID_SELECTALL(5000 + 723):
383 {
384 rSet.DisableItem( nWh );
385 }
386 break;
387 }
388 }
389}
390
391void DialogWindow::ExecuteCommand( SfxRequest& rReq )
392{
393 const sal_uInt16 nSlotId(rReq.GetSlot());
394 sal_uInt16 nInsertObj(0);
395
396 switch ( nSlotId )
397 {
398 case SID_CUT(5000 + 710):
399 if ( !IsReadOnly() )
400 {
401 GetEditor().Cut();
402 if (SfxBindings* pBindings = GetBindingsPtr())
403 pBindings->Invalidate( SID_DOC_MODIFIED(5000 + 584) );
404 }
405 break;
406 case SID_DELETE(5000 + 713):
407 if ( !IsReadOnly() )
408 {
409 GetEditor().Delete();
410 if (SfxBindings* pBindings = GetBindingsPtr())
411 pBindings->Invalidate( SID_DOC_MODIFIED(5000 + 584) );
412 }
413 break;
414 case SID_COPY(5000 + 711):
415 GetEditor().Copy();
416 break;
417 case SID_PASTE(5000 + 712):
418 if ( !IsReadOnly() )
419 {
420 GetEditor().Paste();
421 if (SfxBindings* pBindings = GetBindingsPtr())
422 pBindings->Invalidate( SID_DOC_MODIFIED(5000 + 584) );
423 }
424 break;
425
426 case SID_INSERT_FORM_RADIO( 10000 + 1106 ):
427 nInsertObj = OBJ_DLG_FORMRADIO;
428 break;
429 case SID_INSERT_FORM_CHECK( 10000 + 1107 ):
430 nInsertObj = OBJ_DLG_FORMCHECK;
431 break;
432 case SID_INSERT_FORM_LIST( 10000 + 1108 ):
433 nInsertObj = OBJ_DLG_FORMLIST;
434 break;
435 case SID_INSERT_FORM_COMBO( 10000 + 1109 ):
436 nInsertObj = OBJ_DLG_FORMCOMBO;
437 break;
438 case SID_INSERT_FORM_SPIN( 10000 + 1110 ):
439 nInsertObj = OBJ_DLG_FORMSPIN;
440 break;
441 case SID_INSERT_FORM_VSCROLL( 10000 + 1111 ):
442 nInsertObj = OBJ_DLG_FORMVSCROLL;
443 break;
444 case SID_INSERT_FORM_HSCROLL( 10000 + 1112 ):
445 nInsertObj = OBJ_DLG_FORMHSCROLL;
446 break;
447 case SID_INSERT_PUSHBUTTON( 10000 + 146 ):
448 nInsertObj = OBJ_DLG_PUSHBUTTON;
449 break;
450 case SID_INSERT_RADIOBUTTON( 10000 + 147 ):
451 nInsertObj = OBJ_DLG_RADIOBUTTON;
452 break;
453 case SID_INSERT_CHECKBOX( 10000 + 148 ):
454 nInsertObj = OBJ_DLG_CHECKBOX;
455 break;
456 case SID_INSERT_LISTBOX( 10000 + 192 ):
457 nInsertObj = OBJ_DLG_LISTBOX;
458 break;
459 case SID_INSERT_COMBOBOX( 10000 + 193 ):
460 nInsertObj = OBJ_DLG_COMBOBOX;
461 break;
462 case SID_INSERT_GROUPBOX( 10000 + 190 ):
463 nInsertObj = OBJ_DLG_GROUPBOX;
464 break;
465 case SID_INSERT_EDIT( 10000 + 191 ):
466 nInsertObj = OBJ_DLG_EDIT;
467 break;
468 case SID_INSERT_FIXEDTEXT( 10000 + 189 ):
469 nInsertObj = OBJ_DLG_FIXEDTEXT;
470 break;
471 case SID_INSERT_IMAGECONTROL( 10000 + 926 ):
472 nInsertObj = OBJ_DLG_IMAGECONTROL;
473 break;
474 case SID_INSERT_PROGRESSBAR( 10000 + 927 ):
475 nInsertObj = OBJ_DLG_PROGRESSBAR;
476 break;
477 case SID_INSERT_HSCROLLBAR( 10000 + 195 ):
478 nInsertObj = OBJ_DLG_HSCROLLBAR;
479 break;
480 case SID_INSERT_VSCROLLBAR( 10000 + 196 ):
481 nInsertObj = OBJ_DLG_VSCROLLBAR;
482 break;
483 case SID_INSERT_HFIXEDLINE( 10000 + 928 ):
484 nInsertObj = OBJ_DLG_HFIXEDLINE;
485 break;
486 case SID_INSERT_VFIXEDLINE( 10000 + 929 ):
487 nInsertObj = OBJ_DLG_VFIXEDLINE;
488 break;
489 case SID_INSERT_DATEFIELD( 10000 + 936 ):
490 nInsertObj = OBJ_DLG_DATEFIELD;
491 break;
492 case SID_INSERT_TIMEFIELD( 10000 + 937 ):
493 nInsertObj = OBJ_DLG_TIMEFIELD;
494 break;
495 case SID_INSERT_NUMERICFIELD( 10000 + 938 ):
496 nInsertObj = OBJ_DLG_NUMERICFIELD;
497 break;
498 case SID_INSERT_CURRENCYFIELD( 10000 + 939 ):
499 nInsertObj = OBJ_DLG_CURRENCYFIELD;
500 break;
501 case SID_INSERT_FORMATTEDFIELD( 10000 + 940 ):
502 nInsertObj = OBJ_DLG_FORMATTEDFIELD;
503 break;
504 case SID_INSERT_PATTERNFIELD( 10000 + 941 ):
505 nInsertObj = OBJ_DLG_PATTERNFIELD;
506 break;
507 case SID_INSERT_FILECONTROL( 10000 + 942 ):
508 nInsertObj = OBJ_DLG_FILECONTROL;
509 break;
510 case SID_INSERT_SPINBUTTON( 10000 + 194 ):
511 nInsertObj = OBJ_DLG_SPINBUTTON;
512 break;
513 case SID_INSERT_GRIDCONTROL( 10000 + 753 ):
514 nInsertObj = OBJ_DLG_GRIDCONTROL;
515 break;
516 case SID_INSERT_HYPERLINKCONTROL( 10000 + 1037 ):
517 nInsertObj = OBJ_DLG_HYPERLINKCONTROL;
518 break;
519 case SID_INSERT_TREECONTROL( 10000 + 1063 ):
520 nInsertObj = OBJ_DLG_TREECONTROL;
521 break;
522 case SID_INSERT_SELECT( 10000 + 199 ):
523 m_nControlSlotId = nSlotId;
524 GetEditor().SetMode( DlgEditor::SELECT );
525 Shell::InvalidateControlSlots();
526 break;
527
528 case SID_DIALOG_TESTMODE( 10000 + 200 ):
529 {
530 DlgEditor::Mode eOldMode = GetEditor().GetMode();
531 GetEditor().SetMode( DlgEditor::TEST );
532 GetEditor().SetMode( eOldMode );
533 rReq.Done();
534 if (SfxBindings* pBindings = GetBindingsPtr())
535 pBindings->Invalidate( SID_DIALOG_TESTMODE( 10000 + 200 ) );
536 return;
537 }
538 case SID_EXPORT_DIALOG(5000 + 965):
539 SaveDialog();
540 break;
541
542 case SID_IMPORT_DIALOG(5000 + 966):
543 ImportDialog();
544 break;
545
546 case SID_BASICIDE_DELETECURRENT( (30000 + 768) + 22 ):
547 if (QueryDelDialog(m_aName, GetFrameWeld()))
548 {
549 if (RemoveDialog(m_aDocument, m_aLibName, m_aName))
550 {
551 MarkDocumentModified(m_aDocument);
552 GetShell()->RemoveWindow(this, true);
553 }
554 }
555 break;
556 }
557
558 if ( nInsertObj )
559 {
560 m_nControlSlotId = nSlotId;
561 GetEditor().SetMode( DlgEditor::INSERT );
562 GetEditor().SetInsertObj( nInsertObj );
563
564 if ( rReq.GetModifier() & KEY_MOD1 )
565 {
566 GetEditor().CreateDefaultObject();
567 if (SfxBindings* pBindings = GetBindingsPtr())
568 pBindings->Invalidate( SID_DOC_MODIFIED(5000 + 584) );
569 }
570
571 Shell::InvalidateControlSlots();
572 }
573
574 rReq.Done();
575}
576
577Reference< container::XNameContainer > const & DialogWindow::GetDialog() const
578{
579 return m_pEditor->GetDialog();
580}
581
582bool DialogWindow::RenameDialog( const OUString& rNewName )
583{
584 if (!basctl::RenameDialog(GetFrameWeld(), GetDocument(), GetLibName(), GetName(), rNewName))
585 return false;
586
587 if (SfxBindings* pBindings = GetBindingsPtr())
588 pBindings->Invalidate( SID_DOC_MODIFIED(5000 + 584) );
589
590 return true;
591}
592
593void DialogWindow::DisableBrowser()
594{
595 m_rLayout.DisablePropertyBrowser();
596}
597
598void DialogWindow::UpdateBrowser()
599{
600 m_rLayout.UpdatePropertyBrowser();
601}
602
603void DialogWindow::SaveDialog()
604{
605 Reference< XComponentContext > xContext( comphelper::getProcessComponentContext() );
606 Reference < XFilePicker3 > xFP = FilePicker::createWithMode(xContext, TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD);
607
608 Reference< XFilePickerControlAccess > xFPControl(xFP, UNO_QUERY);
609 xFPControl->enableControl(ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, false);
610 Any aValue;
611 aValue <<= true;
612 xFPControl->setValue(ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, 0, aValue);
613
614 if ( !m_sCurPath.isEmpty() )
615 xFP->setDisplayDirectory ( m_sCurPath );
616
617 xFP->setDefaultName( GetName() );
618
619 OUString aDialogStr(IDEResId(RID_STR_STDDIALOGNAMEreinterpret_cast<char const *>("RID_STR_STDDIALOGNAME" "\004"
u8"Dialog")
));
620 xFP->appendFilter( aDialogStr, "*.xdl" );
621 xFP->appendFilter( IDEResId(RID_STR_FILTER_ALLFILESreinterpret_cast<char const *>("RID_STR_FILTER_ALLFILES"
"\004" u8"<All>")
), FilterMask_All );
622 xFP->setCurrentFilter( aDialogStr );
623
624 if( xFP->execute() != RET_OK )
625 return;
626
627 Sequence< OUString > aPaths = xFP->getSelectedFiles();
628 m_sCurPath = aPaths[0];
629
630 // export dialog model to xml
631 Reference< container::XNameContainer > xDialogModel = GetDialog();
632 Reference< XInputStreamProvider > xISP = ::xmlscript::exportDialogModel( xDialogModel, xContext, GetDocument().isDocument() ? GetDocument().getDocument() : Reference< frame::XModel >() );
633 Reference< XInputStream > xInput( xISP->createInputStream() );
634
635 Reference< XSimpleFileAccess3 > xSFI( SimpleFileAccess::create(xContext) );
636
637 Reference< XOutputStream > xOutput;
638 try
639 {
640 if( xSFI->exists( m_sCurPath ) )
641 xSFI->kill( m_sCurPath );
642 xOutput = xSFI->openFileWrite( m_sCurPath );
643 }
644 catch(const Exception& )
645 {}
646
647 if( xOutput.is() )
648 {
649 Sequence< sal_Int8 > bytes;
650 sal_Int32 nRead = xInput->readBytes( bytes, xInput->available() );
651 for (;;)
652 {
653 if( nRead )
654 xOutput->writeBytes( bytes );
655
656 nRead = xInput->readBytes( bytes, 1024 );
657 if (! nRead)
658 break;
659 }
660
661 // With resource?
662 Reference< beans::XPropertySet > xDialogModelPropSet( xDialogModel, UNO_QUERY );
663 Reference< resource::XStringResourceResolver > xStringResourceResolver;
664 if( xDialogModelPropSet.is() )
665 {
666 try
667 {
668 Any aResourceResolver = xDialogModelPropSet->getPropertyValue( "ResourceResolver" );
669 aResourceResolver >>= xStringResourceResolver;
670 }
671 catch(const beans::UnknownPropertyException& )
672 {}
673 }
674
675 bool bResource = false;
676 if( xStringResourceResolver.is() )
677 {
678 Sequence< lang::Locale > aLocaleSeq = xStringResourceResolver->getLocales();
679 if( aLocaleSeq.hasElements() )
680 bResource = true;
681 }
682
683 if( bResource )
684 {
685 INetURLObject aURLObj( m_sCurPath );
686 aURLObj.removeExtension();
687 OUString aDialogName( aURLObj.getName() );
688 aURLObj.removeSegment();
689 OUString aURL( aURLObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
690 OUString aComment = "# " + aDialogName + " strings" ;
691 Reference< task::XInteractionHandler > xDummyHandler;
692
693 // Remove old properties files in case of overwriting Dialog files
694 if( xSFI->isFolder( aURL ) )
695 {
696 Sequence< OUString > aContentSeq = xSFI->getFolderContents( aURL, false );
697
698 OUString aDialogName_ = aDialogName + "_" ;
699 sal_Int32 nCount = aContentSeq.getLength();
700 const OUString* pFiles = aContentSeq.getConstArray();
701 for( int i = 0 ; i < nCount ; i++ )
702 {
703 OUString aCompleteName = pFiles[i];
704 OUString aPureName;
705 OUString aExtension;
706 sal_Int32 iDot = aCompleteName.lastIndexOf( '.' );
707 sal_Int32 iSlash = aCompleteName.lastIndexOf( '/' );
708 if( iDot != -1 )
709 {
710 sal_Int32 iCopyFrom = (iSlash != -1) ? iSlash + 1 : 0;
711 aPureName = aCompleteName.copy( iCopyFrom, iDot-iCopyFrom );
712 aExtension = aCompleteName.copy( iDot + 1 );
713 }
714
715 if( aExtension == "properties" || aExtension == "default" )
716 {
717 if( aPureName.startsWith( aDialogName_ ) )
718 {
719 try
720 {
721 xSFI->kill( aCompleteName );
722 }
723 catch(const uno::Exception& )
724 {}
725 }
726 }
727 }
728 }
729
730 Reference< XStringResourceWithLocation > xStringResourceWithLocation =
731 StringResourceWithLocation::create( xContext, aURL, false/*bReadOnly*/,
732 xStringResourceResolver->getDefaultLocale(), aDialogName, aComment, xDummyHandler );
733
734 // Add locales
735 Sequence< lang::Locale > aLocaleSeq = xStringResourceResolver->getLocales();
736 const lang::Locale* pLocales = aLocaleSeq.getConstArray();
737 sal_Int32 nLocaleCount = aLocaleSeq.getLength();
738 for( sal_Int32 iLocale = 0 ; iLocale < nLocaleCount ; iLocale++ )
739 {
740 const lang::Locale& rLocale = pLocales[ iLocale ];
741 xStringResourceWithLocation->newLocale( rLocale );
742 }
743
744 LocalizationMgr::copyResourceForDialog( xDialogModel,
745 xStringResourceResolver, xStringResourceWithLocation );
746
747 xStringResourceWithLocation->store();
748 }
749 }
750 else
751 {
752 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(),
753 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_COULDNTWRITEreinterpret_cast<char const *>("RID_STR_COULDNTWRITE" "\004"
u8"The file could not be saved")
)));
754 xBox->run();
755 }
756}
757
758static std::vector< lang::Locale > implGetLanguagesOnlyContainedInFirstSeq
759 ( const Sequence< lang::Locale >& aFirstSeq, const Sequence< lang::Locale >& aSecondSeq )
760{
761 std::vector< lang::Locale > avRet;
762
763 const lang::Locale* pFirst = aFirstSeq.getConstArray();
764 const lang::Locale* pSecond = aSecondSeq.getConstArray();
765 sal_Int32 nFirstCount = aFirstSeq.getLength();
766 sal_Int32 nSecondCount = aSecondSeq.getLength();
767
768 for( sal_Int32 iFirst = 0 ; iFirst < nFirstCount ; iFirst++ )
769 {
770 const lang::Locale& rFirstLocale = pFirst[ iFirst ];
771
772 bool bAlsoContainedInSecondSeq = false;
773 for( sal_Int32 iSecond = 0 ; iSecond < nSecondCount ; iSecond++ )
774 {
775 const lang::Locale& rSecondLocale = pSecond[ iSecond ];
776
777 bool bMatch = localesAreEqual( rFirstLocale, rSecondLocale );
778 if( bMatch )
779 {
780 bAlsoContainedInSecondSeq = true;
781 break;
782 }
783 }
784
785 if( !bAlsoContainedInSecondSeq )
786 avRet.push_back( rFirstLocale );
787 }
788
789 return avRet;
790}
791
792namespace {
793
794class NameClashQueryBox
795{
796private:
797 std::unique_ptr<weld::MessageDialog> m_xQueryBox;
798public:
799 NameClashQueryBox(weld::Window* pParent, const OUString& rTitle, const OUString& rMessage)
800 : m_xQueryBox(Application::CreateMessageDialog(pParent, VclMessageType::Question, VclButtonsType::NONE, rMessage))
801 {
802 if (!rTitle.isEmpty())
803 m_xQueryBox->set_title(rTitle);
804 m_xQueryBox->add_button(IDEResId(RID_STR_DLGIMP_CLASH_RENAMEreinterpret_cast<char const *>("RID_STR_DLGIMP_CLASH_RENAME"
"\004" u8"Rename")
), RET_YES);
805 m_xQueryBox->add_button(IDEResId(RID_STR_DLGIMP_CLASH_REPLACEreinterpret_cast<char const *>("RID_STR_DLGIMP_CLASH_REPLACE"
"\004" u8"Replace")
), RET_NO);
806 m_xQueryBox->add_button(GetStandardText(StandardButtonType::Cancel), RET_CANCEL);
807 m_xQueryBox->set_default_response(RET_YES);
808 }
809 short run() { return m_xQueryBox->run(); }
810};
811
812class LanguageMismatchQueryBox
813{
814private:
815 std::unique_ptr<weld::MessageDialog> m_xQueryBox;
816public:
817 LanguageMismatchQueryBox(weld::Window* pParent, const OUString& rTitle, const OUString& rMessage)
818 : m_xQueryBox(Application::CreateMessageDialog(pParent, VclMessageType::Question, VclButtonsType::NONE, rMessage))
819 {
820 if (!rTitle.isEmpty())
821 m_xQueryBox->set_title(rTitle);
822 m_xQueryBox->add_button(IDEResId(RID_STR_DLGIMP_MISMATCH_ADDreinterpret_cast<char const *>("RID_STR_DLGIMP_MISMATCH_ADD"
"\004" u8"Add")
), RET_YES);
823 m_xQueryBox->add_button(IDEResId(RID_STR_DLGIMP_MISMATCH_OMITreinterpret_cast<char const *>("RID_STR_DLGIMP_MISMATCH_OMIT"
"\004" u8"Omit")
), RET_NO);
824 m_xQueryBox->add_button(GetStandardText(StandardButtonType::Cancel), RET_CANCEL);
825 m_xQueryBox->add_button(GetStandardText(StandardButtonType::Help), RET_HELP);
826 m_xQueryBox->set_default_response(RET_YES);
827 }
828 short run() { return m_xQueryBox->run(); }
829};
830
831}
832
833bool implImportDialog(weld::Window* pWin, const OUString& rCurPath, const ScriptDocument& rDocument, const OUString& aLibName)
834{
835 bool bDone = false;
836
837 Reference< XComponentContext > xContext( comphelper::getProcessComponentContext() );
838 Reference < XFilePicker3 > xFP = FilePicker::createWithMode(xContext, TemplateDescription::FILEOPEN_SIMPLE);
839
840 Reference< XFilePickerControlAccess > xFPControl(xFP, UNO_QUERY);
841 xFPControl->enableControl(ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, false);
842 Any aValue;
843 aValue <<= true;
844 xFPControl->setValue(ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, 0, aValue);
845
846 OUString aCurPath( rCurPath );
847 if ( !aCurPath.isEmpty() )
848 xFP->setDisplayDirectory ( aCurPath );
849
850 OUString aDialogStr(IDEResId(RID_STR_STDDIALOGNAMEreinterpret_cast<char const *>("RID_STR_STDDIALOGNAME" "\004"
u8"Dialog")
));
851 xFP->appendFilter( aDialogStr, "*.xdl" );
852 xFP->appendFilter( IDEResId(RID_STR_FILTER_ALLFILESreinterpret_cast<char const *>("RID_STR_FILTER_ALLFILES"
"\004" u8"<All>")
), FilterMask_All );
853 xFP->setCurrentFilter( aDialogStr );
854
855 if( xFP->execute() == RET_OK )
856 {
857 Sequence< OUString > aPaths = xFP->getSelectedFiles();
858 aCurPath = aPaths[0];
859
860 OUString aBasePath;
861 OUString aOUCurPath( aCurPath );
862 sal_Int32 iSlash = aOUCurPath.lastIndexOf( '/' );
863 if( iSlash != -1 )
864 aBasePath = aOUCurPath.copy( 0, iSlash + 1 );
865
866 try
867 {
868 // create dialog model
869 Reference< container::XNameContainer > xDialogModel(
870 xContext->getServiceManager()->createInstanceWithContext("com.sun.star.awt.UnoControlDialogModel", xContext),
871 UNO_QUERY_THROW );
872
873 Reference< XSimpleFileAccess3 > xSFI( SimpleFileAccess::create(xContext) );
874
875 Reference< XInputStream > xInput;
876 if( xSFI->exists( aCurPath ) )
877 xInput = xSFI->openFileRead( aCurPath );
878
879 ::xmlscript::importDialogModel( xInput, xDialogModel, xContext, rDocument.isDocument() ? rDocument.getDocument() : Reference< frame::XModel >() );
880
881 OUString aXmlDlgName;
882 Reference< beans::XPropertySet > xDialogModelPropSet( xDialogModel, UNO_QUERY );
883 assert(xDialogModelPropSet.is())(static_cast <bool> (xDialogModelPropSet.is()) ? void (
0) : __assert_fail ("xDialogModelPropSet.is()", "/home/maarten/src/libreoffice/core/basctl/source/basicide/baside3.cxx"
, 883, __extension__ __PRETTY_FUNCTION__))
;
884 try
885 {
886 Any aXmlDialogNameAny = xDialogModelPropSet->getPropertyValue( DLGED_PROP_NAME"Name" );
887 aXmlDialogNameAny >>= aXmlDlgName;
888 }
889 catch(const beans::UnknownPropertyException& )
890 {
891 TOOLS_WARN_EXCEPTION("basctl", "")do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "basctl")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "" << " " <<
exceptionToString(tools_warn_exception)) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("basctl"), ("/home/maarten/src/libreoffice/core/basctl/source/basicide/baside3.cxx"
":" "891" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "" << " " << exceptionToString
(tools_warn_exception)), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("basctl"), ("/home/maarten/src/libreoffice/core/basctl/source/basicide/baside3.cxx"
":" "891" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "" << " " << exceptionToString(tools_warn_exception
)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), (
"basctl"), ("/home/maarten/src/libreoffice/core/basctl/source/basicide/baside3.cxx"
":" "891" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "" << " " << exceptionToString
(tools_warn_exception)), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("basctl"), ("/home/maarten/src/libreoffice/core/basctl/source/basicide/baside3.cxx"
":" "891" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
892 }
893 assert( !aXmlDlgName.isEmpty() )(static_cast <bool> (!aXmlDlgName.isEmpty()) ? void (0)
: __assert_fail ("!aXmlDlgName.isEmpty()", "/home/maarten/src/libreoffice/core/basctl/source/basicide/baside3.cxx"
, 893, __extension__ __PRETTY_FUNCTION__))
;
894
895 bool bDialogAlreadyExists = rDocument.hasDialog( aLibName, aXmlDlgName );
896
897 OUString aNewDlgName = aXmlDlgName;
898 enum NameClashMode
899 {
900 NO_CLASH,
901 CLASH_OVERWRITE_DIALOG,
902 CLASH_RENAME_DIALOG,
903 };
904 NameClashMode eNameClashMode = NO_CLASH;
905 if( bDialogAlreadyExists )
906 {
907 OUString aQueryBoxTitle(IDEResId(RID_STR_DLGIMP_CLASH_TITLEreinterpret_cast<char const *>("RID_STR_DLGIMP_CLASH_TITLE"
"\004" u8"Dialog Import - Name already used")
));
908 OUString aQueryBoxText(IDEResId(RID_STR_DLGIMP_CLASH_TEXTreinterpret_cast<char const *>("RID_STR_DLGIMP_CLASH_TEXT"
"\004" u8"The library already contains a dialog with the name:\n\n$(ARG1)\n\nRename dialog to keep current dialog or replace existing dialog.\n "
)
));
909 aQueryBoxText = aQueryBoxText.replaceAll("$(ARG1)", aXmlDlgName);
910
911 NameClashQueryBox aQueryBox(pWin, aQueryBoxTitle, aQueryBoxText);
912 sal_uInt16 nRet = aQueryBox.run();
913 if( nRet == RET_YES )
914 {
915 // RET_YES == Rename, see NameClashQueryBox::NameClashQueryBox
916 eNameClashMode = CLASH_RENAME_DIALOG;
917
918 aNewDlgName = rDocument.createObjectName( E_DIALOGS, aLibName );
919 }
920 else if( nRet == RET_NO )
921 {
922 // RET_NO == Replace, see NameClashQueryBox::NameClashQueryBox
923 eNameClashMode = CLASH_OVERWRITE_DIALOG;
924 }
925 else if( nRet == RET_CANCEL )
926 {
927 return bDone;
928 }
929 }
930
931 Shell* pShell = GetShell();
932 assert(pShell)(static_cast <bool> (pShell) ? void (0) : __assert_fail
("pShell", "/home/maarten/src/libreoffice/core/basctl/source/basicide/baside3.cxx"
, 932, __extension__ __PRETTY_FUNCTION__))
;
933
934 // Resource?
935 css::lang::Locale aLocale = Application::GetSettings().GetUILanguageTag().getLocale();
936 Reference< task::XInteractionHandler > xDummyHandler;
937 Reference< XStringResourceWithLocation > xImportStringResource =
938 StringResourceWithLocation::create( xContext, aBasePath, true/*bReadOnly*/,
939 aLocale, aXmlDlgName, OUString(), xDummyHandler );
940
941 Sequence< lang::Locale > aImportLocaleSeq = xImportStringResource->getLocales();
942 sal_Int32 nImportLocaleCount = aImportLocaleSeq.getLength();
943
944 Reference< container::XNameContainer > xDialogLib( rDocument.getLibrary( E_DIALOGS, aLibName, true ) );
945 Reference< resource::XStringResourceManager > xLibStringResourceManager = LocalizationMgr::getStringResourceFromDialogLibrary( xDialogLib );
946 sal_Int32 nLibLocaleCount = 0;
947 Sequence< lang::Locale > aLibLocaleSeq;
948 if( xLibStringResourceManager.is() )
949 {
950 aLibLocaleSeq = xLibStringResourceManager->getLocales();
951 nLibLocaleCount = aLibLocaleSeq.getLength();
952 }
953
954 // Check language matches
955 std::vector< lang::Locale > aOnlyInImportLanguages =
956 implGetLanguagesOnlyContainedInFirstSeq( aImportLocaleSeq, aLibLocaleSeq );
957 int nOnlyInImportLanguageCount = aOnlyInImportLanguages.size();
958
959 // For now: Keep languages from lib
960 bool bLibLocalized = (nLibLocaleCount > 0);
961 bool bImportLocalized = (nImportLocaleCount > 0);
962
963 bool bAddDialogLanguagesToLib = false;
964 if( nOnlyInImportLanguageCount > 0 )
965 {
966 OUString aQueryBoxTitle(IDEResId(RID_STR_DLGIMP_MISMATCH_TITLEreinterpret_cast<char const *>("RID_STR_DLGIMP_MISMATCH_TITLE"
"\004" u8"Dialog Import - Language Mismatch")
));
967 OUString aQueryBoxText(IDEResId(RID_STR_DLGIMP_MISMATCH_TEXTreinterpret_cast<char const *>("RID_STR_DLGIMP_MISMATCH_TEXT"
"\004" u8"The dialog to be imported supports other languages than the target library.\n\nAdd these languages to the library to keep additional language resources provided by the dialog or omit them to stay with the current library languages.\n\nNote: For languages not supported by the dialog the resources of the dialog's default language will be used.\n "
)
));
968 LanguageMismatchQueryBox aQueryBox(pWin, aQueryBoxTitle, aQueryBoxText);
969 sal_uInt16 nRet = aQueryBox.run();
970 if( nRet == RET_YES )
971 {
972 // RET_YES == Add, see LanguageMismatchQueryBox::LanguageMismatchQueryBox
973 bAddDialogLanguagesToLib = true;
974 }
975 // RET_NO == Omit, see LanguageMismatchQueryBox::LanguageMismatchQueryBox
976 // -> nothing to do here
977 //else if( RET_NO == nRet )
978 //{
979 //}
980 else if( nRet == RET_CANCEL )
981 {
982 return bDone;
983 }
984 }
985
986 if( bImportLocalized )
987 {
988 bool bCopyResourcesForDialog = true;
989 if( bAddDialogLanguagesToLib )
990 {
991 const std::shared_ptr<LocalizationMgr>& pCurMgr = pShell->GetCurLocalizationMgr();
992
993 lang::Locale aFirstLocale = aOnlyInImportLanguages[0];
994 if( nOnlyInImportLanguageCount > 1 )
995 {
996 // Check if import default belongs to only import languages and use it then
997 lang::Locale aImportDefaultLocale = xImportStringResource->getDefaultLocale();
998 lang::Locale aTmpLocale;
999 for( int i = 0 ; i < nOnlyInImportLanguageCount ; ++i )
1000 {
1001 aTmpLocale = aOnlyInImportLanguages[i];
1002 if( localesAreEqual( aImportDefaultLocale, aTmpLocale ) )
1003 {
1004 aFirstLocale = aImportDefaultLocale;
1005 break;
1006 }
1007 }
1008 }
1009
1010 pCurMgr->handleAddLocales( {aFirstLocale} );
1011
1012 if( nOnlyInImportLanguageCount > 1 )
1013 {
1014 Sequence< lang::Locale > aRemainingLocaleSeq( nOnlyInImportLanguageCount - 1 );
1015 lang::Locale aTmpLocale;
1016 int iSeq = 0;
1017 for( int i = 0 ; i < nOnlyInImportLanguageCount ; ++i )
1018 {
1019 aTmpLocale = aOnlyInImportLanguages[i];
1020 if( !localesAreEqual( aFirstLocale, aTmpLocale ) )
1021 aRemainingLocaleSeq[iSeq++] = aTmpLocale;
1022 }
1023 pCurMgr->handleAddLocales( aRemainingLocaleSeq );
1024 }
1025 }
1026 else if( !bLibLocalized )
1027 {
1028 LocalizationMgr::resetResourceForDialog( xDialogModel, xImportStringResource );
1029 bCopyResourcesForDialog = false;
1030 }
1031
1032 if( bCopyResourcesForDialog )
1033 {
1034 LocalizationMgr::copyResourceForDroppedDialog( xDialogModel, aXmlDlgName,
1035 xLibStringResourceManager, xImportStringResource );
1036 }
1037 }
1038 else if( bLibLocalized )
1039 {
1040 LocalizationMgr::setResourceIDsForDialog( xDialogModel, xLibStringResourceManager );
1041 }
1042
1043
1044 LocalizationMgr::setStringResourceAtDialog( rDocument, aLibName, aNewDlgName, xDialogModel );
1045
1046 if( eNameClashMode == CLASH_OVERWRITE_DIALOG )
1047 {
1048 if (basctl::RemoveDialog( rDocument, aLibName, aNewDlgName ) )
1049 {
1050 BaseWindow* pDlgWin = pShell->FindDlgWin( rDocument, aLibName, aNewDlgName, false, true );
1051 if( pDlgWin != nullptr )
1052 pShell->RemoveWindow( pDlgWin, false );
1053 MarkDocumentModified( rDocument );
1054 }
1055 else
1056 {
1057 // TODO: Assertion?
1058 return bDone;
1059 }
1060 }
1061
1062 if( eNameClashMode == CLASH_RENAME_DIALOG )
1063 {
1064 bool bRenamed = false;
1065 if( xDialogModelPropSet.is() )
1066 {
1067 try
1068 {
1069 xDialogModelPropSet->setPropertyValue( DLGED_PROP_NAME"Name", Any(aNewDlgName) );
1070 bRenamed = true;
1071 }
1072 catch(const beans::UnknownPropertyException& )
1073 {}
1074 }
1075
1076
1077 if( bRenamed )
1078 {
1079 LocalizationMgr::renameStringResourceIDs( rDocument, aLibName, aNewDlgName, xDialogModel );
1080 }
1081 else
1082 {
1083 // TODO: Assertion?
1084 return bDone;
1085 }
1086 }
1087
1088 Reference< XInputStreamProvider > xISP = ::xmlscript::exportDialogModel( xDialogModel, xContext, rDocument.isDocument() ? rDocument.getDocument() : Reference< frame::XModel >() );
1089 bool bSuccess = rDocument.insertDialog( aLibName, aNewDlgName, xISP );
1090 if( bSuccess )
1091 {
1092 VclPtr<DialogWindow> pNewDlgWin = pShell->CreateDlgWin( rDocument, aLibName, aNewDlgName );
1093 pShell->SetCurWindow( pNewDlgWin, true );
1094 }
1095
1096 bDone = true;
1097 }
1098 catch(const Exception& )
1099 {}
1100 }
1101
1102 return bDone;
1103}
1104
1105void DialogWindow::ImportDialog()
1106{
1107 const ScriptDocument& rDocument = GetDocument();
1108 OUString aLibName = GetLibName();
1109 implImportDialog(GetFrameWeld(), m_sCurPath, rDocument, aLibName);
1110}
1111
1112DlgEdModel& DialogWindow::GetModel() const
1113{
1114 return m_pEditor->GetModel();
1115}
1116
1117DlgEdPage& DialogWindow::GetPage() const
1118{
1119 return m_pEditor->GetPage();
1120}
1121
1122DlgEdView& DialogWindow::GetView() const
1123{
1124 return m_pEditor->GetView();
1125}
1126
1127bool DialogWindow::IsModified()
1128{
1129 return m_pEditor->IsModified();
1130}
1131
1132SfxUndoManager* DialogWindow::GetUndoManager()
1133{
1134 return m_pUndoMgr.get();
1135}
1136
1137OUString DialogWindow::GetTitle()
1138{
1139 return GetName();
1140}
1141
1142EntryDescriptor DialogWindow::CreateEntryDescriptor()
1143{
1144 ScriptDocument aDocument( GetDocument() );
1145 OUString aLibName( GetLibName() );
1146 LibraryLocation eLocation = aDocument.getLibraryLocation( aLibName );
1147 return EntryDescriptor( aDocument, eLocation, aLibName, OUString(), GetName(), OBJ_TYPE_DIALOG );
1148}
1149
1150void DialogWindow::SetReadOnly (bool bReadOnly)
1151{
1152 m_pEditor->SetMode(bReadOnly ? DlgEditor::READONLY : DlgEditor::SELECT);
1153}
1154
1155bool DialogWindow::IsReadOnly ()
1156{
1157 return m_pEditor->GetMode() == DlgEditor::READONLY;
1158}
1159
1160bool DialogWindow::IsPasteAllowed()
1161{
1162 return m_pEditor->IsPasteAllowed();
1163}
1164
1165void DialogWindow::StoreData()
1166{
1167 if ( !IsModified() )
1168 return;
1169
1170 try
1171 {
1172 Reference< container::XNameContainer > xLib = GetDocument().getLibrary( E_DIALOGS, GetLibName(), true );
1173
1174 if( xLib.is() )
1175 {
1176 Reference< container::XNameContainer > xDialogModel = m_pEditor->GetDialog();
1177
1178 if( xDialogModel.is() )
1179 {
1180 Reference< XComponentContext > xContext(
1181 comphelper::getProcessComponentContext() );
1182 Reference< XInputStreamProvider > xISP = ::xmlscript::exportDialogModel( xDialogModel, xContext, GetDocument().isDocument() ? GetDocument().getDocument() : Reference< frame::XModel >() );
1183 xLib->replaceByName( GetName(), Any( xISP ) );
1184 }
1185 }
1186 }
1187 catch (const uno::Exception& )
1188 {
1189 DBG_UNHANDLED_EXCEPTION("basctl.basicide")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/basctl/source/basicide/baside3.cxx"
":" "1189" ": ", "basctl.basicide" );
;
1190 }
1191 MarkDocumentModified( GetDocument() );
1192 m_pEditor->ClearModifyFlag();
1193}
1194
1195void DialogWindow::Activating ()
1196{
1197 UpdateBrowser();
1198 Show();
1199}
1200
1201void DialogWindow::Deactivating()
1202{
1203 Hide();
1204 if ( IsModified() )
1205 MarkDocumentModified( GetDocument() );
1206 DisableBrowser();
1207}
1208
1209sal_Int32 DialogWindow::countPages( Printer* )
1210{
1211 return 1;
1212}
1213
1214void DialogWindow::printPage( sal_Int32 nPage, Printer* pPrinter )
1215{
1216 DlgEditor::printPage( nPage, pPrinter, CreateQualifiedName() );
1217}
1218
1219void DialogWindow::DataChanged( const DataChangedEvent& rDCEvt )
1220{
1221 if( (rDCEvt.GetType()==DataChangedEventType::SETTINGS) && (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
1222 {
1223 InitSettings();
1224 Invalidate();
1225 }
1226 else
1227 BaseWindow::DataChanged( rDCEvt );
1228}
1229
1230void DialogWindow::InitSettings()
1231{
1232 // FIXME RenderContext
1233 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1234 vcl::Font aFont = rStyleSettings.GetFieldFont();
1235 SetPointFont(*this, aFont);
1236
1237 SetTextColor( rStyleSettings.GetFieldTextColor() );
1238 SetTextFillColor();
1239
1240 SetBackground( rStyleSettings.GetFieldColor() );
1241}
1242
1243css::uno::Reference< css::accessibility::XAccessible > DialogWindow::CreateAccessible()
1244{
1245 return new AccessibleDialogWindow(this);
1246}
1247
1248char const* DialogWindow::GetHid () const
1249{
1250 return HID_BASICIDE_DIALOGWINDOW"BASCTL_HID_BASICIDE_DIALOGWINDOW";
1251}
1252ItemType DialogWindow::GetType () const
1253{
1254 return TYPE_DIALOG;
1255}
1256
1257
1258// DialogWindowLayout
1259
1260
1261DialogWindowLayout::DialogWindowLayout (vcl::Window* pParent, ObjectCatalog& rObjectCatalog_) :
1262 Layout(pParent),
1263 rObjectCatalog(rObjectCatalog_),
1264 pPropertyBrowser(nullptr)
1265{
1266 ShowPropertyBrowser();
1267}
1268
1269DialogWindowLayout::~DialogWindowLayout()
1270{
1271 disposeOnce();
1272}
1273
1274void DialogWindowLayout::dispose()
1275{
1276 if (pPropertyBrowser)
1
Taking true branch
1277 Remove(pPropertyBrowser);
1278 pPropertyBrowser.disposeAndClear();
2
Calling 'VclPtr::disposeAndClear'
1279 Layout::dispose();
1280}
1281
1282// shows the property browser (and creates if necessary)
1283void DialogWindowLayout::ShowPropertyBrowser ()
1284{
1285 // not exists?
1286 if (!pPropertyBrowser)
1287 {
1288 // creating
1289 pPropertyBrowser = VclPtr<PropBrw>::Create(*this);
1290 pPropertyBrowser->Show();
1291 // after OnFirstSize():
1292 if (HasSize())
1293 AddPropertyBrowser();
1294 // updating if necessary
1295 UpdatePropertyBrowser();
1296 }
1297 else
1298 pPropertyBrowser->Show();
1299 // refreshing the button state
1300 if (SfxBindings* pBindings = GetBindingsPtr())
1301 pBindings->Invalidate(SID_SHOW_PROPERTYBROWSER( 10000 + 943 ));
1302}
1303
1304// disables the property browser
1305void DialogWindowLayout::DisablePropertyBrowser ()
1306{
1307 if (pPropertyBrowser)
1308 pPropertyBrowser->Update(nullptr);
1309}
1310
1311// updates the property browser
1312void DialogWindowLayout::UpdatePropertyBrowser ()
1313{
1314 if (pPropertyBrowser)
1315 pPropertyBrowser->Update(GetShell());
1316}
1317
1318void DialogWindowLayout::Activating (BaseWindow& rChild)
1319{
1320 assert(dynamic_cast<DialogWindow*>(&rChild))(static_cast <bool> (dynamic_cast<DialogWindow*>(
&rChild)) ? void (0) : __assert_fail ("dynamic_cast<DialogWindow*>(&rChild)"
, "/home/maarten/src/libreoffice/core/basctl/source/basicide/baside3.cxx"
, 1320, __extension__ __PRETTY_FUNCTION__))
;
1321 rObjectCatalog.SetLayoutWindow(this);
1322 rObjectCatalog.UpdateEntries();
1323 rObjectCatalog.Show();
1324 if (pPropertyBrowser)
1325 pPropertyBrowser->Show();
1326 Layout::Activating(rChild);
1327}
1328
1329void DialogWindowLayout::Deactivating ()
1330{
1331 Layout::Deactivating();
1332 rObjectCatalog.Hide();
1333 if (pPropertyBrowser)
1334 pPropertyBrowser->Hide();
1335}
1336
1337void DialogWindowLayout::ExecuteGlobal (SfxRequest& rReq)
1338{
1339 switch (rReq.GetSlot())
1340 {
1341 case SID_SHOW_PROPERTYBROWSER( 10000 + 943 ):
1342 // toggling property browser
1343 if (pPropertyBrowser && pPropertyBrowser->IsVisible())
1344 pPropertyBrowser->Hide();
1345 else
1346 ShowPropertyBrowser();
1347 ArrangeWindows();
1348 // refreshing the button state
1349 if (SfxBindings* pBindings = GetBindingsPtr())
1350 pBindings->Invalidate(SID_SHOW_PROPERTYBROWSER( 10000 + 943 ));
1351 break;
1352 }
1353}
1354
1355void DialogWindowLayout::GetState (SfxItemSet& rSet, unsigned nWhich)
1356{
1357 switch (nWhich)
1358 {
1359 case SID_SHOW_PROPERTYBROWSER( 10000 + 943 ):
1360 rSet.Put(SfxBoolItem(nWhich, pPropertyBrowser && pPropertyBrowser->IsVisible()));
1361 break;
1362
1363 case SID_BASICIDE_CHOOSEMACRO( (30000 + 768) + 2 ):
1364 rSet.Put(SfxVisibilityItem(nWhich, false));
1365 break;
1366 }
1367}
1368
1369void DialogWindowLayout::OnFirstSize (long const nWidth, long const nHeight)
1370{
1371 AddToLeft(&rObjectCatalog, Size(nWidth * 0.25, nHeight * 0.35));
1372 if (pPropertyBrowser)
1373 AddPropertyBrowser();
1374}
1375
1376void DialogWindowLayout::AddPropertyBrowser () {
1377 Size const aSize = GetOutputSizePixel();
1378 AddToLeft(pPropertyBrowser, Size(aSize.Width() * 0.25, aSize.Height() * 0.65));
1379}
1380
1381
1382} // namespace basctl
1383
1384/* 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();
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);
3
Calling copy constructor for 'Reference<basctl::PropBrw>'
6
Returning from copy constructor for 'Reference<basctl::PropBrw>'
204 m_rInnerRef.clear(); // we should use some 'swap' method ideally ;-)
7
Calling 'Reference::clear'
14
Returning; memory was released
205 if (aTmp.get()) {
15
Calling 'Reference::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)
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)
4
Assuming field 'm_pBody' is non-null
5
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)
113 m_pBody->release();
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
7.1
Field 'm_pBody' is non-null
7.1
Field 'm_pBody' is non-null
7.1
Field 'm_pBody' is non-null
7.1
Field 'm_pBody' is non-null
)
8
Taking true branch
177 {
178 reference_type * const pOld = m_pBody;
179 m_pBody = NULL__null;
180 pOld->release();
9
Calling 'VclReferenceBase::release'
13
Returning; memory was released
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;
16
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)
10
Assuming the condition is true
11
Taking true branch
40 delete this;
12
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