/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::UNO_QUERY; using ::com::sun::star::lang::EventObject; using ::com::sun::star::awt::XWindowListener2; using ::com::sun::star::awt::XDockableWindowListener; using ::com::sun::star::awt::XDevice; using ::com::sun::star::awt::XStyleSettings; using ::com::sun::star::lang::DisposedException; using ::com::sun::star::style::VerticalAlignment; using ::com::sun::star::style::VerticalAlignment_TOP; using ::com::sun::star::style::VerticalAlignment_MIDDLE; using ::com::sun::star::style::VerticalAlignment_BOTTOM;
class VCLXWindowImpl
{ private: typedef ::std::vector< VCLXWindow::Callback > CallbackArray;
private:
VCLXWindow& mrAntiImpl; bool mbDisposed; bool mbDrawingOntoParent; // no bit mask, is passed around by reference bool mbEnableVisible; bool mbDirectVisible;
public: /** ctor @param _pAntiImpl the <type>VCLXWindow</type> instance which the object belongs to. Must live longer then the object just being constructed.
*/
VCLXWindowImpl( VCLXWindow& _rAntiImpl, bool _bWithDefaultProps );
if ( mnCallbackEventId )
{
Application::RemoveUserEvent( mnCallbackEventId );
mnCallbackEventId = nullptr; // we acquired our VCLXWindow once before posting the event, release this one ref now
mrAntiImpl.release();
}
maCallbackEvents.clear();
// For TopWindows this means opened... if ( mpImpl->getTopWindowListeners().getLength() )
{
css::lang::EventObject aEvent;
aEvent.Source = getXWeak();
mpImpl->getTopWindowListeners().windowOpened( aEvent );
}
} break; case VclEventId::WindowHide:
{ if ( mpImpl->getWindowListeners().getLength() )
{
css::awt::WindowEvent aEvent;
aEvent.Source = getXWeak();
ImplInitWindowEvent( aEvent, rVclWindowEvent.GetWindow() );
mpImpl->getWindowListeners().windowHidden( aEvent );
}
// For TopWindows this means closed... if ( mpImpl->getTopWindowListeners().getLength() )
{
css::lang::EventObject aEvent;
aEvent.Source = getXWeak();
mpImpl->getTopWindowListeners().windowClosed( aEvent );
}
} break; case VclEventId::WindowActivate: case VclEventId::WindowDeactivate:
{ if (!mpImpl->getTopWindowListeners().getLength()) return;
// Suppress events which are unlikely to be interesting to our listeners.
vcl::Window* pWin = static_cast<vcl::Window*>(rVclWindowEvent.GetData()); bool bSuppress = false;
while (pWin)
{ // Either the event came from the same window, from its // child, or from a child of its border window (e.g. // menubar or notebookbar). if (pWin->GetWindow(GetWindowType::Client) == GetWindow()) return;
if (pWin->IsMenuFloatingWindow())
bSuppress = true;
if (pWin->GetType() == WindowType::FLOATINGWINDOW && static_cast<FloatingWindow*>(pWin)->IsInPopupMode())
bSuppress = true;
// Otherwise, don't suppress if the event came from a different frame. if (!bSuppress && pWin->GetWindow(GetWindowType::Frame) == pWin) break;
vcl::Window* pNext = Application::GetFocusWindow(); if ( pNext )
{ // Don't care about internals if this control is compound
vcl::Window* pNextC = pNext; while ( pNextC && !pNextC->IsCompoundControl() )
pNextC = pNextC->GetParent(); if ( pNextC )
pNext = pNextC;
pNext->GetComponentInterface();
aEvent.NextFocus = cppu::getXWeak(pNext->GetWindowPeer());
}
mpImpl->getFocusListeners().focusLost( aEvent );
}
}
} break; case VclEventId::WindowMinimize:
{ if ( mpImpl->getTopWindowListeners().getLength() )
{
css::lang::EventObject aEvent;
aEvent.Source = getXWeak();
mpImpl->getTopWindowListeners().windowMinimized( aEvent );
}
} break; case VclEventId::WindowNormalize:
{ if ( mpImpl->getTopWindowListeners().getLength() )
{
css::lang::EventObject aEvent;
aEvent.Source = getXWeak();
mpImpl->getTopWindowListeners().windowNormalized( aEvent );
}
} break; case VclEventId::WindowKeyInput:
{ if ( mpImpl->getKeyListeners().getLength() )
{
css::awt::KeyEvent aEvent( VCLUnoHelper::createKeyEvent(
*static_cast<KeyEvent*>(rVclWindowEvent.GetData()), *this
) );
mpImpl->getKeyListeners().keyPressed( aEvent );
}
} break; case VclEventId::WindowKeyUp:
{ if ( mpImpl->getKeyListeners().getLength() )
{
css::awt::KeyEvent aEvent( VCLUnoHelper::createKeyEvent(
*static_cast<KeyEvent*>(rVclWindowEvent.GetData()), *this
) );
mpImpl->getKeyListeners().keyReleased( aEvent );
}
} break; case VclEventId::WindowCommand:
{
CommandEvent* pCmdEvt = static_cast<CommandEvent*>(rVclWindowEvent.GetData()); if ( mpImpl->getMouseListeners().getLength() && ( pCmdEvt->GetCommand() == CommandEventId::ContextMenu ) )
{ // CommandEventId::ContextMenu: send as mousePressed with PopupTrigger = true ...
Point aWhere = static_cast< CommandEvent* >( rVclWindowEvent.GetData() )->GetMousePosPixel(); if ( !pCmdEvt->IsMouseEvent() )
{ // for keyboard events, we set the coordinates to -1,-1. This is a slight HACK, but the current API // handles a context menu command as special case of a mouse event, which is simply wrong. // Without extending the API, we would not have another chance to notify listeners of a // keyboard-triggered context menu request
aWhere = Point( -1, -1 );
}
// #i14103# dispose the accessible context after the window has been destroyed, // otherwise the old value in the child event fired in VCLXAccessibleComponent::ProcessWindowEvent() // for VclEventId::WindowChildDestroyed contains a reference to an already disposed accessible object try
{
css::uno::Reference< css::lang::XComponent > xComponent( mpImpl->mxAccessibleContext, css::uno::UNO_QUERY ); if ( xComponent.is() )
xComponent->dispose();
} catch ( const css::uno::Exception& )
{
OSL_FAIL( "VCLXWindow::dispose: could not dispose the accessible context!" );
}
mpImpl->mxAccessibleContext.clear();
}
void VCLXWindow::addEventListener( const css::uno::Reference< css::lang::XEventListener >& rxListener )
{
SolarMutexGuard aGuard; if (mpImpl->mbDisposing) // called during dispose by accessibility stuff return;
mpImpl->getEventListeners().addInterface( rxListener );
}
for ( int nId = nFirstId; nId != BASEPROPERTY_NOTFOUND;
nId = va_arg( pVarArgs, int ) )
rIds.push_back( static_cast<sal_uInt16>(nId) );
va_end( pVarArgs );
}
void VCLXWindow::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds, bool bWithDefaults )
{ // These are common across ~all VCLXWindow derived classes if( bWithDefaults )
PushPropertyIds( rIds,
BASEPROPERTY_ALIGN,
BASEPROPERTY_BACKGROUNDCOLOR,
BASEPROPERTY_BORDER,
BASEPROPERTY_BORDERCOLOR,
BASEPROPERTY_DEFAULTCONTROL,
BASEPROPERTY_ENABLED,
BASEPROPERTY_FONTDESCRIPTOR,
BASEPROPERTY_HELPTEXT,
BASEPROPERTY_HELPURL,
BASEPROPERTY_TEXT,
BASEPROPERTY_PRINTABLE,
BASEPROPERTY_ENABLEVISIBLE, // for visibility
BASEPROPERTY_TABSTOP,
0);
// lovely hack from: // void UnoControlModel::ImplRegisterProperty( sal_uInt16 nPropId ) if( std::find(rIds.begin(), rIds.end(), BASEPROPERTY_FONTDESCRIPTOR) != rIds.end() )
{ // some properties are not included in the FontDescriptor, but every time // when we have a FontDescriptor we want to have these properties too. // => Easier to register the here, instead everywhere where I register the FontDescriptor...
case BASEPROPERTY_NATIVE_WIDGET_LOOK:
{ bool bEnable( true );
OSL_VERIFY( Value >>= bEnable );
pWindow->EnableNativeWidget( bEnable );
} break;
case BASEPROPERTY_PLUGINPARENT:
{ // set parent handle
SetSystemParent_Impl( Value );
} break;
case BASEPROPERTY_ENABLED:
{ bool b = bool(); if ( Value >>= b )
setEnable( b );
} break; case BASEPROPERTY_ENABLEVISIBLE:
{ bool b = false; if ( Value >>= b )
{ if( b != mpImpl->isEnableVisible() )
{
mpImpl->setEnableVisible( b );
pWindow->Show( b && mpImpl->isDirectVisible() );
}
}
} break; case BASEPROPERTY_TEXT: case BASEPROPERTY_LABEL: case BASEPROPERTY_TITLE:
{
OUString aText; if ( Value >>= aText )
{ switch (eWinType)
{ case WindowType::OKBUTTON: case WindowType::CANCELBUTTON: case WindowType::HELPBUTTON: // Standard Button: overwrite only if not empty. if (!aText.isEmpty())
pWindow->SetText( aText ); break;
default:
pWindow->SetText( aText ); break;
}
}
} break; case BASEPROPERTY_ACCESSIBLENAME:
{
OUString aText; if ( Value >>= aText )
pWindow->SetAccessibleName( aText );
} break; case BASEPROPERTY_HELPURL:
{
OUString aURL; if ( Value >>= aURL )
{
INetURLObject aHelpURL( aURL ); if ( aHelpURL.GetProtocol() == INetProtocol::Hid )
pWindow->SetHelpId( aHelpURL.GetURLPath() ); else
pWindow->SetHelpId( aURL );
}
} break; case BASEPROPERTY_HELPTEXT:
{
OUString aHelpText; if ( Value >>= aHelpText )
{
pWindow->SetQuickHelpText( aHelpText );
}
} break; case BASEPROPERTY_FONTDESCRIPTOR:
{ if ( bVoid )
pWindow->SetControlFont( vcl::Font() ); else
{
css::awt::FontDescriptor aFont; if ( Value >>= aFont )
pWindow->SetControlFont( VCLUnoHelper::CreateFont( aFont, pWindow->GetControlFont() ) );
}
} break; case BASEPROPERTY_FONTRELIEF:
{
sal_Int16 n = sal_Int16(); if ( Value >>= n )
{
vcl::Font aFont = pWindow->GetControlFont();
aFont.SetRelief( static_cast<FontRelief>(n) );
pWindow->SetControlFont( aFont );
}
} break; case BASEPROPERTY_FONTEMPHASISMARK:
{
sal_Int16 n = sal_Int16(); if ( Value >>= n )
{
vcl::Font aFont = pWindow->GetControlFont();
aFont.SetEmphasisMark( static_cast<FontEmphasisMark>(n) );
pWindow->SetControlFont( aFont );
}
} break; case BASEPROPERTY_BACKGROUNDCOLOR: if ( bVoid )
{ switch ( eWinType )
{ // set dialog color for default case WindowType::DIALOG: case WindowType::MESSBOX: case WindowType::INFOBOX: case WindowType::WARNINGBOX: case WindowType::ERRORBOX: case WindowType::QUERYBOX: case WindowType::TABPAGE:
{
Color aColor = pWindow->GetSettings().GetStyleSettings().GetDialogColor();
pWindow->SetBackground( aColor );
pWindow->SetControlBackground( aColor ); break;
}
case WindowType::FIXEDTEXT: case WindowType::CHECKBOX: case WindowType::RADIOBUTTON: case WindowType::GROUPBOX: case WindowType::FIXEDLINE:
{ // support transparency only for special controls
pWindow->SetBackground();
pWindow->SetControlBackground();
pWindow->SetPaintTransparent( true ); break;
}
default:
{ // default code which enables transparency for // compound controls. It's not real transparency // as most of these controls repaint their client // area completely new. if ( pWindow->IsCompoundControl() )
pWindow->SetBackground();
pWindow->SetControlBackground(); break;
}
}
} else
{
Color aColor; if ( Value >>= aColor )
{
pWindow->SetControlBackground( aColor );
pWindow->SetBackground( aColor ); switch ( eWinType )
{ // reset paint transparent mode case WindowType::FIXEDTEXT: case WindowType::CHECKBOX: case WindowType::RADIOBUTTON: case WindowType::GROUPBOX: case WindowType::FIXEDLINE:
pWindow->SetPaintTransparent( false ); break; default: break;
}
pWindow->Invalidate(); // Invalidate if control does not respond to it
}
} break; case BASEPROPERTY_TEXTCOLOR: if ( bVoid )
{
pWindow->SetControlForeground();
} else
{
Color nColor ; if ( Value >>= nColor )
{
pWindow->SetTextColor( nColor );
pWindow->SetControlForeground( nColor );
}
} break; case BASEPROPERTY_TEXTLINECOLOR: if ( bVoid )
{
pWindow->SetTextLineColor();
} else
{
Color nColor; if ( Value >>= nColor )
pWindow->SetTextLineColor( nColor );
} break; case BASEPROPERTY_FILLCOLOR: if ( bVoid )
pWindow->GetOutDev()->SetFillColor(); else
{
Color nColor; if ( Value >>= nColor )
pWindow->GetOutDev()->SetFillColor( nColor );
} break; case BASEPROPERTY_LINECOLOR: if ( bVoid )
pWindow->GetOutDev()->SetLineColor(); else
{
Color nColor; if ( Value >>= nColor )
pWindow->GetOutDev()->SetLineColor( nColor );
} break; case BASEPROPERTY_HIGHLIGHT_COLOR:
{
Color nColor = 0; if ( bVoid )
{
nColor = Application::GetSettings().GetStyleSettings().GetHighlightColor();
} else
{ if (!(Value >>= nColor)) break;
}
AllSettings aSettings(pWindow->GetSettings());
StyleSettings aStyle(aSettings.GetStyleSettings());
aStyle.SetHighlightColor(nColor);
aSettings.SetStyleSettings(aStyle);
pWindow->SetSettings(aSettings);
} break; case BASEPROPERTY_HIGHLIGHT_TEXT_COLOR:
{
Color nColor = 0; if (bVoid)
{
nColor = Application::GetSettings().GetStyleSettings().GetHighlightTextColor();
} else
{ if (!(Value >>= nColor)) break;
}
AllSettings aSettings(pWindow->GetSettings());
StyleSettings aStyle(aSettings.GetStyleSettings());
aStyle.SetHighlightTextColor(nColor);
aSettings.SetStyleSettings(aStyle);
pWindow->SetSettings(aSettings);
} break; case BASEPROPERTY_BORDER:
{
WinBits nStyle = pWindow->GetStyle();
sal_uInt16 nTmp = 0;
Value >>= nTmp; // clear any dodgy bits passed in, can come from dodgy extensions
nTmp &= o3tl::typed_flags<WindowBorderStyle>::mask;
WindowBorderStyle nBorder = static_cast<WindowBorderStyle>(nTmp); if ( !bool(nBorder) )
{
pWindow->SetStyle( nStyle & ~WB_BORDER );
} else
{
pWindow->SetStyle( nStyle | WB_BORDER );
pWindow->SetBorderStyle( nBorder );
}
} break; case BASEPROPERTY_TABSTOP:
{
WinBits nStyle = pWindow->GetStyle() & ~WB_TABSTOP; if ( !bVoid )
{ bool bTab = false;
Value >>= bTab; if ( bTab )
nStyle |= WB_TABSTOP; else
nStyle |= WB_NOTABSTOP;
}
pWindow->SetStyle( nStyle );
} break; case BASEPROPERTY_VERTICALALIGN:
{
VerticalAlignment eAlign = css::style::VerticalAlignment::VerticalAlignment_MAKE_FIXED_SIZE;
WinBits nStyle = pWindow->GetStyle();
nStyle &= ~(WB_TOP|WB_VCENTER|WB_BOTTOM); if ( !bVoid )
Value >>= eAlign; switch ( eAlign )
{ case VerticalAlignment_TOP:
nStyle |= WB_TOP; break; case VerticalAlignment_MIDDLE:
nStyle |= WB_VCENTER; break; case VerticalAlignment_BOTTOM:
nStyle |= WB_BOTTOM; break; default: ; // for warning free code, MAKE_FIXED_SIZE
}
pWindow->SetStyle( nStyle );
} break; case BASEPROPERTY_ALIGN:
{
sal_Int16 nAlign = PROPERTY_ALIGN_LEFT; switch ( eWinType )
{ case WindowType::COMBOBOX: case WindowType::PUSHBUTTON: case WindowType::OKBUTTON: case WindowType::CANCELBUTTON: case WindowType::HELPBUTTON:
nAlign = PROPERTY_ALIGN_CENTER;
[[fallthrough]]; case WindowType::FIXEDTEXT: case WindowType::EDIT: case WindowType::MULTILINEEDIT: case WindowType::CHECKBOX: case WindowType::RADIOBUTTON: case WindowType::LISTBOX:
{
WinBits nStyle = pWindow->GetStyle();
nStyle &= ~(WB_LEFT|WB_CENTER|WB_RIGHT); if ( !bVoid )
Value >>= nAlign; if ( nAlign == PROPERTY_ALIGN_LEFT )
nStyle |= WB_LEFT; elseif ( nAlign == PROPERTY_ALIGN_CENTER )
nStyle |= WB_CENTER; else
nStyle |= WB_RIGHT;
pWindow->SetStyle( nStyle );
} break; default: break;
}
} break; case BASEPROPERTY_MULTILINE:
{ if ( ( eWinType == WindowType::FIXEDTEXT )
|| ( eWinType == WindowType::CHECKBOX )
|| ( eWinType == WindowType::RADIOBUTTON )
|| ( eWinType == WindowType::PUSHBUTTON )
|| ( eWinType == WindowType::OKBUTTON )
|| ( eWinType == WindowType::CANCELBUTTON )
|| ( eWinType == WindowType::HELPBUTTON )
)
{
WinBits nStyle = pWindow->GetStyle(); bool bMulti = false;
Value >>= bMulti; if ( bMulti )
nStyle |= WB_WORDBREAK; else
nStyle &= ~WB_WORDBREAK;
pWindow->SetStyle( nStyle );
}
} break;
--> --------------------
--> maximum size reached
--> --------------------
Messung V0.5
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.