Bump version to 24.04.3.4
[LibreOffice.git] / toolkit / source / awt / vclxtoolkit.cxx
blobfc6b7b9df8d91ff63f7afffdedf2810a9d6b3633
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sal/config.h>
22 #include <string_view>
23 #include <thread>
25 #ifdef _WIN32
26 #include <prewin.h>
27 #include <postwin.h>
28 #endif
29 #include <config_features.h>
30 #include <com/sun/star/awt/WindowAttribute.hpp>
31 #include <com/sun/star/awt/VclWindowPeerAttribute.hpp>
32 #include <com/sun/star/awt/WindowClass.hpp>
33 #include <com/sun/star/awt/MessageBoxButtons.hpp>
34 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
35 #include <com/sun/star/lang/SystemDependent.hpp>
36 #include <com/sun/star/awt/FocusEvent.hpp>
37 #include <com/sun/star/awt/KeyEvent.hpp>
38 #include <com/sun/star/awt/KeyModifier.hpp>
39 #include <com/sun/star/lang/EventObject.hpp>
40 #include <com/sun/star/uno/Reference.hxx>
41 #include <com/sun/star/uno/Sequence.hxx>
42 #include <com/sun/star/uno/XComponentContext.hpp>
43 #include <com/sun/star/uno/XInterface.hpp>
44 #include <com/sun/star/beans/NamedValue.hpp>
45 #include <com/sun/star/beans/XPropertyChangeListener.hpp>
46 #include <com/sun/star/beans/XPropertySet.hpp>
47 #include <com/sun/star/datatransfer/clipboard/SystemClipboard.hpp>
48 #include <com/sun/star/lang/XServiceInfo.hpp>
49 #include <com/sun/star/awt/XToolkitExperimental.hpp>
50 #include <com/sun/star/awt/XToolkitRobot.hpp>
52 #include <cppuhelper/basemutex.hxx>
53 #include <cppuhelper/bootstrap.hxx>
54 #include <cppuhelper/compbase.hxx>
55 #include <cppuhelper/supportsservice.hxx>
56 #include <o3tl/safeint.hxx>
57 #include <osl/conditn.hxx>
58 #include <osl/module.h>
59 #include <osl/thread.hxx>
60 #include <osl/mutex.hxx>
61 #include <rtl/ref.hxx>
62 #include <rtl/process.h>
63 #include <sal/log.hxx>
64 #include <tools/link.hxx>
65 #include <vcl/idletask.hxx>
66 #include <vcl/wintypes.hxx>
68 #ifdef MACOSX
69 #include <premac.h>
70 #include <Cocoa/Cocoa.h>
71 #include <postmac.h>
72 #endif
74 #include <utility>
75 #include <vcl/sysdata.hxx>
76 #include <vcl/textrectinfo.hxx>
77 #include <vcl/toolkit/vclmedit.hxx>
79 #include <toolkit/awt/vclxwindows.hxx>
80 #include <awt/vclxwindows.hxx>
81 #include <awt/vclxsystemdependentwindow.hxx>
82 #include <awt/vclxregion.hxx>
83 #include <awt/vclxtabpagecontainer.hxx>
84 #include <awt/vclxtopwindow.hxx>
86 #include <awt/animatedimagespeer.hxx>
87 #include <toolkit/awt/vclxwindow.hxx>
88 #include <toolkit/helper/vclunohelper.hxx>
89 #include <helper/property.hxx>
91 #include <toolkit/helper/convert.hxx>
92 #include <controls/filectrl.hxx>
93 #include <controls/svmedit.hxx>
94 #include <controls/table/tablecontrol.hxx>
95 #include <controls/treecontrolpeer.hxx>
96 #include <vcl/toolkit/button.hxx>
97 #include <vcl/toolkit/calendar.hxx>
98 #include <vcl/toolkit/combobox.hxx>
99 #include <vcl/ctrl.hxx>
100 #include <vcl/toolkit/dialog.hxx>
101 #include <vcl/dockingarea.hxx>
102 #include <vcl/dockwin.hxx>
103 #include <vcl/toolkit/edit.hxx>
104 #include <vcl/event.hxx>
105 #include <vcl/toolkit/field.hxx>
106 #include <vcl/toolkit/fixed.hxx>
107 #include <vcl/toolkit/fixedhyper.hxx>
108 #include <vcl/toolkit/floatwin.hxx>
109 #include <vcl/toolkit/fmtfield.hxx>
110 #include <vcl/toolkit/prgsbar.hxx>
111 #include <vcl/scheduler.hxx>
112 #include <vcl/toolkit/lstbox.hxx>
113 #include <vcl/toolkit/longcurr.hxx>
114 #include <vcl/toolkit/menubtn.hxx>
115 #include <vcl/stdtext.hxx>
116 #include <vcl/toolkit/scrbar.hxx>
117 #include <vcl/split.hxx>
118 #include <vcl/splitwin.hxx>
119 #include <vcl/status.hxx>
120 #include <vcl/svapp.hxx>
121 #include <vcl/syschild.hxx>
122 #include <vcl/tabctrl.hxx>
123 #include <vcl/tabpage.hxx>
124 #include <vcl/toolbox.hxx>
125 #include <vcl/virdev.hxx>
126 #include <vcl/window.hxx>
127 #include <vcl/wrkwin.hxx>
128 #include <vcl/toolkit/group.hxx>
129 #include <vcl/toolkit/imgctrl.hxx>
130 #include <vcl/toolkit/morebtn.hxx>
131 #include <vcl/toolkit/roadmap.hxx>
132 #include <vcl/toolkit/spin.hxx>
133 #include <vcl/toolkit/tabdlg.hxx>
134 #include <vcl/toolkit/throbber.hxx>
135 #if HAVE_FEATURE_OPENGL
136 #include <vcl/opengl/OpenGLWrapper.hxx>
137 #endif
138 #include <awt/vclxspinbutton.hxx>
139 #include <tools/debug.hxx>
140 #include <comphelper/diagnose_ex.hxx>
141 #include <comphelper/interfacecontainer3.hxx>
142 #include <comphelper/processfactory.hxx>
143 #include <comphelper/profilezone.hxx>
145 #include <helper/msgbox.hxx>
146 #include <helper/scrollabledialog.hxx>
147 #include <helper/unowrapper.hxx>
149 #if defined(_WIN32)
150 #define SYSTEM_DEPENDENT_TYPE css::lang::SystemDependent::SYSTEM_WIN32
151 #elif defined(MACOSX)
152 #define SYSTEM_DEPENDENT_TYPE css::lang::SystemDependent::SYSTEM_MAC
153 #elif defined(UNX)
154 #define SYSTEM_DEPENDENT_TYPE css::lang::SystemDependent::SYSTEM_XWINDOW
155 #endif
157 void MessBox::ImplInitButtons()
159 ButtonDialogFlags nOKFlags = ButtonDialogFlags::OK;
160 ButtonDialogFlags nCancelFlags = ButtonDialogFlags::Cancel;
161 ButtonDialogFlags nRetryFlags = ButtonDialogFlags::NONE;
162 ButtonDialogFlags nYesFlags = ButtonDialogFlags::NONE;
163 ButtonDialogFlags nNoFlags = ButtonDialogFlags::NONE;
165 if ( mnMessBoxStyle & MessBoxStyle::OkCancel )
167 if ( mnMessBoxStyle & MessBoxStyle::DefaultCancel )
168 nCancelFlags |= ButtonDialogFlags::Default | ButtonDialogFlags::Focus;
169 else // MessBoxStyle::DefaultOk
170 nOKFlags |= ButtonDialogFlags::Default | ButtonDialogFlags::Focus;
172 AddButton( StandardButtonType::OK, RET_OK, nOKFlags );
173 AddButton( StandardButtonType::Cancel, RET_CANCEL, nCancelFlags );
175 else if ( mnMessBoxStyle & MessBoxStyle::YesNo )
177 if ( mnMessBoxStyle & MessBoxStyle::DefaultYes )
178 nYesFlags |= ButtonDialogFlags::Default | ButtonDialogFlags::Focus;
179 else // MessBoxStyle::DefaultNo
180 nNoFlags |= ButtonDialogFlags::Default | ButtonDialogFlags::Focus;
181 nNoFlags |= ButtonDialogFlags::Cancel;
183 AddButton( StandardButtonType::Yes, RET_YES, nYesFlags );
184 AddButton( StandardButtonType::No, RET_NO, nNoFlags );
186 else if ( mnMessBoxStyle & MessBoxStyle::YesNoCancel )
188 if ( mnMessBoxStyle & MessBoxStyle::DefaultYes )
189 nYesFlags |= ButtonDialogFlags::Default | ButtonDialogFlags::Focus;
190 else if ( mnMessBoxStyle & MessBoxStyle::DefaultNo )
191 nNoFlags |= ButtonDialogFlags::Default | ButtonDialogFlags::Focus;
192 else
193 nCancelFlags |= ButtonDialogFlags::Default | ButtonDialogFlags::Focus;
195 AddButton( StandardButtonType::Yes, RET_YES, nYesFlags );
196 AddButton( StandardButtonType::No, RET_NO, nNoFlags );
197 AddButton( StandardButtonType::Cancel, RET_CANCEL, nCancelFlags );
199 else if ( mnMessBoxStyle & MessBoxStyle::RetryCancel )
201 if ( mnMessBoxStyle & MessBoxStyle::DefaultCancel )
202 nCancelFlags |= ButtonDialogFlags::Default | ButtonDialogFlags::Focus;
203 else // MessBoxStyle::DefaultRetry
204 nRetryFlags |= ButtonDialogFlags::Default | ButtonDialogFlags::Focus;
206 AddButton( StandardButtonType::Retry, RET_RETRY, nRetryFlags );
207 AddButton( StandardButtonType::Cancel, RET_CANCEL, nCancelFlags );
209 else if ( mnMessBoxStyle & MessBoxStyle::AbortRetryIgnore )
211 ButtonDialogFlags nAbortFlags = ButtonDialogFlags::NONE;
212 ButtonDialogFlags nIgnoreFlags = ButtonDialogFlags::NONE;
214 if ( mnMessBoxStyle & MessBoxStyle::DefaultCancel )
215 nAbortFlags |= ButtonDialogFlags::Default | ButtonDialogFlags::Focus;
216 else if ( mnMessBoxStyle & MessBoxStyle::DefaultRetry )
217 nRetryFlags |= ButtonDialogFlags::Default | ButtonDialogFlags::Focus;
218 else if ( mnMessBoxStyle & MessBoxStyle::DefaultIgnore )
219 nIgnoreFlags |= ButtonDialogFlags::Default | ButtonDialogFlags::Focus;
221 AddButton( StandardButtonType::Abort, RET_CANCEL, nAbortFlags );
222 AddButton( StandardButtonType::Retry, RET_RETRY, nRetryFlags );
223 AddButton( StandardButtonType::Ignore, RET_IGNORE, nIgnoreFlags );
225 else if ( mnMessBoxStyle & MessBoxStyle::Ok )
227 nOKFlags |= ButtonDialogFlags::Default | ButtonDialogFlags::Focus;
229 AddButton( StandardButtonType::OK, RET_OK, nOKFlags );
233 MessBox::MessBox(vcl::Window* pParent, MessBoxStyle nMessBoxStyle, WinBits nWinBits,
234 const OUString& rTitle, OUString aMessage) :
235 ButtonDialog( WindowType::MESSBOX ),
236 mbHelpBtn( false ),
237 mnMessBoxStyle( nMessBoxStyle ),
238 maMessText(std::move( aMessage ))
240 ImplLOKNotifier(pParent);
241 ImplInitDialog(pParent, nWinBits | WB_MOVEABLE | WB_HORZ | WB_CENTER);
242 ImplInitButtons();
244 if ( !rTitle.isEmpty() )
245 SetText( rTitle );
248 MessBox::~MessBox()
250 disposeOnce();
253 void MessBox::dispose()
255 mpVCLMultiLineEdit.disposeAndClear();
256 mpFixedImage.disposeAndClear();
257 ButtonDialog::dispose();
260 void MessBox::ImplPosControls()
262 if ( !GetHelpId().isEmpty() )
264 if ( !mbHelpBtn )
266 AddButton( StandardButtonType::Help, RET_HELP, ButtonDialogFlags::Help, 3 );
267 mbHelpBtn = true;
270 else
272 if ( mbHelpBtn )
274 RemoveButton( RET_HELP );
275 mbHelpBtn = false;
279 TextRectInfo aTextInfo;
280 tools::Rectangle aRect( 0, 0, 30000, 30000 );
281 tools::Rectangle aFormatRect;
282 Point aTextPos( IMPL_DIALOG_OFFSET, IMPL_DIALOG_OFFSET+IMPL_MSGBOX_OFFSET_EXTRA_Y );
283 Size aImageSize;
284 Size aPageSize;
285 Size aMEditSize;
286 tools::Long nTitleWidth;
287 tools::Long nButtonSize = ImplGetButtonSize();
288 tools::Long nMaxLineWidth;
289 tools::Long nWidth;
290 WinBits nWinStyle = WB_LEFT | WB_NOLABEL;
291 DrawTextFlags nTextStyle = DrawTextFlags::MultiLine | DrawTextFlags::Top | DrawTextFlags::Left;
293 mpVCLMultiLineEdit.disposeAndClear();
294 mpFixedImage.disposeAndClear();
296 // Clean up message text with tabs
297 OUString aMessText(maMessText.replaceAll("\t", " "));
299 //If window too small, we make dialog box be wider
300 tools::Long nMaxWidth = 630 * GetDPIScaleFactor();
302 // MessagBox should be at least as wide as to see the title
303 // Extra-Width for Close button, because Close button is set after this call
304 nTitleWidth = CalcTitleWidth();
306 nMaxWidth -= (IMPL_DIALOG_OFFSET*2)+(IMPL_MSGBOX_OFFSET_EXTRA_X*2);
308 // for an image, get its size, create a suitable control and position it
309 aImageSize = maImage.GetSizePixel();
310 if ( aImageSize.Width() )
312 aImageSize.AdjustWidth(4 );
313 aImageSize.AdjustHeight(4 );
314 aTextPos.AdjustX(aImageSize.Width()+IMPL_SEP_MSGBOX_IMAGE );
315 mpFixedImage = VclPtr<FixedImage>::Create( this );
316 mpFixedImage->SetPosSizePixel( Point( IMPL_DIALOG_OFFSET-2+IMPL_MSGBOX_OFFSET_EXTRA_X,
317 IMPL_DIALOG_OFFSET-2+IMPL_MSGBOX_OFFSET_EXTRA_Y ),
318 aImageSize );
319 mpFixedImage->SetImage( maImage );
320 mpFixedImage->Show();
321 nMaxWidth -= aImageSize.Width()+IMPL_SEP_MSGBOX_IMAGE;
323 else
324 aTextPos.AdjustX(IMPL_MSGBOX_OFFSET_EXTRA_X );
326 // Determine maximum line length without wordbreak
327 aFormatRect = GetTextRect( aRect, aMessText, nTextStyle, &aTextInfo );
328 nMaxLineWidth = aFormatRect.GetWidth();
329 nTextStyle |= DrawTextFlags::WordBreak;
331 // Determine the width for text formatting
332 if ( nMaxLineWidth > 450 )
333 nWidth = 450;
334 else if ( nMaxLineWidth > 300 )
335 nWidth = nMaxLineWidth+5;
336 else
337 nWidth = 300;
339 nWidth *= GetDPIScaleFactor();
341 if ( nButtonSize > nWidth )
342 nWidth = nButtonSize-(aTextPos.X()-IMPL_DIALOG_OFFSET);
343 if ( nWidth > nMaxWidth )
344 nWidth = nMaxWidth;
346 aRect.SetRight( nWidth );
347 aFormatRect = GetTextRect( aRect, aMessText, nTextStyle, &aTextInfo );
348 if ( aTextInfo.GetMaxLineWidth() > nWidth )
350 nWidth = aTextInfo.GetMaxLineWidth()+8;
351 aRect.SetRight( nWidth );
352 aFormatRect = GetTextRect( aRect, aMessText, nTextStyle, &aTextInfo );
355 // get Style for VCLMultiLineEdit
356 aMEditSize.setWidth( aTextInfo.GetMaxLineWidth()+1 );
357 aMEditSize.setHeight( aFormatRect.GetHeight() );
358 aPageSize.setWidth( aImageSize.Width() );
359 if ( aMEditSize.Height() < aImageSize.Height() )
361 nWinStyle |= WB_VCENTER;
362 aPageSize.setHeight( aImageSize.Height() );
363 aMEditSize.setHeight( aImageSize.Height() );
365 else
367 nWinStyle |= WB_TOP;
368 aPageSize.setHeight( aMEditSize.Height() );
370 if ( aImageSize.Width() )
371 aPageSize.AdjustWidth(IMPL_SEP_MSGBOX_IMAGE );
372 aPageSize.AdjustWidth((IMPL_DIALOG_OFFSET*2)+(IMPL_MSGBOX_OFFSET_EXTRA_X*2) );
373 aPageSize.AdjustWidth(aMEditSize.Width()+1 );
374 aPageSize.AdjustHeight((IMPL_DIALOG_OFFSET*2)+(IMPL_MSGBOX_OFFSET_EXTRA_Y*2) );
376 if ( aPageSize.Width() < IMPL_MINSIZE_MSGBOX_WIDTH )
377 aPageSize.setWidth( IMPL_MINSIZE_MSGBOX_WIDTH );
378 if ( aPageSize.Width() < nTitleWidth )
379 aPageSize.setWidth( nTitleWidth );
381 mpVCLMultiLineEdit = VclPtr<VclMultiLineEdit>::Create( this, nWinStyle );
382 mpVCLMultiLineEdit->SetText( aMessText );
383 mpVCLMultiLineEdit->SetPosSizePixel( aTextPos, aMEditSize );
384 mpVCLMultiLineEdit->Show();
385 mpVCLMultiLineEdit->SetPaintTransparent(true);
386 mpVCLMultiLineEdit->EnableCursor(false);
387 SetPageSizePixel( aPageSize );
390 void MessBox::StateChanged( StateChangedType nType )
392 if ( nType == StateChangedType::InitShow )
394 ImplPosControls();
396 ButtonDialog::StateChanged( nType );
399 Size MessBox::GetOptimalSize() const
401 // FIXME: base me on the font size ?
402 return Size( 250, 100 );
406 namespace {
408 class Pause : public Idle
410 public:
411 explicit Pause(sal_Int32 nPauseMilliseconds) :
412 Idle("pause"),
413 m_nPauseMilliseconds(nPauseMilliseconds)
415 SetPriority(TaskPriority::HIGHEST);
416 Start();
419 virtual void Invoke() override
421 SolarMutexGuard aSolarGuard;
422 std::this_thread::sleep_for(std::chrono::milliseconds(m_nPauseMilliseconds));
423 Stop();
424 delete this;
427 sal_Int32 m_nPauseMilliseconds;
430 class VCLXToolkit : public cppu::BaseMutex,
431 public cppu::WeakComponentImplHelper<
432 css::awt::XToolkitExperimental,
433 css::awt::XToolkitRobot,
434 css::lang::XServiceInfo >
436 css::uno::Reference< css::datatransfer::clipboard::XClipboard > mxClipboard;
437 css::uno::Reference< css::datatransfer::clipboard::XClipboard > mxSelection;
439 ::comphelper::OInterfaceContainerHelper3<css::awt::XTopWindowListener> m_aTopWindowListeners;
440 ::comphelper::OInterfaceContainerHelper3<css::awt::XKeyHandler> m_aKeyHandlers;
441 ::comphelper::OInterfaceContainerHelper3<css::awt::XFocusListener> m_aFocusListeners;
442 ::Link<VclSimpleEvent&,void> m_aEventListenerLink;
443 ::Link<VclWindowEvent&,bool> m_aKeyListenerLink;
444 bool m_bEventListener;
445 bool m_bKeyListener;
447 DECL_LINK(eventListenerHandler, ::VclSimpleEvent&, void);
449 DECL_LINK(keyListenerHandler, ::VclWindowEvent&, bool);
451 void callTopWindowListeners(
452 ::VclSimpleEvent const * pEvent,
453 void (SAL_CALL css::awt::XTopWindowListener::* pFn)(
454 css::lang::EventObject const &));
456 bool callKeyHandlers(::VclSimpleEvent const * pEvent, bool bPressed);
458 void callFocusListeners(::VclSimpleEvent const * pEvent, bool bGained);
460 protected:
461 ::osl::Mutex& GetMutex() { return m_aMutex; }
463 virtual void SAL_CALL disposing() override;
465 static vcl::Window* ImplCreateWindow( rtl::Reference<VCLXWindow>* ppNewComp, const css::awt::WindowDescriptor& rDescriptor, vcl::Window* pParent,
466 WinBits nWinBits, MessBoxStyle nMessBoxStyle );
467 css::uno::Reference< css::awt::XWindowPeer > ImplCreateWindow( const css::awt::WindowDescriptor& Descriptor,
468 MessBoxStyle nForceMessBoxStyle );
470 public:
472 VCLXToolkit();
474 // css::awt::XToolkitExperimental
475 virtual void SAL_CALL processEventsToIdle() override;
477 virtual sal_Int64 SAL_CALL getOpenGLBufferSwapCounter() override;
479 virtual void SAL_CALL setDeterministicScheduling(sal_Bool bDeterministicMode) override;
481 virtual void SAL_CALL pause(sal_Int32 nMilliseconds) override;
483 virtual void SAL_CALL startRecording() override;
485 virtual void SAL_CALL stopRecording() override;
487 css::uno::Sequence< OUString > SAL_CALL getRecordingAndClear() override;
489 virtual void SAL_CALL waitUntilAllIdlesDispatched() override;
491 // css::awt::XToolkit
492 css::uno::Reference< css::awt::XWindowPeer > SAL_CALL getDesktopWindow( ) override;
493 css::awt::Rectangle SAL_CALL getWorkArea( ) override;
494 css::uno::Reference< css::awt::XWindowPeer > SAL_CALL createWindow( const css::awt::WindowDescriptor& Descriptor ) override;
495 css::uno::Sequence< css::uno::Reference< css::awt::XWindowPeer > > SAL_CALL createWindows( const css::uno::Sequence< css::awt::WindowDescriptor >& Descriptors ) override;
496 css::uno::Reference< css::awt::XDevice > SAL_CALL createScreenCompatibleDevice( sal_Int32 Width, sal_Int32 Height ) override;
497 css::uno::Reference< css::awt::XRegion > SAL_CALL createRegion( ) override;
499 // css::awt::XSystemChildFactory
500 css::uno::Reference< css::awt::XWindowPeer > SAL_CALL createSystemChild( const css::uno::Any& Parent, const css::uno::Sequence< sal_Int8 >& ProcessId, sal_Int16 SystemType ) override;
502 // css::awt::XMessageBoxFactory
503 virtual css::uno::Reference< css::awt::XMessageBox > SAL_CALL createMessageBox( const css::uno::Reference< css::awt::XWindowPeer >& aParent, css::awt::MessageBoxType eType, ::sal_Int32 aButtons, const OUString& aTitle, const OUString& aMessage ) override;
505 // css::awt::XDataTransfer
506 css::uno::Reference< css::datatransfer::dnd::XDragGestureRecognizer > SAL_CALL getDragGestureRecognizer( const css::uno::Reference< css::awt::XWindow >& window ) override;
507 css::uno::Reference< css::datatransfer::dnd::XDragSource > SAL_CALL getDragSource( const css::uno::Reference< css::awt::XWindow >& window ) override;
508 css::uno::Reference< css::datatransfer::dnd::XDropTarget > SAL_CALL getDropTarget( const css::uno::Reference< css::awt::XWindow >& window ) override;
509 css::uno::Reference< css::datatransfer::clipboard::XClipboard > SAL_CALL getClipboard( const OUString& clipboardName ) override;
511 // css::lang::XServiceInfo
512 OUString SAL_CALL getImplementationName( ) override;
513 sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
514 css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override;
516 // css::awt::XExtendedToolkit:
518 virtual ::sal_Int32 SAL_CALL getTopWindowCount() override;
520 virtual css::uno::Reference< css::awt::XTopWindow >
521 SAL_CALL getTopWindow(::sal_Int32 nIndex) override;
523 virtual css::uno::Reference< css::awt::XTopWindow >
524 SAL_CALL getActiveTopWindow() override;
526 virtual void SAL_CALL addTopWindowListener(
527 css::uno::Reference<
528 css::awt::XTopWindowListener > const & rListener) override;
530 virtual void SAL_CALL removeTopWindowListener(
531 css::uno::Reference<
532 css::awt::XTopWindowListener > const & rListener) override;
534 virtual void SAL_CALL addKeyHandler(
535 css::uno::Reference<
536 css::awt::XKeyHandler > const & rHandler) override;
538 virtual void SAL_CALL removeKeyHandler(
539 css::uno::Reference<
540 css::awt::XKeyHandler > const & rHandler) override;
542 virtual void SAL_CALL addFocusListener(
543 css::uno::Reference<
544 css::awt::XFocusListener > const & rListener) override;
546 virtual void SAL_CALL removeFocusListener(
547 css::uno::Reference<
548 css::awt::XFocusListener > const & rListener) override;
550 virtual void SAL_CALL fireFocusGained(
551 css::uno::Reference<
552 css::uno::XInterface > const & source) override;
554 virtual void SAL_CALL fireFocusLost(
555 css::uno::Reference<
556 css::uno::XInterface > const & source) override;
558 // css::awt::XReschedule:
559 virtual void SAL_CALL reschedule() override;
561 // css::awt::XFontMappingUse:
562 virtual void SAL_CALL startTrackingFontMappingUse() override;
564 virtual css::uno::Sequence<css::awt::XFontMappingUseItem> SAL_CALL finishTrackingFontMappingUse() override;
566 // css:awt:XToolkitRobot
567 virtual void SAL_CALL keyPress( const css::awt::KeyEvent & aKeyEvent ) override;
569 virtual void SAL_CALL keyRelease( const css::awt::KeyEvent & aKeyEvent ) override;
571 virtual void SAL_CALL mousePress( const css::awt::MouseEvent & aMouseEvent ) override;
573 virtual void SAL_CALL mouseRelease( const css::awt::MouseEvent & aMouseEvent ) override;
575 virtual void SAL_CALL mouseMove( const css::awt::MouseEvent & aMouseEvent ) override;
579 std::pair<WinBits,MessBoxStyle> ImplGetWinBits( sal_uInt32 nComponentAttribs, WindowType nCompType )
581 WinBits nWinBits = 0;
582 MessBoxStyle nStyle = MessBoxStyle::NONE;
584 bool bMessBox = false;
585 if ( ( nCompType == WindowType::INFOBOX ) ||
586 ( nCompType == WindowType::MESSBOX ) ||
587 ( nCompType == WindowType::QUERYBOX ) ||
588 ( nCompType == WindowType::WARNINGBOX ) ||
589 ( nCompType == WindowType::ERRORBOX ) )
591 bMessBox = true;
594 bool bDecoratedWindow = false;
595 if ( bMessBox
596 || ( nCompType == WindowType::DIALOG )
597 || ( nCompType == WindowType::MODELESSDIALOG )
598 || ( nCompType == WindowType::DOCKINGWINDOW )
599 || ( nCompType == WindowType::TABDIALOG )
600 || ( nCompType == WindowType::BUTTONDIALOG )
601 || ( nCompType == WindowType::SYSTEMCHILDWINDOW )
604 bDecoratedWindow = true;
607 if( nComponentAttribs & css::awt::WindowAttribute::BORDER )
608 nWinBits |= WB_BORDER;
609 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::NOBORDER )
610 nWinBits |= WB_NOBORDER;
611 if( nComponentAttribs & css::awt::WindowAttribute::SIZEABLE )
612 nWinBits |= WB_SIZEABLE;
613 if( nComponentAttribs & css::awt::WindowAttribute::MOVEABLE )
614 nWinBits |= WB_MOVEABLE;
615 if( nComponentAttribs & css::awt::WindowAttribute::CLOSEABLE )
616 nWinBits |= WB_CLOSEABLE;
617 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::HSCROLL )
618 nWinBits |= WB_HSCROLL;
619 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::VSCROLL )
620 nWinBits |= WB_VSCROLL;
621 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::LEFT )
622 nWinBits |= WB_LEFT;
623 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::CENTER )
624 nWinBits |= WB_CENTER;
625 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::RIGHT )
626 nWinBits |= WB_RIGHT;
627 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::SPIN )
628 nWinBits |= WB_SPIN;
629 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::SORT )
630 nWinBits |= WB_SORT;
631 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::DROPDOWN )
632 nWinBits |= WB_DROPDOWN;
633 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::DEFBUTTON )
634 nWinBits |= WB_DEFBUTTON;
635 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::READONLY )
636 nWinBits |= WB_READONLY;
637 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::CLIPCHILDREN )
638 nWinBits |= WB_CLIPCHILDREN;
639 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::GROUP )
640 nWinBits |= WB_GROUP;
641 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::NOLABEL ) //added for issue79712
642 nWinBits |= WB_NOLABEL;
644 // These bits are not unique
645 if ( bMessBox )
647 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::OK )
648 nStyle |= MessBoxStyle::Ok;
649 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::OK_CANCEL )
650 nStyle |= MessBoxStyle::OkCancel;
651 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::YES_NO )
652 nStyle |= MessBoxStyle::YesNo;
653 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::YES_NO_CANCEL )
654 nStyle |= MessBoxStyle::YesNoCancel;
655 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::RETRY_CANCEL )
656 nStyle |= MessBoxStyle::RetryCancel;
657 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::DEF_OK )
658 nStyle |= MessBoxStyle::DefaultOk;
659 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::DEF_CANCEL )
660 nStyle |= MessBoxStyle::DefaultCancel;
661 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::DEF_RETRY )
662 nStyle |= MessBoxStyle::DefaultRetry;
663 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::DEF_YES )
664 nStyle |= MessBoxStyle::DefaultYes;
665 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::DEF_NO )
666 nStyle |= MessBoxStyle::DefaultNo;
668 if ( nCompType == WindowType::MULTILINEEDIT || nCompType == WindowType::DIALOG
669 || nCompType == WindowType::GROUPBOX || nCompType == WindowType::TABPAGE )
671 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::AUTOHSCROLL )
672 nWinBits |= WB_AUTOHSCROLL;
673 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::AUTOVSCROLL )
674 nWinBits |= WB_AUTOVSCROLL;
678 if ( bDecoratedWindow )
680 if( nComponentAttribs & css::awt::WindowAttribute::NODECORATION )
682 // No decoration removes several window attributes and must
683 // set WB_NOBORDER!
684 nWinBits &= ~WB_BORDER;
685 nWinBits &= ~WB_SIZEABLE;
686 nWinBits &= ~WB_MOVEABLE;
687 nWinBits &= ~WB_CLOSEABLE;
688 nWinBits |= WB_NOBORDER;
692 return { nWinBits, nStyle };
695 struct ComponentInfo
697 std::u16string_view sName;
698 WindowType nWinType;
701 ComponentInfo const aComponentInfos [] =
703 { std::u16string_view(u"animatedimages"), WindowType::CONTROL },
704 { std::u16string_view(u"buttondialog"), WindowType::BUTTONDIALOG },
705 { std::u16string_view(u"cancelbutton"), WindowType::CANCELBUTTON },
706 { std::u16string_view(u"checkbox"), WindowType::CHECKBOX },
707 { std::u16string_view(u"combobox"), WindowType::COMBOBOX },
708 { std::u16string_view(u"control"), WindowType::CONTROL },
709 { std::u16string_view(u"currencybox"), WindowType::CURRENCYBOX },
710 { std::u16string_view(u"currencyfield"), WindowType::CURRENCYFIELD },
711 { std::u16string_view(u"datebox"), WindowType::DATEBOX },
712 { std::u16string_view(u"datefield"), WindowType::CONTROL },
713 { std::u16string_view(u"dialog"), WindowType::DIALOG },
714 { std::u16string_view(u"dockingarea"), WindowType::DOCKINGAREA },
715 { std::u16string_view(u"dockingwindow"), WindowType::DOCKINGWINDOW },
716 { std::u16string_view(u"edit"), WindowType::EDIT },
717 { std::u16string_view(u"errorbox"), WindowType::ERRORBOX },
718 { std::u16string_view(u"filecontrol"), WindowType::CONTROL },
719 { std::u16string_view(u"fixedbitmap"), WindowType::FIXEDBITMAP },
720 { std::u16string_view(u"fixedhyperlink"), WindowType::CONTROL },
721 { std::u16string_view(u"fixedimage"), WindowType::FIXEDIMAGE },
722 { std::u16string_view(u"fixedline"), WindowType::FIXEDLINE },
723 { std::u16string_view(u"fixedtext"), WindowType::FIXEDTEXT },
724 { std::u16string_view(u"floatingwindow"), WindowType::FLOATINGWINDOW },
725 { std::u16string_view(u"formattedfield"), WindowType::CONTROL },
726 { std::u16string_view(u"frame"), WindowType::GROUPBOX },
727 { std::u16string_view(u"framewindow"), WindowType::TOOLKIT_FRAMEWINDOW },
728 { std::u16string_view(u"grid"), WindowType::CONTROL },
729 { std::u16string_view(u"groupbox"), WindowType::GROUPBOX },
730 { std::u16string_view(u"helpbutton"), WindowType::HELPBUTTON },
731 { std::u16string_view(u"imagebutton"), WindowType::IMAGEBUTTON },
732 { std::u16string_view(u"infobox"), WindowType::INFOBOX },
733 { std::u16string_view(u"listbox"), WindowType::LISTBOX },
734 { std::u16string_view(u"longcurrencybox"), WindowType::LONGCURRENCYBOX },
735 { std::u16string_view(u"longcurrencyfield"), WindowType::CONTROL },
736 { std::u16string_view(u"menubutton"), WindowType::MENUBUTTON },
737 { std::u16string_view(u"messbox"), WindowType::MESSBOX },
738 { std::u16string_view(u"metricbox"), WindowType::METRICBOX },
739 { std::u16string_view(u"metricfield"), WindowType::METRICFIELD },
740 { std::u16string_view(u"modelessdialog"), WindowType::MODELESSDIALOG },
741 { std::u16string_view(u"morebutton"), WindowType::MOREBUTTON },
742 { std::u16string_view(u"multilineedit"), WindowType::MULTILINEEDIT },
743 { std::u16string_view(u"multilistbox"), WindowType::MULTILISTBOX },
744 { std::u16string_view(u"numericbox"), WindowType::NUMERICBOX },
745 { std::u16string_view(u"numericfield"), WindowType::CONTROL },
746 { std::u16string_view(u"okbutton"), WindowType::OKBUTTON },
747 { std::u16string_view(u"patternbox"), WindowType::PATTERNBOX },
748 { std::u16string_view(u"patternfield"), WindowType::PATTERNFIELD },
749 { std::u16string_view(u"progressbar"), WindowType::CONTROL },
750 { std::u16string_view(u"pushbutton"), WindowType::PUSHBUTTON },
751 { std::u16string_view(u"querybox"), WindowType::QUERYBOX },
752 { std::u16string_view(u"radiobutton"), WindowType::RADIOBUTTON },
753 { std::u16string_view(u"roadmap"), WindowType::CONTROL },
754 { std::u16string_view(u"scrollbar"), WindowType::SCROLLBAR },
755 { std::u16string_view(u"scrollbarbox"), WindowType::SCROLLBARBOX },
756 { std::u16string_view(u"spinbutton"), WindowType::SPINBUTTON },
757 { std::u16string_view(u"spinfield"), WindowType::SPINFIELD },
758 { std::u16string_view(u"splitter"), WindowType::SPLITTER },
759 { std::u16string_view(u"splitwindow"), WindowType::SPLITWINDOW },
760 { std::u16string_view(u"statusbar"), WindowType::STATUSBAR },
761 { std::u16string_view(u"systemchildwindow"), WindowType::TOOLKIT_SYSTEMCHILDWINDOW },
762 { std::u16string_view(u"tabcontrol"), WindowType::TABCONTROL },
763 { std::u16string_view(u"tabdialog"), WindowType::TABDIALOG },
764 { std::u16string_view(u"tabpage"), WindowType::TABPAGE },
765 { std::u16string_view(u"tabpagecontainer"), WindowType::CONTROL },
766 { std::u16string_view(u"tabpagemodel"), WindowType::TABPAGE },
767 { std::u16string_view(u"timebox"), WindowType::TIMEBOX },
768 { std::u16string_view(u"timefield"), WindowType::TIMEFIELD },
769 { std::u16string_view(u"toolbox"), WindowType::TOOLBOX },
770 { std::u16string_view(u"tree"), WindowType::CONTROL },
771 { std::u16string_view(u"tristatebox"), WindowType::TRISTATEBOX },
772 { std::u16string_view(u"warningbox"), WindowType::WARNINGBOX },
773 { std::u16string_view(u"window"), WindowType::WINDOW },
774 { std::u16string_view(u"workwindow"), WindowType::WORKWINDOW }
777 bool ComponentInfoFindCompare( const ComponentInfo & lhs, const OUString & s)
779 return rtl_ustr_compareIgnoreAsciiCase_WithLength(s.pData->buffer, s.pData->length,
780 lhs.sName.data(), lhs.sName.size()) > 0;
783 WindowType ImplGetComponentType( const OUString& rServiceName )
785 static bool bSorted = false;
786 if( !bSorted )
788 assert( std::is_sorted( std::begin(aComponentInfos), std::end(aComponentInfos),
789 [](const ComponentInfo & lhs, const ComponentInfo & rhs) {
790 return
791 rtl_ustr_compare_WithLength(
792 lhs.sName.data(), lhs.sName.size(), rhs.sName.data(),
793 rhs.sName.size())
794 < 0;
795 } ) );
796 bSorted = true;
799 OUString sSearch;
800 if ( !rServiceName.isEmpty() )
801 sSearch = rServiceName;
802 else
803 sSearch = "window";
805 auto it = std::lower_bound( std::begin(aComponentInfos), std::end(aComponentInfos), sSearch,
806 ComponentInfoFindCompare );
807 if (it != std::end(aComponentInfos) &&
808 rtl_ustr_compareIgnoreAsciiCase_WithLength(sSearch.pData->buffer, sSearch.pData->length, it->sName.data(), it->sName.size()) == 0)
809 return it->nWinType;
810 return WindowType::NONE;
813 struct MessageBoxTypeInfo
815 css::awt::MessageBoxType eType;
816 const char *pName;
817 sal_Int32 nLen;
820 const MessageBoxTypeInfo aMessageBoxTypeInfo[] =
822 { css::awt::MessageBoxType_MESSAGEBOX, RTL_CONSTASCII_STRINGPARAM("messbox") },
823 { css::awt::MessageBoxType_INFOBOX, RTL_CONSTASCII_STRINGPARAM("infobox") },
824 { css::awt::MessageBoxType_WARNINGBOX, RTL_CONSTASCII_STRINGPARAM("warningbox") },
825 { css::awt::MessageBoxType_ERRORBOX, RTL_CONSTASCII_STRINGPARAM("errorbox") },
826 { css::awt::MessageBoxType_QUERYBOX, RTL_CONSTASCII_STRINGPARAM("querybox") },
827 { css::awt::MessageBoxType::MessageBoxType_MAKE_FIXED_SIZE, nullptr, 0 }
830 bool lcl_convertMessageBoxType(
831 OUString &sType,
832 css::awt::MessageBoxType eType )
834 const MessageBoxTypeInfo *pMap = aMessageBoxTypeInfo;
835 css::awt::MessageBoxType eVal = css::awt::MessageBoxType::MessageBoxType_MAKE_FIXED_SIZE;
837 while ( pMap->pName )
839 if ( pMap->eType == eType )
841 eVal = eType;
842 sType = OUString( pMap->pName, pMap->nLen, RTL_TEXTENCODING_ASCII_US );
843 break;
845 pMap++;
848 return ( eVal != css::awt::MessageBoxType::MessageBoxType_MAKE_FIXED_SIZE );
851 #ifndef IOS
853 sal_Int32 nVCLToolkitInstanceCount = 0;
854 bool bInitedByVCLToolkit = false;
856 osl::Mutex & getInitMutex()
858 static osl::Mutex aMutex;
859 return aMutex;
862 osl::Condition & getInitCondition()
864 static osl::Condition aCondition;
865 return aCondition;
868 extern "C"
870 static void ToolkitWorkerFunction( void* pArgs )
872 osl_setThreadName("VCLXToolkit VCL main thread");
874 css::uno::Reference<css::lang::XMultiServiceFactory> xServiceManager;
877 xServiceManager = ::comphelper::getProcessServiceFactory();
879 catch (const css::uno::DeploymentException&)
882 if (!xServiceManager.is())
884 css::uno::Reference<css::uno::XComponentContext> xContext =
885 ::cppu::defaultBootstrap_InitialComponentContext();
887 xServiceManager.set( xContext->getServiceManager(), css::uno::UNO_QUERY_THROW );
888 // set global process service factory used by unotools config helpers
889 ::comphelper::setProcessServiceFactory( xServiceManager );
892 VCLXToolkit * pTk = static_cast<VCLXToolkit *>(pArgs);
893 bInitedByVCLToolkit = !IsVCLInit() && InitVCL();
894 if( bInitedByVCLToolkit )
896 UnoWrapper* pUnoWrapper = new UnoWrapper( pTk );
897 UnoWrapperBase::SetUnoWrapper( pUnoWrapper );
899 getInitCondition().set();
900 if( bInitedByVCLToolkit )
903 SolarMutexGuard aGuard;
904 Application::Execute();
908 pTk->dispose();
910 catch( css::uno::Exception & )
913 DeInitVCL();
915 else
917 // having the thread join itself is pretty stupid.
918 // but we can't get the osl_Thread to destroy here so just leak it.
923 #endif
925 // constructor, which might initialize VCL
926 VCLXToolkit::VCLXToolkit():
927 cppu::WeakComponentImplHelper<
928 css::awt::XToolkitExperimental,
929 css::awt::XToolkitRobot,
930 css::lang::XServiceInfo>( GetMutex() ),
931 m_aTopWindowListeners(rBHelper.rMutex),
932 m_aKeyHandlers(rBHelper.rMutex),
933 m_aFocusListeners(rBHelper.rMutex),
934 m_aEventListenerLink(LINK(this, VCLXToolkit, eventListenerHandler)),
935 m_aKeyListenerLink(LINK(this, VCLXToolkit, keyListenerHandler)),
936 m_bEventListener(false),
937 m_bKeyListener(false)
939 #ifndef IOS
940 osl::Guard< osl::Mutex > aGuard( getInitMutex() );
941 nVCLToolkitInstanceCount++;
942 if( ( nVCLToolkitInstanceCount == 1 ) && ( !Application::IsInMain() ) )
944 // setup execute thread
945 CreateMainLoopThread( ToolkitWorkerFunction, this );
946 getInitCondition().wait();
948 #endif
951 void SAL_CALL VCLXToolkit::disposing()
953 #ifndef IOS
955 osl::Guard< osl::Mutex > aGuard( getInitMutex() );
956 if( --nVCLToolkitInstanceCount == 0 )
958 if( bInitedByVCLToolkit )
960 Application::Quit();
961 JoinMainLoopThread();
962 bInitedByVCLToolkit = false;
966 #endif
967 if (m_bEventListener)
969 ::Application::RemoveEventListener(m_aEventListenerLink);
970 m_bEventListener = false;
972 if (m_bKeyListener)
974 ::Application::RemoveKeyListener(m_aKeyListenerLink);
975 m_bKeyListener = false;
977 css::lang::EventObject aEvent(
978 getXWeak());
979 m_aTopWindowListeners.disposeAndClear(aEvent);
980 m_aKeyHandlers.disposeAndClear(aEvent);
981 m_aFocusListeners.disposeAndClear(aEvent);
985 css::uno::Reference< css::awt::XWindowPeer > VCLXToolkit::getDesktopWindow( )
987 css::uno::Reference< css::awt::XWindowPeer > xRef;
988 // 07/00: AppWindow doesn't exist anymore...
989 return xRef;
992 css::awt::Rectangle VCLXToolkit::getWorkArea( )
994 sal_Int32 nDisplay = Application::GetDisplayBuiltInScreen();
995 AbsoluteScreenPixelRectangle aWorkRect = Application::GetScreenPosSizePixel( nDisplay );
996 css::awt::Rectangle aNotherRect;
997 aNotherRect.X = aWorkRect.Left();
998 aNotherRect.Y = aWorkRect.Top();
999 aNotherRect.Width = aWorkRect.getOpenWidth();
1000 aNotherRect.Height = aWorkRect.getOpenHeight();
1001 return aNotherRect;
1004 css::uno::Reference< css::awt::XWindowPeer > VCLXToolkit::createWindow( const css::awt::WindowDescriptor& rDescriptor )
1006 return ImplCreateWindow( rDescriptor, MessBoxStyle::NONE );
1009 css::uno::Reference< css::awt::XDevice > VCLXToolkit::createScreenCompatibleDevice( sal_Int32 Width, sal_Int32 Height )
1011 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
1013 rtl::Reference<VCLXVirtualDevice> pVDev = new VCLXVirtualDevice;
1015 SolarMutexGuard aSolarGuard;
1017 VclPtrInstance<VirtualDevice> pV;
1018 pV->SetOutputSizePixel( Size( Width, Height ) );
1019 pVDev->SetVirtualDevice( pV );
1021 return pVDev;
1024 css::uno::Reference< css::awt::XRegion > VCLXToolkit::createRegion( )
1026 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
1028 css::uno::Reference< css::awt::XRegion > xRef = new VCLXRegion;
1029 return xRef;
1032 class InfoBox : public MessBox
1034 public:
1035 InfoBox(vcl::Window* pParent, const OUString& rMessage)
1036 : MessBox(pParent, MessBoxStyle::Ok | MessBoxStyle::DefaultOk, 0, OUString(), rMessage)
1038 // Default Text is the display title from the application
1039 if (GetText().isEmpty())
1040 SetText(GetStandardInfoBoxText());
1041 SetImage(GetStandardInfoBoxImage());
1045 class ErrorBox : public MessBox
1047 public:
1048 ErrorBox(vcl::Window* pParent, MessBoxStyle nStyle, WinBits nWinBits, const OUString& rMessage)
1049 : MessBox(pParent, nStyle, nWinBits, OUString(), rMessage)
1051 // Default Text is the display title from the application
1052 if (GetText().isEmpty())
1053 SetText(GetStandardErrorBoxText());
1054 SetImage(GetStandardErrorBoxImage());
1058 class QueryBox : public MessBox
1060 public:
1061 QueryBox(vcl::Window* pParent, MessBoxStyle nStyle, WinBits nWinBits, const OUString& rMessage)
1062 : MessBox(pParent, nStyle, nWinBits, OUString(), rMessage)
1064 // Default Text is the display title from the application
1065 if (GetText().isEmpty())
1066 SetText(GetStandardQueryBoxText());
1067 SetImage(GetStandardQueryBoxImage());
1071 class WarningBox : public MessBox
1073 public:
1074 WarningBox(vcl::Window* pParent, MessBoxStyle nStyle, WinBits nWinBits, const OUString& rMessage)
1075 : MessBox(pParent, nStyle, nWinBits, OUString(), rMessage)
1077 // Default Text is the display title from the application
1078 if (GetText().isEmpty())
1079 SetText(GetStandardWarningBoxText());
1080 SetImage(GetStandardWarningBoxImage());
1085 struct RMItemData
1087 bool b_Enabled;
1088 sal_Int32 n_ID;
1089 OUString Label;
1092 typedef ::cppu::ImplInheritanceHelper < VCLXGraphicControl
1093 , css::container::XContainerListener
1094 , css::beans::XPropertyChangeListener
1095 , css::awt::XItemEventBroadcaster
1096 > SVTXRoadmap_Base;
1097 class SVTXRoadmap final : public SVTXRoadmap_Base
1099 public:
1100 SVTXRoadmap();
1102 void SAL_CALL disposing( const css::lang::EventObject& Source ) override { VCLXWindow::disposing( Source ); }
1104 // css::awt::XVclWindowPeer
1105 void SAL_CALL setProperty( const OUString& PropertyName, const css::uno::Any& Value ) override;
1107 css::uno::Any SAL_CALL getProperty( const OUString& PropertyName ) override;
1109 // XContainerListener
1110 void SAL_CALL elementInserted( const css::container::ContainerEvent& rEvent ) override;
1111 void SAL_CALL elementRemoved( const css::container::ContainerEvent& rEvent ) override;
1112 void SAL_CALL elementReplaced( const css::container::ContainerEvent& rEvent ) override;
1114 // XItemEventBroadcaster
1115 virtual void SAL_CALL addItemListener( const css::uno::Reference< css::awt::XItemListener >& l ) override;
1116 virtual void SAL_CALL removeItemListener( const css::uno::Reference< css::awt::XItemListener >& l ) override;
1118 // XPropertyChangeListener
1119 virtual void SAL_CALL propertyChange( const css::beans::PropertyChangeEvent& evt ) override;
1121 private:
1123 // VCLXGraphicControl overridables
1124 virtual void ImplSetNewImage() override;
1126 static void ImplGetPropertyIds( std::vector< sal_uInt16 > &aIds );
1127 virtual void GetPropertyIds( std::vector< sal_uInt16 > &aIds ) override { return ImplGetPropertyIds( aIds ); }
1129 static RMItemData GetRMItemData( const css::container::ContainerEvent& _rEvent );
1131 virtual void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) override;
1133 virtual ~SVTXRoadmap() override;
1135 ItemListenerMultiplexer maItemListeners;
1141 SVTXRoadmap::SVTXRoadmap() : maItemListeners( *this )
1145 SVTXRoadmap::~SVTXRoadmap()
1149 void SVTXRoadmap::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
1151 switch ( rVclWindowEvent.GetId() )
1153 case VclEventId::RoadmapItemSelected:
1155 SolarMutexGuard aGuard;
1156 VclPtr<::vcl::ORoadmap> pField = GetAs< vcl::ORoadmap >();
1157 if ( pField )
1159 sal_Int16 CurItemID = pField->GetCurrentRoadmapItemID();
1160 css::awt::ItemEvent aEvent;
1161 aEvent.Selected = CurItemID;
1162 aEvent.Highlighted = CurItemID;
1163 aEvent.ItemId = CurItemID;
1164 maItemListeners.itemStateChanged( aEvent );
1167 break;
1168 default:
1169 SVTXRoadmap_Base::ProcessWindowEvent( rVclWindowEvent );
1170 break;
1174 void SVTXRoadmap::propertyChange( const css::beans::PropertyChangeEvent& evt )
1176 SolarMutexGuard aGuard;
1177 VclPtr<::vcl::ORoadmap> pField = GetAs< vcl::ORoadmap >();
1178 if ( !pField )
1179 return;
1181 css::uno::Reference< css::uno::XInterface > xRoadmapItem = evt.Source;
1182 sal_Int32 nID = 0;
1183 css::uno::Reference< css::beans::XPropertySet > xPropertySet( xRoadmapItem, css::uno::UNO_QUERY );
1184 css::uno::Any aValue = xPropertySet->getPropertyValue("ID");
1185 aValue >>= nID;
1187 OUString sPropertyName = evt.PropertyName;
1188 if ( sPropertyName == "Enabled" )
1190 bool bEnable = false;
1191 evt.NewValue >>= bEnable;
1192 pField->EnableRoadmapItem( static_cast<vcl::RoadmapTypes::ItemId>(nID) , bEnable );
1194 else if ( sPropertyName == "Label" )
1196 OUString sLabel;
1197 evt.NewValue >>= sLabel;
1198 pField->ChangeRoadmapItemLabel( static_cast<vcl::RoadmapTypes::ItemId>(nID) , sLabel );
1200 else if ( sPropertyName == "ID" )
1202 sal_Int32 nNewID = 0;
1203 evt.NewValue >>= nNewID;
1204 evt.OldValue >>= nID;
1205 pField->ChangeRoadmapItemID( static_cast<vcl::RoadmapTypes::ItemId>(nID), static_cast<vcl::RoadmapTypes::ItemId>(nNewID) );
1207 // else
1208 // TODO handle Interactive appropriately
1211 void SVTXRoadmap::addItemListener( const css::uno::Reference< css::awt::XItemListener >& l )
1213 maItemListeners.addInterface( l );
1216 void SVTXRoadmap::removeItemListener( const css::uno::Reference< css::awt::XItemListener >& l )
1218 maItemListeners.removeInterface( l );
1221 RMItemData SVTXRoadmap::GetRMItemData( const css::container::ContainerEvent& _rEvent )
1223 RMItemData aCurRMItemData;
1224 css::uno::Reference< css::uno::XInterface > xRoadmapItem;
1225 _rEvent.Element >>= xRoadmapItem;
1226 css::uno::Reference< css::beans::XPropertySet > xPropertySet( xRoadmapItem, css::uno::UNO_QUERY );
1227 if ( xPropertySet.is() )
1229 css::uno::Any aValue = xPropertySet->getPropertyValue("Label");
1230 aValue >>= aCurRMItemData.Label;
1231 aValue = xPropertySet->getPropertyValue("ID");
1232 aValue >>= aCurRMItemData.n_ID;
1233 aValue = xPropertySet->getPropertyValue("Enabled");
1234 aValue >>= aCurRMItemData.b_Enabled;
1236 else
1238 aCurRMItemData.b_Enabled = false;
1239 aCurRMItemData.n_ID = 0;
1241 return aCurRMItemData;
1244 void SVTXRoadmap::elementInserted( const css::container::ContainerEvent& _rEvent )
1246 SolarMutexGuard aGuard;
1247 VclPtr<::vcl::ORoadmap> pField = GetAs< vcl::ORoadmap >();
1248 if ( pField )
1250 RMItemData CurItemData = GetRMItemData( _rEvent );
1251 sal_Int32 InsertIndex = 0;
1252 _rEvent.Accessor >>= InsertIndex;
1253 pField->InsertRoadmapItem( InsertIndex, CurItemData.Label, static_cast<vcl::RoadmapTypes::ItemId>(CurItemData.n_ID), CurItemData.b_Enabled );
1257 void SVTXRoadmap::elementRemoved( const css::container::ContainerEvent& _rEvent )
1259 SolarMutexGuard aGuard;
1260 VclPtr<::vcl::ORoadmap> pField = GetAs< vcl::ORoadmap >();
1261 if ( pField )
1263 sal_Int32 DelIndex = 0;
1264 _rEvent.Accessor >>= DelIndex;
1265 pField->DeleteRoadmapItem(DelIndex);
1269 void SVTXRoadmap::elementReplaced( const css::container::ContainerEvent& _rEvent )
1271 SolarMutexGuard aGuard;
1272 VclPtr<::vcl::ORoadmap> pField = GetAs< vcl::ORoadmap >();
1273 if ( pField )
1275 RMItemData CurItemData = GetRMItemData( _rEvent );
1276 sal_Int32 ReplaceIndex = 0;
1277 _rEvent.Accessor >>= ReplaceIndex;
1278 pField->ReplaceRoadmapItem( ReplaceIndex, CurItemData.Label, static_cast<vcl::RoadmapTypes::ItemId>(CurItemData.n_ID), CurItemData.b_Enabled );
1282 void SVTXRoadmap::setProperty( const OUString& PropertyName, const css::uno::Any& Value)
1284 SolarMutexGuard aGuard;
1286 VclPtr<::vcl::ORoadmap> pField = GetAs< vcl::ORoadmap >();
1287 if ( pField )
1289 sal_uInt16 nPropType = GetPropertyId( PropertyName );
1290 switch (nPropType)
1292 case BASEPROPERTY_COMPLETE:
1294 bool b = false;
1295 Value >>= b;
1296 pField->SetRoadmapComplete( b);
1298 break;
1300 case BASEPROPERTY_ACTIVATED:
1302 bool b = false;
1303 Value >>= b;
1304 pField->SetRoadmapInteractive( b);
1306 break;
1308 case BASEPROPERTY_CURRENTITEMID:
1310 sal_Int32 nId = 0;
1311 Value >>= nId;
1312 pField->SelectRoadmapItemByID( static_cast<vcl::RoadmapTypes::ItemId>(nId) );
1314 break;
1316 case BASEPROPERTY_TEXT:
1318 OUString aStr;
1319 Value >>= aStr;
1320 pField->SetText( aStr );
1321 pField->Invalidate();
1323 break;
1325 default:
1326 SVTXRoadmap_Base::setProperty( PropertyName, Value );
1327 break;
1331 else
1332 SVTXRoadmap_Base::setProperty( PropertyName, Value );
1336 css::uno::Any SVTXRoadmap::getProperty( const OUString& PropertyName )
1338 SolarMutexGuard aGuard;
1340 css::uno::Any aReturn;
1342 VclPtr<::vcl::ORoadmap> pField = GetAs< vcl::ORoadmap >();
1343 if ( pField )
1345 sal_uInt16 nPropType = GetPropertyId( PropertyName );
1346 switch (nPropType)
1348 case BASEPROPERTY_COMPLETE:
1349 aReturn <<= pField->IsRoadmapComplete();
1350 break;
1351 case BASEPROPERTY_ACTIVATED:
1352 aReturn <<= pField->IsRoadmapInteractive();
1353 break;
1354 case BASEPROPERTY_CURRENTITEMID:
1355 aReturn <<= pField->GetCurrentRoadmapItemID();
1356 break;
1357 default:
1358 aReturn = SVTXRoadmap_Base::getProperty(PropertyName);
1359 break;
1362 return aReturn;
1365 void SVTXRoadmap::ImplSetNewImage()
1367 OSL_PRECOND( GetWindow(), "SVTXRoadmap::ImplSetNewImage: window is required to be not-NULL!" );
1368 VclPtr< ::vcl::ORoadmap > pButton = GetAs< ::vcl::ORoadmap >();
1369 pButton->SetRoadmapBitmap( GetImage().GetBitmapEx() );
1372 void SVTXRoadmap::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds )
1374 PushPropertyIds( rIds,
1375 BASEPROPERTY_COMPLETE,
1376 BASEPROPERTY_ACTIVATED,
1377 BASEPROPERTY_CURRENTITEMID,
1378 BASEPROPERTY_TEXT,
1380 VCLXWindow::ImplGetPropertyIds( rIds, true );
1381 VCLXGraphicControl::ImplGetPropertyIds( rIds );
1384 vcl::Window* VCLXToolkit::ImplCreateWindow( rtl::Reference<VCLXWindow>* ppNewComp,
1385 const css::awt::WindowDescriptor& rDescriptor,
1386 vcl::Window* pParent, WinBits nWinBits, MessBoxStyle nMessBoxStyle )
1388 OUString aServiceName = rDescriptor.WindowServiceName.toAsciiLowerCase();
1390 VclPtr<vcl::Window> pNewWindow;
1391 WindowType nType = ImplGetComponentType( aServiceName );
1392 bool bFrameControl = false;
1393 if ( aServiceName == "frame" )
1394 bFrameControl = true;
1395 if ( aServiceName == "tabcontrolnotabs" )
1397 nWinBits |= WB_NOBORDER;
1398 nType = ImplGetComponentType( "tabcontrol" );
1400 if ( !pParent )
1402 // If the component needs a parent, then return NULL,
1403 // some time later css::uno::Exception...
1404 bool bException = true;
1405 if ( ( nType == WindowType::DIALOG )
1406 || ( nType == WindowType::MODELESSDIALOG )
1407 || ( nType == WindowType::MESSBOX )
1408 || ( nType == WindowType::INFOBOX )
1409 || ( nType == WindowType::WARNINGBOX )
1410 || ( nType == WindowType::ERRORBOX )
1411 || ( nType == WindowType::QUERYBOX )
1413 bException = false;
1414 else if ( ( nType == WindowType::WINDOW ) ||
1415 ( nType == WindowType::WORKWINDOW ) ||
1416 ( nType == WindowType::TOOLKIT_FRAMEWINDOW ) )
1418 if ( rDescriptor.Type == css::awt::WindowClass_TOP )
1419 bException = false;
1422 if ( bException )
1424 *ppNewComp = nullptr;
1425 return nullptr;
1429 if ( nType != WindowType::NONE )
1431 SolarMutexGuard aVclGuard;
1432 switch ( nType )
1434 case WindowType::CANCELBUTTON:
1435 pNewWindow = VclPtr<CancelButton>::Create( pParent, nWinBits );
1436 *ppNewComp = new VCLXButton;
1437 break;
1438 case WindowType::CHECKBOX:
1439 pNewWindow = VclPtr<CheckBox>::Create( pParent, nWinBits );
1440 *ppNewComp = new VCLXCheckBox;
1441 break;
1442 case WindowType::COMBOBOX:
1443 pNewWindow = VclPtr<ComboBox>::Create( pParent, nWinBits|WB_AUTOHSCROLL );
1444 static_cast<ComboBox*>(pNewWindow.get())->EnableAutoSize( false );
1445 *ppNewComp = new VCLXComboBox;
1446 break;
1447 case WindowType::CURRENCYBOX:
1448 pNewWindow = VclPtr<CurrencyBox>::Create( pParent, nWinBits );
1449 break;
1450 case WindowType::CURRENCYFIELD:
1451 pNewWindow = VclPtr<CurrencyField>::Create( pParent, nWinBits );
1452 static_cast<CurrencyField*>(pNewWindow.get())->EnableEmptyFieldValue( true );
1453 *ppNewComp = new VCLXNumericField;
1454 static_cast<VCLXFormattedSpinField*>((*ppNewComp).get())->SetFormatter( static_cast<FormatterBase*>(static_cast<CurrencyField*>(pNewWindow.get())) );
1455 break;
1456 case WindowType::DATEBOX:
1457 pNewWindow = VclPtr<DateBox>::Create( pParent, nWinBits );
1458 break;
1459 case WindowType::DOCKINGAREA:
1460 pNewWindow = VclPtr<DockingAreaWindow>::Create( pParent );
1461 break;
1462 case WindowType::MULTILINEEDIT:
1463 pNewWindow = VclPtr<MultiLineEdit>::Create(pParent, nWinBits|WB_IGNORETAB);
1464 static_cast<MultiLineEdit*>(pNewWindow.get())->DisableSelectionOnFocus();
1465 *ppNewComp = new VCLXMultiLineEdit;
1466 break;
1467 case WindowType::EDIT:
1468 pNewWindow = VclPtr<Edit>::Create( pParent, nWinBits );
1469 *ppNewComp = new VCLXEdit;
1470 break;
1471 case WindowType::ERRORBOX:
1472 pNewWindow = VclPtr<ErrorBox>::Create( pParent, nMessBoxStyle, nWinBits, OUString() );
1473 *ppNewComp = new VCLXMessageBox;
1474 break;
1475 case WindowType::FIXEDBITMAP:
1476 pNewWindow = VclPtr<FixedBitmap>::Create( pParent, nWinBits );
1477 break;
1478 case WindowType::FIXEDIMAGE:
1479 pNewWindow = VclPtr<ImageControl>::Create( pParent, nWinBits );
1480 *ppNewComp = new VCLXImageControl;
1481 break;
1482 case WindowType::FIXEDLINE:
1483 pNewWindow = VclPtr<FixedLine>::Create( pParent, nWinBits );
1484 break;
1485 case WindowType::FIXEDTEXT:
1486 pNewWindow = VclPtr<FixedText>::Create( pParent, nWinBits );
1487 *ppNewComp = new VCLXFixedText;
1488 break;
1489 case WindowType::FLOATINGWINDOW:
1490 pNewWindow = VclPtr<FloatingWindow>::Create( pParent, nWinBits );
1491 break;
1492 case WindowType::GROUPBOX:
1493 pNewWindow = VclPtr<GroupBox>::Create( pParent, nWinBits );
1494 if ( bFrameControl )
1496 GroupBox* pGroupBox = static_cast< GroupBox* >( pNewWindow.get() );
1497 *ppNewComp = new VCLXFrame;
1498 // Frame control needs to receive
1499 // Mouse events
1500 pGroupBox->SetMouseTransparent( false );
1502 break;
1503 case WindowType::HELPBUTTON:
1504 pNewWindow = VclPtr<HelpButton>::Create( pParent, nWinBits );
1505 *ppNewComp = new VCLXButton;
1506 break;
1507 case WindowType::IMAGEBUTTON:
1508 pNewWindow = VclPtr<ImageButton>::Create( pParent, nWinBits );
1509 *ppNewComp = new VCLXButton;
1510 break;
1511 case WindowType::INFOBOX:
1512 pNewWindow = VclPtr<InfoBox>::Create( pParent, OUString() );
1513 *ppNewComp = new VCLXMessageBox;
1514 break;
1515 case WindowType::LISTBOX:
1516 pNewWindow = VclPtr<ListBox>::Create( pParent, nWinBits|WB_SIMPLEMODE|WB_AUTOHSCROLL );
1517 static_cast<ListBox*>(pNewWindow.get())->EnableAutoSize( false );
1518 *ppNewComp = new VCLXListBox;
1519 break;
1520 case WindowType::LONGCURRENCYBOX:
1521 pNewWindow = VclPtr<LongCurrencyBox>::Create( pParent, nWinBits );
1522 break;
1523 case WindowType::MENUBUTTON:
1524 pNewWindow = VclPtr<MenuButton>::Create( pParent, nWinBits );
1525 *ppNewComp = new VCLXButton;
1526 break;
1527 case WindowType::MESSBOX:
1528 pNewWindow = VclPtr<MessBox>::Create( pParent, nMessBoxStyle, nWinBits, OUString(), OUString() );
1529 *ppNewComp = new VCLXMessageBox;
1530 break;
1531 case WindowType::METRICBOX:
1532 pNewWindow = VclPtr<MetricBox>::Create( pParent, nWinBits );
1533 break;
1534 case WindowType::METRICFIELD:
1535 pNewWindow = VclPtr<MetricField>::Create( pParent, nWinBits );
1536 *ppNewComp = new VCLXMetricField;
1537 static_cast<VCLXFormattedSpinField*>((*ppNewComp).get())->SetFormatter( static_cast<FormatterBase*>(static_cast<MetricField*>(pNewWindow.get())) );
1538 break;
1539 case WindowType::DIALOG:
1540 case WindowType::MODELESSDIALOG:
1542 // Modal/Modeless only via Show/Execute
1543 if ( (pParent == nullptr ) && ( rDescriptor.ParentIndex == -1 ) )
1544 pNewWindow = VclPtr<toolkit::ScrollableDialog>::Create( nullptr, nWinBits, Dialog::InitFlag::NoParent );
1545 else
1546 pNewWindow = VclPtr<toolkit::ScrollableDialog>::Create( pParent, nWinBits );
1547 // #i70217# Don't always create a new component object. It's possible that VCL has called
1548 // GetComponentInterface( sal_True ) in the Dialog ctor itself (see Window::IsTopWindow() )
1549 // which creates a component object.
1550 css::uno::Reference< css::awt::XWindowPeer > xWinPeer = pNewWindow->GetComponentInterface( false );
1551 if ( xWinPeer.is() )
1552 *ppNewComp = dynamic_cast< VCLXDialog* >( xWinPeer.get() );
1553 else
1554 *ppNewComp = new VCLXDialog;
1556 break;
1557 case WindowType::MOREBUTTON:
1558 pNewWindow = VclPtr<MoreButton>::Create( pParent, nWinBits );
1559 *ppNewComp = new VCLXButton;
1560 break;
1561 case WindowType::MULTILISTBOX:
1562 pNewWindow = VclPtr<MultiListBox>::Create( pParent, nWinBits );
1563 *ppNewComp = new VCLXListBox;
1564 break;
1565 case WindowType::NUMERICBOX:
1566 pNewWindow = VclPtr<NumericBox>::Create( pParent, nWinBits );
1567 break;
1568 case WindowType::OKBUTTON:
1569 pNewWindow = VclPtr<OKButton>::Create( pParent, nWinBits );
1570 *ppNewComp = new VCLXButton;
1571 break;
1572 case WindowType::PATTERNBOX:
1573 pNewWindow = VclPtr<PatternBox>::Create( pParent, nWinBits );
1574 break;
1575 case WindowType::PATTERNFIELD:
1576 pNewWindow = VclPtr<PatternField>::Create( pParent, nWinBits );
1577 *ppNewComp = new VCLXPatternField;
1578 static_cast<VCLXFormattedSpinField*>((*ppNewComp).get())->SetFormatter( static_cast<FormatterBase*>(static_cast<PatternField*>(pNewWindow.get())) );
1579 break;
1580 case WindowType::PUSHBUTTON:
1581 pNewWindow = VclPtr<PushButton>::Create( pParent, nWinBits );
1582 *ppNewComp = new VCLXButton;
1583 break;
1584 case WindowType::QUERYBOX:
1585 pNewWindow = VclPtr<QueryBox>::Create( pParent, nMessBoxStyle, nWinBits, OUString() );
1586 *ppNewComp = new VCLXMessageBox;
1587 break;
1588 case WindowType::RADIOBUTTON:
1589 pNewWindow = VclPtr<RadioButton>::Create(pParent, false, nWinBits);
1590 *ppNewComp = new VCLXRadioButton;
1592 // by default, disable RadioCheck
1593 // Since the VCLXRadioButton really cares for its RadioCheck settings, this is important:
1594 // if we enable it, the VCLXRadioButton will use RadioButton::Check instead of RadioButton::SetState
1595 // This leads to a strange behaviour if the control is newly created: when settings the initial
1596 // state to "checked", the RadioButton::Check (called because RadioCheck=sal_True) will uncheck
1597 // _all_other_ radio buttons in the same group. However, at this moment the grouping of the controls
1598 // is not really valid: the controls are grouped after they have been created, but we're still in
1599 // the creation process, so the RadioButton::Check relies on invalid grouping information.
1600 // 07.08.2001 - #87254# - frank.schoenheit@sun.com
1601 static_cast<RadioButton*>(pNewWindow.get())->EnableRadioCheck( false );
1602 break;
1603 case WindowType::SCROLLBAR:
1604 pNewWindow = VclPtr<ScrollBar>::Create( pParent, nWinBits );
1605 *ppNewComp = new VCLXScrollBar;
1606 break;
1607 case WindowType::SCROLLBARBOX:
1608 pNewWindow = VclPtr<ScrollBarBox>::Create( pParent, nWinBits );
1609 break;
1610 case WindowType::SPINBUTTON:
1611 pNewWindow = VclPtr<SpinButton>::Create( pParent, nWinBits );
1612 *ppNewComp = new ::toolkit::VCLXSpinButton;
1613 break;
1614 case WindowType::SPINFIELD:
1615 pNewWindow = VclPtr<SpinField>::Create( pParent, nWinBits );
1616 *ppNewComp = new VCLXNumericField;
1617 break;
1618 case WindowType::SPLITTER:
1619 pNewWindow = VclPtr<Splitter>::Create( pParent, nWinBits );
1620 break;
1621 case WindowType::SPLITWINDOW:
1622 pNewWindow = VclPtr<SplitWindow>::Create( pParent, nWinBits );
1623 break;
1624 case WindowType::STATUSBAR:
1625 pNewWindow = VclPtr<StatusBar>::Create( pParent, nWinBits );
1626 break;
1627 case WindowType::TOOLKIT_SYSTEMCHILDWINDOW:
1628 pNewWindow = VclPtr<SystemChildWindow>::Create( pParent, nWinBits );
1629 *ppNewComp = new VCLXSystemDependentWindow();
1630 break;
1631 case WindowType::TABCONTROL:
1632 pNewWindow = VclPtr<TabControl>::Create( pParent, nWinBits );
1633 *ppNewComp = new VCLXMultiPage;
1634 break;
1635 case WindowType::TABDIALOG:
1636 pNewWindow = VclPtr<TabDialog>::Create( pParent, nWinBits );
1637 break;
1638 case WindowType::TABPAGE:
1640 pNewWindow = VclPtr<TabPage>::Create( pParent, nWinBits );
1641 *ppNewComp = new VCLXTabPage;
1643 break;
1644 case WindowType::TIMEBOX:
1645 pNewWindow = VclPtr<TimeBox>::Create( pParent, nWinBits );
1646 break;
1647 case WindowType::TIMEFIELD:
1648 pNewWindow = VclPtr<TimeField>::Create( pParent, nWinBits );
1649 static_cast<TimeField*>(pNewWindow.get())->EnableEmptyFieldValue( true );
1650 *ppNewComp = new VCLXTimeField;
1651 static_cast<VCLXFormattedSpinField*>((*ppNewComp).get())->SetFormatter( static_cast<FormatterBase*>(static_cast<TimeField*>(pNewWindow.get())) );
1652 break;
1653 case WindowType::TOOLBOX:
1654 pNewWindow = VclPtr<ToolBox>::Create( pParent, nWinBits );
1655 *ppNewComp = new VCLXToolBox;
1656 break;
1657 case WindowType::TRISTATEBOX:
1658 pNewWindow = VclPtr<CheckBox>::Create( pParent, nWinBits );
1659 static_cast<CheckBox*>(pNewWindow.get())->EnableTriState(true);
1660 break;
1661 case WindowType::WARNINGBOX:
1662 pNewWindow = VclPtr<WarningBox>::Create( pParent, nMessBoxStyle, nWinBits, OUString() );
1663 *ppNewComp = new VCLXMessageBox;
1664 break;
1665 case WindowType::WORKWINDOW:
1666 case WindowType::WINDOW:
1667 case WindowType::TOOLKIT_FRAMEWINDOW:
1668 case WindowType::DOCKINGWINDOW:
1669 if ( rDescriptor.Type == css::awt::WindowClass_TOP )
1671 if (nType == WindowType::DOCKINGWINDOW )
1672 pNewWindow = VclPtr<DockingWindow>::Create( pParent, nWinBits );
1673 else
1675 if ((pParent == nullptr) && rDescriptor.Parent.is())
1677 // try to get a system dependent window handle
1678 css::uno::Reference< css::awt::XSystemDependentWindowPeer > xSystemDepParent(rDescriptor.Parent, css::uno::UNO_QUERY);
1680 if (xSystemDepParent.is())
1682 sal_Int8 processID[16];
1684 rtl_getGlobalProcessId( reinterpret_cast<sal_uInt8*>(processID) );
1686 // coverity[overrun-buffer-arg : FALSE] - coverity has difficulty with css::uno::Sequence
1687 css::uno::Sequence<sal_Int8> processIdSeq(processID, 16);
1689 css::uno::Any anyHandle = xSystemDepParent->getWindowHandle(processIdSeq, SYSTEM_DEPENDENT_TYPE);
1691 // use sal_Int64 here to accommodate all int types
1692 // uno::Any shift operator will upcast if necessary
1693 sal_Int64 nWindowHandle = 0;
1694 bool bXEmbed = false;
1696 bool bUseParentData = true;
1697 if( ! (anyHandle >>= nWindowHandle) )
1699 css::uno::Sequence< css::beans::NamedValue > aProps;
1700 if( anyHandle >>= aProps )
1702 for( const css::beans::NamedValue& rProp : std::as_const(aProps) )
1704 if ( rProp.Name == "WINDOW" )
1705 rProp.Value >>= nWindowHandle;
1706 else if ( rProp.Name == "XEMBED" )
1707 rProp.Value >>= bXEmbed;
1710 else
1711 bUseParentData = false;
1714 if( bUseParentData )
1716 SystemParentData aParentData;
1717 aParentData.nSize = sizeof( aParentData );
1718 #if defined MACOSX
1719 aParentData.pView = reinterpret_cast<NSView*>(nWindowHandle);
1720 #elif defined ANDROID
1721 // Nothing
1722 #elif defined IOS
1723 // Nothing
1724 #elif defined UNX
1725 aParentData.aWindow = nWindowHandle;
1726 aParentData.bXEmbedSupport = bXEmbed;
1727 #elif defined _WIN32
1728 aParentData.hWnd = reinterpret_cast<HWND>(nWindowHandle);
1729 #endif
1730 pNewWindow = VclPtr<WorkWindow>::Create( &aParentData );
1735 if (!pNewWindow)
1736 pNewWindow = VclPtr<WorkWindow>::Create( pParent, nWinBits );
1739 *ppNewComp = new VCLXTopWindow();
1741 else if ( rDescriptor.Type == css::awt::WindowClass_CONTAINER )
1743 if (nType == WindowType::DOCKINGWINDOW )
1744 pNewWindow = VclPtr<DockingWindow>::Create( pParent, nWinBits );
1745 else
1746 pNewWindow = VclPtr<vcl::Window>::Create( pParent, nWinBits );
1747 *ppNewComp = new VCLXContainer;
1749 else
1751 if (nType == WindowType::DOCKINGWINDOW )
1752 pNewWindow = VclPtr<DockingWindow>::Create( pParent, nWinBits );
1753 else
1754 pNewWindow = VclPtr<vcl::Window>::Create( pParent, nWinBits );
1755 *ppNewComp = new VCLXWindow;
1757 break;
1758 case WindowType::CONTROL:
1759 if ( aServiceName == "tabpagecontainer" )
1761 // TabControl has a special case for tabs without border: they are displayed
1762 // in a different way, so we need to ensure that this style is not set, so
1763 // we can guarantee normal tab behavior
1764 pNewWindow = VclPtr<TabControl>::Create( pParent, nWinBits & (~WB_NOBORDER));
1765 *ppNewComp = new VCLXTabPageContainer;
1767 else if ( aServiceName == "animatedimages" )
1769 pNewWindow = VclPtr<Throbber>::Create( pParent, nWinBits );
1770 *ppNewComp = new ::toolkit::AnimatedImagesPeer;
1772 else if (aServiceName == "roadmap")
1774 pNewWindow = VclPtr<::vcl::ORoadmap>::Create( pParent, WB_TABSTOP );
1775 *ppNewComp = new SVTXRoadmap;
1777 else if (aServiceName == "fixedhyperlink")
1779 pNewWindow = VclPtr<FixedHyperlink>::Create( pParent, nWinBits );
1780 *ppNewComp = new VCLXFixedHyperlink;
1782 else if (aServiceName == "progressbar")
1784 pNewWindow = VclPtr<ProgressBar>::Create( pParent, nWinBits, ProgressBar::BarStyle::Progress );
1785 *ppNewComp = new VCLXProgressBar;
1787 else if (aServiceName == "filecontrol")
1789 pNewWindow = VclPtr<FileControl>::Create( pParent, nWinBits );
1790 *ppNewComp = new VCLXFileControl;
1792 else if (aServiceName == "tree")
1794 rtl::Reference<TreeControlPeer> pPeer = new TreeControlPeer;
1795 *ppNewComp = pPeer;
1796 pNewWindow = pPeer->createVclControl( pParent, nWinBits );
1798 else if (aServiceName == "formattedfield")
1800 pNewWindow = VclPtr<FormattedField>::Create( pParent, nWinBits );
1801 *ppNewComp = new SVTXFormattedField;
1803 else if (aServiceName == "numericfield")
1805 pNewWindow = VclPtr<DoubleNumericField>::Create( pParent, nWinBits );
1806 *ppNewComp = new SVTXNumericField;
1808 else if (aServiceName == "longcurrencyfield")
1810 pNewWindow = VclPtr<DoubleCurrencyField>::Create( pParent, nWinBits );
1811 *ppNewComp = new SVTXCurrencyField;
1813 else if (aServiceName == "datefield")
1815 pNewWindow = VclPtr<CalendarField>::Create(pParent, nWinBits);
1816 static_cast<CalendarField*>(pNewWindow.get())->EnableToday();
1817 static_cast<CalendarField*>(pNewWindow.get())->EnableNone();
1818 static_cast<CalendarField*>(pNewWindow.get())->EnableEmptyFieldValue( true );
1819 rtl::Reference<SVTXDateField> newComp = new SVTXDateField;
1820 *ppNewComp = newComp;
1821 newComp->SetFormatter( static_cast<FormatterBase*>(static_cast<DateField*>(pNewWindow.get())) );
1823 else if (aServiceName == "grid")
1825 pNewWindow = VclPtr<::svt::table::TableControl>::Create(pParent, nWinBits);
1826 *ppNewComp = new SVTXGridControl;
1828 break;
1829 default:
1830 OSL_ENSURE( false, "VCLXToolkit::ImplCreateWindow: unknown window type!" );
1831 break;
1835 // tdf#126717 default that formcontrols show accelerators
1836 if (Control* pControl = dynamic_cast<Control*>(pNewWindow.get()))
1837 pControl->SetShowAccelerator(true);
1838 return pNewWindow;
1841 css::uno::Reference< css::awt::XWindowPeer > VCLXToolkit::ImplCreateWindow(
1842 const css::awt::WindowDescriptor& rDescriptor,
1843 MessBoxStyle nForceMessBoxStyle )
1845 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
1847 SolarMutexGuard aSolarGuard;
1849 css::uno::Reference< css::awt::XVclWindowPeer > xRef;
1851 VclPtr<vcl::Window> pParent;
1852 if ( rDescriptor.Parent.is() )
1854 VCLXWindow* pParentComponent = dynamic_cast<VCLXWindow*>( rDescriptor.Parent.get() );
1856 // #103939# Don't throw assertion, may be it's a system dependent window, used in ImplCreateWindow.
1857 // DBG_ASSERT( pParentComponent, "ParentComponent not valid" );
1859 if ( pParentComponent )
1860 pParent = pParentComponent->GetWindow();
1862 std::pair<WinBits, MessBoxStyle> aPair = ImplGetWinBits( rDescriptor.WindowAttributes,
1863 ImplGetComponentType( rDescriptor.WindowServiceName ) );
1864 WinBits nWinBits = aPair.first;
1865 aPair.second |= nForceMessBoxStyle;
1867 rtl::Reference<VCLXWindow> pNewComp;
1869 vcl::Window* pNewWindow = ImplCreateWindow( &pNewComp, rDescriptor, pParent, nWinBits, aPair.second );
1871 DBG_ASSERT( pNewWindow, "createWindow: Unknown Component!" );
1872 SAL_INFO_IF( !pNewComp, "toolkit", "createWindow: No special Interface!" );
1874 if ( pNewWindow )
1876 pNewWindow->SetCreatedWithToolkit( true );
1877 //pNewWindow->SetPosPixel( Point() ); // do not force (0,0) position, keep default pos instead
1879 if ( rDescriptor.WindowAttributes & css::awt::WindowAttribute::MINSIZE )
1881 pNewWindow->SetSizePixel( Size() );
1883 else if ( rDescriptor.WindowAttributes & css::awt::WindowAttribute::FULLSIZE )
1885 if ( pParent )
1886 pNewWindow->SetSizePixel( pParent->GetOutputSizePixel() );
1888 else if ( !VCLUnoHelper::IsZero( rDescriptor.Bounds ) )
1890 tools::Rectangle aRect = VCLRectangle( rDescriptor.Bounds );
1891 pNewWindow->SetPosSizePixel( aRect.TopLeft(), aRect.GetSize() );
1894 if ( !pNewComp )
1896 // Default-Interface
1897 xRef = pNewWindow->GetComponentInterface();
1899 else
1901 xRef = pNewComp;
1902 pNewWindow->SetComponentInterface( xRef );
1904 DBG_ASSERT( pNewWindow->GetComponentInterface( false ) == xRef,
1905 "VCLXToolkit::createWindow: did #133706# resurge?" );
1907 if ( rDescriptor.WindowAttributes & css::awt::WindowAttribute::SHOW )
1908 pNewWindow->Show();
1911 return xRef;
1914 css::uno::Sequence< css::uno::Reference< css::awt::XWindowPeer > > VCLXToolkit::createWindows( const css::uno::Sequence< css::awt::WindowDescriptor >& rDescriptors )
1916 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
1918 sal_uInt32 nComponents = rDescriptors.getLength();
1919 css::uno::Sequence< css::uno::Reference< css::awt::XWindowPeer > > aSeq( nComponents );
1920 for ( sal_uInt32 n = 0; n < nComponents; n++ )
1922 css::awt::WindowDescriptor aDescr = rDescriptors.getConstArray()[n];
1924 if ( aDescr.ParentIndex == -1 )
1925 aDescr.Parent = nullptr;
1926 else if ( ( aDescr.ParentIndex >= 0 ) && ( o3tl::make_unsigned(aDescr.ParentIndex) < n ) )
1927 aDescr.Parent = aSeq.getConstArray()[aDescr.ParentIndex];
1928 aSeq.getArray()[n] = createWindow( aDescr );
1930 return aSeq;
1933 // css::awt::XSystemChildFactory
1934 css::uno::Reference< css::awt::XWindowPeer > VCLXToolkit::createSystemChild( const css::uno::Any& Parent, const css::uno::Sequence< sal_Int8 >& /*ProcessId*/, sal_Int16 nSystemType )
1936 VclPtr<vcl::Window> pChildWindow;
1937 if ( nSystemType == SYSTEM_DEPENDENT_TYPE )
1939 // use sal_Int64 here to accommodate all int types
1940 // uno::Any shift operator will upcast if necessary
1941 sal_Int64 nWindowHandle = 0;
1942 bool bXEmbed = false;
1944 bool bUseParentData = true;
1945 if( ! (Parent >>= nWindowHandle) )
1947 css::uno::Sequence< css::beans::NamedValue > aProps;
1948 if( Parent >>= aProps )
1950 for( const css::beans::NamedValue& rProp : std::as_const(aProps) )
1952 if ( rProp.Name == "WINDOW" )
1953 rProp.Value >>= nWindowHandle;
1954 else if ( rProp.Name == "XEMBED" )
1955 rProp.Value >>= bXEmbed;
1958 else
1959 bUseParentData = false;
1962 if( bUseParentData )
1964 SystemParentData aParentData;
1965 aParentData.nSize = sizeof( aParentData );
1966 #if defined MACOSX
1967 aParentData.pView = reinterpret_cast<NSView*>(nWindowHandle);
1968 #elif defined ANDROID
1969 // Nothing
1970 #elif defined IOS
1971 // Nothing
1972 #elif defined UNX
1973 aParentData.aWindow = nWindowHandle;
1974 aParentData.bXEmbedSupport = bXEmbed;
1975 #elif defined _WIN32
1976 aParentData.hWnd = reinterpret_cast<HWND>(nWindowHandle);
1977 #endif
1978 SolarMutexGuard aGuard;
1981 pChildWindow.reset( VclPtr<WorkWindow>::Create( &aParentData ) );
1983 catch ( const css::uno::RuntimeException & )
1985 // system child window could not be created
1986 DBG_UNHANDLED_EXCEPTION("toolkit");
1987 pChildWindow.clear();
1991 else if (nSystemType == css::lang::SystemDependent::SYSTEM_JAVA)
1993 SolarMutexGuard aGuard;
1994 pChildWindow.reset(VclPtr<WorkWindow>::Create(nullptr, Parent));
1997 css::uno::Reference< css::awt::XVclWindowPeer > xPeer;
1998 if ( pChildWindow )
2000 rtl::Reference<VCLXTopWindow> pPeer = new VCLXTopWindow;
2001 SolarMutexGuard aGuard;
2002 pPeer->SetWindow( pChildWindow );
2003 xPeer = pPeer;
2004 pChildWindow->SetWindowPeer(xPeer, pPeer.get());
2007 return xPeer;
2010 // css::awt::XMessageBoxFactory
2011 css::uno::Reference< css::awt::XMessageBox > SAL_CALL VCLXToolkit::createMessageBox(
2012 const css::uno::Reference< css::awt::XWindowPeer >& aParent,
2013 css::awt::MessageBoxType eType,
2014 ::sal_Int32 aButtons,
2015 const OUString& aTitle,
2016 const OUString& aMessage )
2018 css::awt::WindowDescriptor aDescriptor;
2020 sal_Int32 nWindowAttributes = css::awt::WindowAttribute::BORDER|css::awt::WindowAttribute::MOVEABLE|css::awt::WindowAttribute::CLOSEABLE;
2022 // Map button definitions to window attributes
2023 if (( aButtons & 0x0000ffffL ) == css::awt::MessageBoxButtons::BUTTONS_OK )
2024 nWindowAttributes |= css::awt::VclWindowPeerAttribute::OK;
2025 else if (( aButtons & 0x0000ffffL ) == css::awt::MessageBoxButtons::BUTTONS_OK_CANCEL )
2026 nWindowAttributes |= css::awt::VclWindowPeerAttribute::OK_CANCEL;
2027 else if (( aButtons & 0x0000ffffL ) == css::awt::MessageBoxButtons::BUTTONS_YES_NO )
2028 nWindowAttributes |= css::awt::VclWindowPeerAttribute::YES_NO;
2029 else if (( aButtons & 0x0000ffffL ) == css::awt::MessageBoxButtons::BUTTONS_YES_NO_CANCEL )
2030 nWindowAttributes |= css::awt::VclWindowPeerAttribute::YES_NO_CANCEL;
2031 else if (( aButtons & 0x0000ffffL ) == css::awt::MessageBoxButtons::BUTTONS_RETRY_CANCEL )
2032 nWindowAttributes |= css::awt::VclWindowPeerAttribute::RETRY_CANCEL;
2034 // Map default button definitions to window attributes
2035 if (sal_Int32( aButtons & 0xffff0000L ) == css::awt::MessageBoxButtons::DEFAULT_BUTTON_OK )
2036 nWindowAttributes |= css::awt::VclWindowPeerAttribute::DEF_OK;
2037 else if (sal_Int32( aButtons & 0xffff0000L ) == css::awt::MessageBoxButtons::DEFAULT_BUTTON_CANCEL )
2038 nWindowAttributes |= css::awt::VclWindowPeerAttribute::DEF_CANCEL;
2039 else if (sal_Int32( aButtons & 0xffff0000L ) == css::awt::MessageBoxButtons::DEFAULT_BUTTON_YES )
2040 nWindowAttributes |= css::awt::VclWindowPeerAttribute::DEF_YES;
2041 else if (sal_Int32( aButtons & 0xffff0000L ) == css::awt::MessageBoxButtons::DEFAULT_BUTTON_NO )
2042 nWindowAttributes |= css::awt::VclWindowPeerAttribute::DEF_NO;
2043 else if (sal_Int32( aButtons & 0xffff0000L ) == css::awt::MessageBoxButtons::DEFAULT_BUTTON_RETRY )
2044 nWindowAttributes |= css::awt::VclWindowPeerAttribute::DEF_RETRY;
2046 // No more bits for VclWindowPeerAttribute possible. Mapping must be
2047 // done explicitly using VCL methods
2048 MessBoxStyle nAddWinBits = MessBoxStyle::NONE;
2049 if (( aButtons & 0x0000ffffL ) == css::awt::MessageBoxButtons::BUTTONS_ABORT_IGNORE_RETRY )
2050 nAddWinBits |= MessBoxStyle::AbortRetryIgnore;
2051 if ( sal_Int32( aButtons & 0xffff0000L ) == css::awt::MessageBoxButtons::DEFAULT_BUTTON_IGNORE )
2052 nAddWinBits |= MessBoxStyle::DefaultIgnore;
2054 OUString aType;
2055 lcl_convertMessageBoxType( aType, eType );
2057 aDescriptor.Type = css::awt::WindowClass_MODALTOP;
2058 aDescriptor.WindowServiceName = aType;
2059 aDescriptor.ParentIndex = -1;
2060 aDescriptor.Parent = aParent;
2061 aDescriptor.WindowAttributes = nWindowAttributes;
2062 css::uno::Reference< css::awt::XMessageBox > xMsgBox(
2063 ImplCreateWindow( aDescriptor, nAddWinBits ), css::uno::UNO_QUERY );
2064 css::uno::Reference< css::awt::XWindow > xWindow( xMsgBox, css::uno::UNO_QUERY );
2065 if ( xMsgBox.is() && xWindow.is() )
2067 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
2068 if ( pWindow )
2070 SolarMutexGuard aGuard;
2071 xMsgBox->setCaptionText( aTitle );
2072 xMsgBox->setMessageText( aMessage );
2076 return xMsgBox;
2079 css::uno::Reference< css::datatransfer::dnd::XDragGestureRecognizer > SAL_CALL VCLXToolkit::getDragGestureRecognizer( const css::uno::Reference< css::awt::XWindow >& window )
2081 SolarMutexGuard g;
2083 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( window );
2085 if( pWindow )
2086 return pWindow->GetDragGestureRecognizer();
2088 return css::uno::Reference< css::datatransfer::dnd::XDragGestureRecognizer >();
2091 css::uno::Reference< css::datatransfer::dnd::XDragSource > SAL_CALL VCLXToolkit::getDragSource( const css::uno::Reference< css::awt::XWindow >& window )
2093 SolarMutexGuard g;
2095 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( window );
2097 if( pWindow )
2098 return pWindow->GetDragSource();
2100 return css::uno::Reference< css::datatransfer::dnd::XDragSource >();
2103 css::uno::Reference< css::datatransfer::dnd::XDropTarget > SAL_CALL VCLXToolkit::getDropTarget( const css::uno::Reference< css::awt::XWindow >& window )
2105 SolarMutexGuard g;
2107 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( window );
2109 if( pWindow )
2110 return pWindow->GetDropTarget();
2112 return css::uno::Reference< css::datatransfer::dnd::XDropTarget >();
2115 css::uno::Reference< css::datatransfer::clipboard::XClipboard > SAL_CALL VCLXToolkit::getClipboard( const OUString& clipboardName )
2117 if( clipboardName.isEmpty() )
2119 if( !mxClipboard.is() )
2121 // remember clipboard here
2122 mxClipboard = css::datatransfer::clipboard::SystemClipboard::create(
2123 comphelper::getProcessComponentContext());
2126 return mxClipboard;
2129 else if( clipboardName == "Selection" )
2131 return mxSelection;
2134 return css::uno::Reference< css::datatransfer::clipboard::XClipboard >();
2137 // XServiceInfo
2138 OUString VCLXToolkit::getImplementationName()
2140 return "stardiv.Toolkit.VCLXToolkit";
2143 sal_Bool VCLXToolkit::supportsService( const OUString& rServiceName )
2145 return cppu::supportsService(this, rServiceName);
2148 css::uno::Sequence< OUString > VCLXToolkit::getSupportedServiceNames()
2150 return css::uno::Sequence<OUString>{
2151 "com.sun.star.awt.Toolkit", "stardiv.vcl.VclToolkit"};
2154 // css::awt::XExtendedToolkit:
2156 // virtual
2157 ::sal_Int32 SAL_CALL VCLXToolkit::getTopWindowCount()
2159 return static_cast< ::sal_Int32 >(::Application::GetTopWindowCount());
2160 // XXX numeric overflow
2163 // virtual
2164 css::uno::Reference< css::awt::XTopWindow > SAL_CALL
2165 VCLXToolkit::getTopWindow(::sal_Int32 nIndex)
2167 vcl::Window * p = ::Application::GetTopWindow(static_cast< tools::Long >(nIndex));
2168 // XXX numeric overflow
2169 return css::uno::Reference< css::awt::XTopWindow >(
2170 p == nullptr ? nullptr : static_cast< css::awt::XWindow * >(p->GetWindowPeer()),
2171 css::uno::UNO_QUERY);
2174 // virtual
2175 css::uno::Reference< css::awt::XTopWindow > SAL_CALL
2176 VCLXToolkit::getActiveTopWindow()
2178 vcl::Window * p = ::Application::GetActiveTopWindow();
2179 return css::uno::Reference< css::awt::XTopWindow >(
2180 p == nullptr ? nullptr : static_cast< css::awt::XWindow * >(p->GetWindowPeer()),
2181 css::uno::UNO_QUERY);
2184 // virtual
2185 void SAL_CALL VCLXToolkit::addTopWindowListener(
2186 css::uno::Reference< css::awt::XTopWindowListener > const & rListener)
2188 OSL_ENSURE(rListener.is(), "Null rListener");
2189 ::osl::ClearableMutexGuard aGuard(rBHelper.rMutex);
2190 if (rBHelper.bDisposed || rBHelper.bInDispose)
2192 aGuard.clear();
2193 rListener->disposing(
2194 css::lang::EventObject(
2195 getXWeak()));
2197 else if (m_aTopWindowListeners.addInterface(rListener) == 1
2198 && !m_bEventListener)
2200 m_bEventListener = true;
2201 ::Application::AddEventListener(m_aEventListenerLink);
2205 // virtual
2206 void SAL_CALL VCLXToolkit::removeTopWindowListener(
2207 css::uno::Reference< css::awt::XTopWindowListener > const & rListener)
2209 ::osl::MutexGuard aGuard(rBHelper.rMutex);
2210 if (!(rBHelper.bDisposed || rBHelper.bInDispose)
2211 && m_aTopWindowListeners.removeInterface(rListener) == 0
2212 && m_aFocusListeners.getLength() == 0 && m_bEventListener)
2214 ::Application::RemoveEventListener(m_aEventListenerLink);
2215 m_bEventListener = false;
2219 // virtual
2220 void SAL_CALL VCLXToolkit::addKeyHandler(
2221 css::uno::Reference< css::awt::XKeyHandler > const & rHandler)
2223 OSL_ENSURE(rHandler.is(), "Null rHandler");
2224 ::osl::ClearableMutexGuard aGuard(rBHelper.rMutex);
2225 if (rBHelper.bDisposed || rBHelper.bInDispose)
2227 aGuard.clear();
2228 rHandler->disposing(
2229 css::lang::EventObject(
2230 getXWeak()));
2232 else if (m_aKeyHandlers.addInterface(rHandler) == 1 && !m_bKeyListener)
2234 m_bKeyListener = true;
2235 ::Application::AddKeyListener(m_aKeyListenerLink);
2239 // virtual
2240 void SAL_CALL VCLXToolkit::removeKeyHandler(
2241 css::uno::Reference< css::awt::XKeyHandler > const & rHandler)
2243 ::osl::MutexGuard aGuard(rBHelper.rMutex);
2244 if (!(rBHelper.bDisposed || rBHelper.bInDispose)
2245 && m_aKeyHandlers.removeInterface(rHandler) == 0 && m_bKeyListener)
2247 ::Application::RemoveKeyListener(m_aKeyListenerLink);
2248 m_bKeyListener = false;
2252 // virtual
2253 void SAL_CALL VCLXToolkit::addFocusListener(
2254 css::uno::Reference< css::awt::XFocusListener > const & rListener)
2256 OSL_ENSURE(rListener.is(), "Null rListener");
2257 ::osl::ClearableMutexGuard aGuard(rBHelper.rMutex);
2258 if (rBHelper.bDisposed || rBHelper.bInDispose)
2260 aGuard.clear();
2261 rListener->disposing(
2262 css::lang::EventObject(
2263 getXWeak()));
2265 else if (m_aFocusListeners.addInterface(rListener) == 1
2266 && !m_bEventListener)
2268 m_bEventListener = true;
2269 ::Application::AddEventListener(m_aEventListenerLink);
2273 // virtual
2274 void SAL_CALL VCLXToolkit::removeFocusListener(
2275 css::uno::Reference< css::awt::XFocusListener > const & rListener)
2277 ::osl::MutexGuard aGuard(rBHelper.rMutex);
2278 if (!(rBHelper.bDisposed || rBHelper.bInDispose)
2279 && m_aFocusListeners.removeInterface(rListener) == 0
2280 && m_aTopWindowListeners.getLength() == 0 && m_bEventListener)
2282 ::Application::RemoveEventListener(m_aEventListenerLink);
2283 m_bEventListener = false;
2287 // virtual
2288 void SAL_CALL VCLXToolkit::fireFocusGained(
2289 css::uno::Reference<
2290 css::uno::XInterface > const &)
2294 // virtual
2295 void SAL_CALL VCLXToolkit::fireFocusLost(
2296 css::uno::Reference<
2297 css::uno::XInterface > const &)
2302 IMPL_LINK(VCLXToolkit, eventListenerHandler, ::VclSimpleEvent&, rEvent, void)
2304 switch (rEvent.GetId())
2306 case VclEventId::WindowShow:
2307 callTopWindowListeners(
2308 &rEvent, &css::awt::XTopWindowListener::windowOpened);
2309 break;
2310 case VclEventId::WindowHide:
2311 callTopWindowListeners(
2312 &rEvent, &css::awt::XTopWindowListener::windowClosed);
2313 break;
2314 case VclEventId::WindowActivate:
2315 callTopWindowListeners(
2316 &rEvent, &css::awt::XTopWindowListener::windowActivated);
2317 break;
2318 case VclEventId::WindowDeactivate:
2319 callTopWindowListeners(
2320 &rEvent, &css::awt::XTopWindowListener::windowDeactivated);
2321 break;
2322 case VclEventId::WindowClose:
2323 callTopWindowListeners(
2324 &rEvent, &css::awt::XTopWindowListener::windowClosing);
2325 break;
2326 case VclEventId::WindowGetFocus:
2327 callFocusListeners(&rEvent, true);
2328 break;
2329 case VclEventId::WindowLoseFocus:
2330 callFocusListeners(&rEvent, false);
2331 break;
2332 case VclEventId::WindowMinimize:
2333 callTopWindowListeners(
2334 &rEvent, &css::awt::XTopWindowListener::windowMinimized);
2335 break;
2336 case VclEventId::WindowNormalize:
2337 callTopWindowListeners(
2338 &rEvent, &css::awt::XTopWindowListener::windowNormalized);
2339 break;
2340 default: break;
2344 IMPL_LINK(VCLXToolkit, keyListenerHandler, ::VclWindowEvent&, rEvent, bool)
2346 switch (rEvent.GetId())
2348 case VclEventId::WindowKeyInput:
2349 return callKeyHandlers(&rEvent, true);
2350 case VclEventId::WindowKeyUp:
2351 return callKeyHandlers(&rEvent, false);
2352 default: break;
2354 return false;
2357 void VCLXToolkit::callTopWindowListeners(
2358 ::VclSimpleEvent const * pEvent,
2359 void (SAL_CALL css::awt::XTopWindowListener::* pFn)(
2360 css::lang::EventObject const &))
2362 vcl::Window * pWindow
2363 = static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow();
2364 if (!pWindow->IsTopWindow())
2365 return;
2367 std::vector< css::uno::Reference< css::awt::XTopWindowListener > >
2368 aListeners(m_aTopWindowListeners.getElements());
2369 if (aListeners.empty())
2370 return;
2372 css::lang::EventObject aAwtEvent(
2373 static_cast< css::awt::XWindow * >(pWindow->GetWindowPeer()));
2374 for (const css::uno::Reference<css::awt::XTopWindowListener> & xListener : aListeners)
2378 (xListener.get()->*pFn)(aAwtEvent);
2380 catch (const css::uno::RuntimeException &)
2382 DBG_UNHANDLED_EXCEPTION("toolkit");
2387 bool VCLXToolkit::callKeyHandlers(::VclSimpleEvent const * pEvent,
2388 bool bPressed)
2390 std::vector< css::uno::Reference< css::awt::XKeyHandler > >
2391 aHandlers(m_aKeyHandlers.getElements());
2393 if (!aHandlers.empty())
2395 vcl::Window * pWindow = static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow();
2397 // See implementation in vclxwindow.cxx for mapping between VCL and UNO AWT event
2398 ::KeyEvent * pKeyEvent = static_cast< ::KeyEvent * >(
2399 static_cast< ::VclWindowEvent const * >(pEvent)->GetData());
2400 css::awt::KeyEvent aAwtEvent(
2401 static_cast< css::awt::XWindow * >(pWindow->GetWindowPeer()),
2402 (pKeyEvent->GetKeyCode().IsShift()
2403 ? css::awt::KeyModifier::SHIFT : 0)
2404 | (pKeyEvent->GetKeyCode().IsMod1()
2405 ? css::awt::KeyModifier::MOD1 : 0)
2406 | (pKeyEvent->GetKeyCode().IsMod2()
2407 ? css::awt::KeyModifier::MOD2 : 0)
2408 | (pKeyEvent->GetKeyCode().IsMod3()
2409 ? css::awt::KeyModifier::MOD3 : 0),
2410 pKeyEvent->GetKeyCode().GetCode(), pKeyEvent->GetCharCode(),
2411 sal::static_int_cast< sal_Int16 >(
2412 pKeyEvent->GetKeyCode().GetFunction()));
2413 for (const css::uno::Reference<css::awt::XKeyHandler> & xHandler : aHandlers)
2417 if (bPressed ? xHandler->keyPressed(aAwtEvent)
2418 : xHandler->keyReleased(aAwtEvent))
2419 return true;
2421 catch (const css::uno::RuntimeException &)
2423 DBG_UNHANDLED_EXCEPTION("toolkit");
2427 return false;
2430 void VCLXToolkit::callFocusListeners(::VclSimpleEvent const * pEvent,
2431 bool bGained)
2433 vcl::Window * pWindow
2434 = static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow();
2435 if (!pWindow->IsTopWindow())
2436 return;
2438 std::vector< css::uno::Reference< css::awt::XFocusListener > >
2439 aListeners(m_aFocusListeners.getElements());
2440 if (aListeners.empty())
2441 return;
2443 // Ignore the interior of compound controls when determining the
2444 // window that gets the focus next (see implementation in
2445 // vclxwindow.cxx for mapping between VCL and UNO AWT event):
2446 css::uno::Reference< css::uno::XInterface > xNext;
2447 vcl::Window * pFocus = ::Application::GetFocusWindow();
2448 for (vcl::Window * p = pFocus; p != nullptr; p = p->GetParent())
2449 if (!p->IsCompoundControl())
2451 pFocus = p;
2452 break;
2454 if (pFocus != nullptr)
2455 xNext = pFocus->GetComponentInterface();
2456 css::awt::FocusEvent aAwtEvent(
2457 static_cast< css::awt::XWindow * >(pWindow->GetWindowPeer()),
2458 static_cast<sal_Int16>(pWindow->GetGetFocusFlags()),
2459 xNext, false);
2460 for (const css::uno::Reference<css::awt::XFocusListener> & xListener : aListeners)
2464 bGained ? xListener->focusGained(aAwtEvent)
2465 : xListener->focusLost(aAwtEvent);
2467 catch (const css::uno::RuntimeException &)
2469 DBG_UNHANDLED_EXCEPTION("toolkit");
2474 // css::awt::XReschedule:
2476 void SAL_CALL VCLXToolkit::reschedule()
2478 SolarMutexGuard aSolarGuard;
2479 Application::Reschedule(true);
2482 // css::awt::XFontMappingUse:
2483 void SAL_CALL VCLXToolkit::startTrackingFontMappingUse()
2485 SolarMutexGuard aSolarGuard;
2486 OutputDevice::StartTrackingFontMappingUse();
2489 css::uno::Sequence<css::awt::XFontMappingUseItem>
2490 SAL_CALL VCLXToolkit::finishTrackingFontMappingUse()
2492 SolarMutexGuard aSolarGuard;
2493 OutputDevice::FontMappingUseData data = OutputDevice::FinishTrackingFontMappingUse();
2494 css::uno::Sequence<css::awt::XFontMappingUseItem> ret( data.size());
2495 css::awt::XFontMappingUseItem* retData = ret.getArray();
2496 for( size_t i = 0; i < data.size(); ++i )
2498 retData[ i ].originalFont = data[ i ].mOriginalFont;
2499 retData[ i ].usedFonts = comphelper::arrayToSequence<OUString,OUString>
2500 (data[ i ].mUsedFonts.data(), data[ i ].mUsedFonts.size());
2501 retData[ i ].count = data[ i ].mCount;
2503 return ret;
2506 // css::awt::XToolkitExperimental
2508 void SAL_CALL VCLXToolkit::processEventsToIdle()
2510 SolarMutexGuard aSolarGuard;
2511 comphelper::ProfileZone aZone("processEvents");
2512 Scheduler::ProcessEventsToIdle();
2515 sal_Int64 SAL_CALL VCLXToolkit::getOpenGLBufferSwapCounter()
2517 #if HAVE_FEATURE_OPENGL
2518 return OpenGLWrapper::getBufferSwapCounter();
2519 #else
2520 return 0;
2521 #endif
2524 void SAL_CALL VCLXToolkit::setDeterministicScheduling(sal_Bool bDeterministicMode)
2526 SolarMutexGuard aSolarGuard;
2527 Scheduler::SetDeterministicMode(bDeterministicMode);
2530 void SAL_CALL VCLXToolkit::pause(sal_Int32 nMilliseconds)
2532 new Pause(nMilliseconds);
2535 void SAL_CALL VCLXToolkit::startRecording()
2537 comphelper::TraceEvent::startRecording();
2540 void SAL_CALL VCLXToolkit::stopRecording()
2542 comphelper::TraceEvent::stopRecording();
2545 css::uno::Sequence< OUString > VCLXToolkit::getRecordingAndClear()
2547 return comphelper::ProfileZone::getRecordingAndClear();
2550 void VCLXToolkit::waitUntilAllIdlesDispatched()
2552 IdleTask::waitUntilIdleDispatched();
2555 // css:awt:XToolkitRobot
2557 void SAL_CALL VCLXToolkit::keyPress( const css::awt::KeyEvent & aKeyEvent )
2559 css::uno::Reference<css::awt::XWindow> xWindow ( aKeyEvent.Source, css::uno::UNO_QUERY_THROW );
2560 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
2561 if( !pWindow )
2562 throw css::uno::RuntimeException( "invalid event source" );
2564 ::KeyEvent aVCLKeyEvent = VCLUnoHelper::createVCLKeyEvent( aKeyEvent );
2565 ::Application::PostKeyEvent( VclEventId::WindowKeyInput, pWindow, &aVCLKeyEvent );
2568 void SAL_CALL VCLXToolkit::keyRelease( const css::awt::KeyEvent & aKeyEvent )
2570 css::uno::Reference<css::awt::XWindow> xWindow ( aKeyEvent.Source, css::uno::UNO_QUERY_THROW );
2571 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
2572 if( !pWindow )
2573 throw css::uno::RuntimeException( "invalid event source" );
2575 ::KeyEvent aVCLKeyEvent = VCLUnoHelper::createVCLKeyEvent( aKeyEvent );
2576 ::Application::PostKeyEvent( VclEventId::WindowKeyUp, pWindow, &aVCLKeyEvent );
2580 void SAL_CALL VCLXToolkit::mousePress( const css::awt::MouseEvent & aMouseEvent )
2582 css::uno::Reference<css::awt::XWindow> xWindow ( aMouseEvent.Source, css::uno::UNO_QUERY_THROW );
2583 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
2584 if( !pWindow )
2585 throw css::uno::RuntimeException( "invalid event source" );
2587 ::MouseEvent aVCLMouseEvent = VCLUnoHelper::createVCLMouseEvent( aMouseEvent );
2588 ::Application::PostMouseEvent( VclEventId::WindowMouseButtonDown, pWindow, &aVCLMouseEvent );
2591 void SAL_CALL VCLXToolkit::mouseRelease( const css::awt::MouseEvent & aMouseEvent )
2593 css::uno::Reference<css::awt::XWindow> xWindow ( aMouseEvent.Source, css::uno::UNO_QUERY_THROW );
2594 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
2595 if( !pWindow )
2596 throw css::uno::RuntimeException( "invalid event source" );
2598 ::MouseEvent aVCLMouseEvent = VCLUnoHelper::createVCLMouseEvent( aMouseEvent );
2599 ::Application::PostMouseEvent( VclEventId::WindowMouseButtonUp, pWindow, &aVCLMouseEvent );
2602 void SAL_CALL VCLXToolkit::mouseMove( const css::awt::MouseEvent & aMouseEvent )
2604 css::uno::Reference<css::awt::XWindow> xWindow ( aMouseEvent.Source, css::uno::UNO_QUERY_THROW );
2605 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
2606 if( !pWindow )
2607 throw css::uno::RuntimeException( "invalid event source" );
2609 ::MouseEvent aVCLMouseEvent = VCLUnoHelper::createVCLMouseEvent( aMouseEvent );
2610 ::Application::PostMouseEvent( VclEventId::WindowMouseMove, pWindow, &aVCLMouseEvent );
2616 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
2617 stardiv_Toolkit_VCLXToolkit_get_implementation(
2618 css::uno::XComponentContext *,
2619 css::uno::Sequence<css::uno::Any> const &)
2621 return cppu::acquire(new VCLXToolkit());
2624 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */