File: | home/maarten/src/libreoffice/core/include/rtl/ref.hxx |
Warning: | line 192, column 9 Use of memory after it is freed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | ||||
61 | namespace basctl | |||
62 | { | |||
63 | ||||
64 | using namespace ::com::sun::star; | |||
65 | using namespace ::com::sun::star::uno; | |||
66 | using namespace ::com::sun::star::ucb; | |||
67 | using namespace ::com::sun::star::io; | |||
68 | using namespace ::com::sun::star::resource; | |||
69 | using namespace ::com::sun::star::ui::dialogs; | |||
70 | ||||
71 | #ifdef _WIN32 | |||
72 | char const FilterMask_All[] = "*.*"; | |||
73 | #else | |||
74 | char const FilterMask_All[] = "*"; | |||
75 | #endif | |||
76 | ||||
77 | DialogWindow::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 | ||||
105 | void DialogWindow::dispose() | |||
106 | { | |||
107 | m_pEditor.reset(); | |||
108 | BaseWindow::dispose(); | |||
109 | } | |||
110 | ||||
111 | void DialogWindow::LoseFocus() | |||
112 | { | |||
113 | if ( IsModified() ) | |||
114 | StoreData(); | |||
115 | ||||
116 | Window::LoseFocus(); | |||
117 | } | |||
118 | ||||
119 | void DialogWindow::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) | |||
120 | { | |||
121 | m_pEditor->Paint(rRenderContext, rRect); | |||
122 | } | |||
123 | ||||
124 | void DialogWindow::Resize() | |||
125 | { | |||
126 | if (GetHScrollBar() && GetVScrollBar()) | |||
127 | { | |||
128 | m_pEditor->SetScrollBars( GetHScrollBar(), GetVScrollBar() ); | |||
129 | } | |||
130 | } | |||
131 | ||||
132 | void 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 | ||||
140 | void 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 | ||||
159 | void DialogWindow::MouseMove( const MouseEvent& rMEvt ) | |||
160 | { | |||
161 | m_pEditor->MouseMove( rMEvt ); | |||
162 | } | |||
163 | ||||
164 | void 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 | ||||
193 | void 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 | ||||
225 | void 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 | ||||
232 | void DialogWindow::DoInit() | |||
233 | { | |||
234 | GetHScrollBar()->Show(); | |||
235 | GetVScrollBar()->Show(); | |||
236 | m_pEditor->SetScrollBars( GetHScrollBar(), GetVScrollBar() ); | |||
237 | } | |||
238 | ||||
239 | void DialogWindow::DoScroll( ScrollBar* ) | |||
240 | { | |||
241 | m_pEditor->DoScroll(); | |||
242 | } | |||
243 | ||||
244 | void 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 | ||||
391 | void 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 | ||||
577 | Reference< container::XNameContainer > const & DialogWindow::GetDialog() const | |||
578 | { | |||
579 | return m_pEditor->GetDialog(); | |||
580 | } | |||
581 | ||||
582 | bool 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 | ||||
593 | void DialogWindow::DisableBrowser() | |||
594 | { | |||
595 | m_rLayout.DisablePropertyBrowser(); | |||
596 | } | |||
597 | ||||
598 | void DialogWindow::UpdateBrowser() | |||
599 | { | |||
600 | m_rLayout.UpdatePropertyBrowser(); | |||
601 | } | |||
602 | ||||
603 | void 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 | ||||
758 | static 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 | ||||
792 | namespace { | |||
793 | ||||
794 | class NameClashQueryBox | |||
795 | { | |||
796 | private: | |||
797 | std::unique_ptr<weld::MessageDialog> m_xQueryBox; | |||
798 | public: | |||
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 | ||||
812 | class LanguageMismatchQueryBox | |||
813 | { | |||
814 | private: | |||
815 | std::unique_ptr<weld::MessageDialog> m_xQueryBox; | |||
816 | public: | |||
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 | ||||
833 | bool 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 | ||||
1105 | void DialogWindow::ImportDialog() | |||
1106 | { | |||
1107 | const ScriptDocument& rDocument = GetDocument(); | |||
1108 | OUString aLibName = GetLibName(); | |||
1109 | implImportDialog(GetFrameWeld(), m_sCurPath, rDocument, aLibName); | |||
1110 | } | |||
1111 | ||||
1112 | DlgEdModel& DialogWindow::GetModel() const | |||
1113 | { | |||
1114 | return m_pEditor->GetModel(); | |||
1115 | } | |||
1116 | ||||
1117 | DlgEdPage& DialogWindow::GetPage() const | |||
1118 | { | |||
1119 | return m_pEditor->GetPage(); | |||
1120 | } | |||
1121 | ||||
1122 | DlgEdView& DialogWindow::GetView() const | |||
1123 | { | |||
1124 | return m_pEditor->GetView(); | |||
1125 | } | |||
1126 | ||||
1127 | bool DialogWindow::IsModified() | |||
1128 | { | |||
1129 | return m_pEditor->IsModified(); | |||
1130 | } | |||
1131 | ||||
1132 | SfxUndoManager* DialogWindow::GetUndoManager() | |||
1133 | { | |||
1134 | return m_pUndoMgr.get(); | |||
1135 | } | |||
1136 | ||||
1137 | OUString DialogWindow::GetTitle() | |||
1138 | { | |||
1139 | return GetName(); | |||
1140 | } | |||
1141 | ||||
1142 | EntryDescriptor 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 | ||||
1150 | void DialogWindow::SetReadOnly (bool bReadOnly) | |||
1151 | { | |||
1152 | m_pEditor->SetMode(bReadOnly ? DlgEditor::READONLY : DlgEditor::SELECT); | |||
1153 | } | |||
1154 | ||||
1155 | bool DialogWindow::IsReadOnly () | |||
1156 | { | |||
1157 | return m_pEditor->GetMode() == DlgEditor::READONLY; | |||
1158 | } | |||
1159 | ||||
1160 | bool DialogWindow::IsPasteAllowed() | |||
1161 | { | |||
1162 | return m_pEditor->IsPasteAllowed(); | |||
1163 | } | |||
1164 | ||||
1165 | void 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 | ||||
1195 | void DialogWindow::Activating () | |||
1196 | { | |||
1197 | UpdateBrowser(); | |||
1198 | Show(); | |||
1199 | } | |||
1200 | ||||
1201 | void DialogWindow::Deactivating() | |||
1202 | { | |||
1203 | Hide(); | |||
1204 | if ( IsModified() ) | |||
1205 | MarkDocumentModified( GetDocument() ); | |||
1206 | DisableBrowser(); | |||
1207 | } | |||
1208 | ||||
1209 | sal_Int32 DialogWindow::countPages( Printer* ) | |||
1210 | { | |||
1211 | return 1; | |||
1212 | } | |||
1213 | ||||
1214 | void DialogWindow::printPage( sal_Int32 nPage, Printer* pPrinter ) | |||
1215 | { | |||
1216 | DlgEditor::printPage( nPage, pPrinter, CreateQualifiedName() ); | |||
1217 | } | |||
1218 | ||||
1219 | void 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 | ||||
1230 | void 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 | ||||
1243 | css::uno::Reference< css::accessibility::XAccessible > DialogWindow::CreateAccessible() | |||
1244 | { | |||
1245 | return new AccessibleDialogWindow(this); | |||
1246 | } | |||
1247 | ||||
1248 | char const* DialogWindow::GetHid () const | |||
1249 | { | |||
1250 | return HID_BASICIDE_DIALOGWINDOW"BASCTL_HID_BASICIDE_DIALOGWINDOW"; | |||
1251 | } | |||
1252 | ItemType DialogWindow::GetType () const | |||
1253 | { | |||
1254 | return TYPE_DIALOG; | |||
1255 | } | |||
1256 | ||||
1257 | ||||
1258 | // DialogWindowLayout | |||
1259 | ||||
1260 | ||||
1261 | DialogWindowLayout::DialogWindowLayout (vcl::Window* pParent, ObjectCatalog& rObjectCatalog_) : | |||
1262 | Layout(pParent), | |||
1263 | rObjectCatalog(rObjectCatalog_), | |||
1264 | pPropertyBrowser(nullptr) | |||
1265 | { | |||
1266 | ShowPropertyBrowser(); | |||
1267 | } | |||
1268 | ||||
1269 | DialogWindowLayout::~DialogWindowLayout() | |||
1270 | { | |||
1271 | disposeOnce(); | |||
1272 | } | |||
1273 | ||||
1274 | void DialogWindowLayout::dispose() | |||
1275 | { | |||
1276 | if (pPropertyBrowser) | |||
| ||||
1277 | Remove(pPropertyBrowser); | |||
1278 | pPropertyBrowser.disposeAndClear(); | |||
1279 | Layout::dispose(); | |||
1280 | } | |||
1281 | ||||
1282 | // shows the property browser (and creates if necessary) | |||
1283 | void 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 | |||
1305 | void DialogWindowLayout::DisablePropertyBrowser () | |||
1306 | { | |||
1307 | if (pPropertyBrowser) | |||
1308 | pPropertyBrowser->Update(nullptr); | |||
1309 | } | |||
1310 | ||||
1311 | // updates the property browser | |||
1312 | void DialogWindowLayout::UpdatePropertyBrowser () | |||
1313 | { | |||
1314 | if (pPropertyBrowser) | |||
1315 | pPropertyBrowser->Update(GetShell()); | |||
1316 | } | |||
1317 | ||||
1318 | void 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 | ||||
1329 | void DialogWindowLayout::Deactivating () | |||
1330 | { | |||
1331 | Layout::Deactivating(); | |||
1332 | rObjectCatalog.Hide(); | |||
1333 | if (pPropertyBrowser) | |||
1334 | pPropertyBrowser->Hide(); | |||
1335 | } | |||
1336 | ||||
1337 | void 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 | ||||
1355 | void 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 | ||||
1369 | void 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 | ||||
1376 | void 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: */ |
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 | |
36 | class VclReferenceBase; |
37 | |
38 | namespace vcl::detail { |
39 | |
40 | template<typename> |
41 | constexpr bool isIncompleteOrDerivedFromVclReferenceBase(...) { return true; } |
42 | |
43 | template<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 | */ |
56 | template <class reference_type> |
57 | class 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 | |
66 | public: |
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); |
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 | |
218 | template<typename T1, typename T2> |
219 | inline bool operator ==(VclPtr<T1> const & p1, VclPtr<T2> const & p2) { |
220 | return p1.get() == p2.get(); |
221 | } |
222 | |
223 | template<typename T> inline bool operator ==(VclPtr<T> const & p1, T const * p2) |
224 | { |
225 | return p1.get() == p2; |
226 | } |
227 | |
228 | template<typename T> inline bool operator ==(VclPtr<T> const & p1, T * p2) { |
229 | return p1.get() == p2; |
230 | } |
231 | |
232 | template<typename T> inline bool operator ==(T const * p1, VclPtr<T> const & p2) |
233 | { |
234 | return p1 == p2.get(); |
235 | } |
236 | |
237 | template<typename T> inline bool operator ==(T * p1, VclPtr<T> const & p2) { |
238 | return p1 == p2.get(); |
239 | } |
240 | |
241 | template<typename T1, typename T2> |
242 | inline bool operator !=(VclPtr<T1> const & p1, VclPtr<T2> const & p2) { |
243 | return !(p1 == p2); |
244 | } |
245 | |
246 | template<typename T> inline bool operator !=(VclPtr<T> const & p1, T const * p2) |
247 | { |
248 | return !(p1 == p2); |
249 | } |
250 | |
251 | template<typename T> inline bool operator !=(VclPtr<T> const & p1, T * p2) { |
252 | return !(p1 == p2); |
253 | } |
254 | |
255 | template<typename T> inline bool operator !=(T const * p1, VclPtr<T> const & p2) |
256 | { |
257 | return !(p1 == p2); |
258 | } |
259 | |
260 | template<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 | */ |
274 | template <class reference_type> |
275 | class SAL_WARN_UNUSED__attribute__((warn_unused)) VclPtrInstance final : public VclPtr<reference_type> |
276 | { |
277 | public: |
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 | |
290 | template <class reference_type> |
291 | class ScopedVclPtr : public VclPtr<reference_type> |
292 | { |
293 | public: |
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 | |
378 | private: |
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 | |
387 | protected: |
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 |
406 | template <class reference_type> |
407 | class SAL_WARN_UNUSED__attribute__((warn_unused)) ScopedVclPtrInstance final : public ScopedVclPtr<reference_type> |
408 | { |
409 | public: |
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 | |
421 | private: |
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: */ |
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 | |||||||||
34 | namespace rtl | ||||||||
35 | { | ||||||||
36 | |||||||||
37 | /** Template reference class for reference type. | ||||||||
38 | */ | ||||||||
39 | template <class reference_type> | ||||||||
40 | class Reference | ||||||||
41 | { | ||||||||
42 | /** The <b>reference_type</b> body pointer. | ||||||||
43 | */ | ||||||||
44 | reference_type * m_pBody; | ||||||||
45 | |||||||||
46 | |||||||||
47 | public: | ||||||||
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) | ||||||||
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
| ||||||||
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; | ||||||||
| |||||||||
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 | ||||||||
277 | namespace 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 | */ | ||||||||
286 | template<typename T> | ||||||||
287 | struct 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: */ |
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 | |
25 | class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclReferenceBase |
26 | { |
27 | mutable oslInterlockedCount mnRefCnt; |
28 | |
29 | template<typename T> friend class VclPtr; |
30 | |
31 | public: |
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) |
40 | delete this; |
41 | } |
42 | #ifdef DBG_UTIL |
43 | #ifndef _WIN32 |
44 | sal_Int32 getRefCount() const { return mnRefCnt; } |
45 | #endif |
46 | #endif |
47 | |
48 | |
49 | private: |
50 | VclReferenceBase(const VclReferenceBase&) = delete; |
51 | VclReferenceBase& operator=(const VclReferenceBase&) = delete; |
52 | |
53 | bool mbDisposed : 1; |
54 | |
55 | protected: |
56 | VclReferenceBase(); |
57 | protected: |
58 | virtual ~VclReferenceBase(); |
59 | |
60 | protected: |
61 | virtual void dispose(); |
62 | |
63 | public: |
64 | void disposeOnce(); |
65 | bool isDisposed() const { return mbDisposed; } |
66 | |
67 | }; |
68 | #endif |