text: /**************************************************************
   * 
   * 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
   * 
   * Unless required by applicable law or agreed to in writing,
   * software distributed under the License is distributed on an
   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   * KIND, either express or implied.  See the License for the
   * specific language governing permissions and limitations
   * under the License.
   * 
   *************************************************************/
  
  
  
  #include <tools/rc.h>
  //#define RESOURCE_PUBLISH_PROTECTED 1
  #if RESOURCE_PUBLISH_PROTECTED
  // ugh, override non-helpful proctection
  #define protected public
  #endif /* RESOURCE_PUBLISH_PROTECTED */
  #include <tools/rc.hxx>
  #undef protected
  
  
  #include "wrapper.hxx"
  
  #include <awt/vclxplugin.hxx>
  #include <awt/vclxtabcontrol.hxx>
  #include <com/sun/star/awt/PosSize.hpp>
  #include <com/sun/star/awt/VclWindowPeerAttribute.hpp>
  #include <com/sun/star/awt/WindowAttribute.hpp>
  #include <com/sun/star/awt/XDialog2.hpp>
  #include <com/sun/star/awt/XProgressBar.hpp>
  #include <com/sun/star/awt/XSimpleTabController.hpp>
  #include <com/sun/star/awt/XTabListener.hpp>
  #include <com/sun/star/graphic/XGraphic.hpp>
  #include <comphelper/processfactory.hxx>
  #include <layout/core/factory.hxx>
  #include <layout/core/localized-string.hxx>
  #include <layout/core/root.hxx>
  #include <toolkit/awt/vclxwindow.hxx>
  #include <vcl/ctrl.hxx>
  #include <vcl/dialog.hxx>
  #include <vcl/image.hxx>
  #include <vcl/tabctrl.hxx>
  #include <vcl/tabpage.hxx>
  #include <vcl/window.hxx>
  
  using namespace ::com::sun::star;
  using rtl::OUString;
  
  namespace layout
  {
  
  // Context bits ...
  class ContextImpl
  {
      uno::Reference< awt::XLayoutRoot > mxRoot;
      uno::Reference< container::XNameAccess > mxNameAccess;
      PeerHandle mxTopLevel;
  
  public:
      ContextImpl( char const *pPath )
      {
          uno::Sequence< uno::Any > aParams( 1 );
          aParams[0] <<= OUString( pPath, strlen( pPath ), RTL_TEXTENCODING_UTF8 );
  
          uno::Reference< lang::XSingleServiceFactory > xFactory(
              comphelper::createProcessComponent(
                  OUString::createFromAscii( "com.sun.star.awt.Layout" ) ),
              uno::UNO_QUERY );
          if ( !xFactory.is() )
          {
              throw uno::RuntimeException(
                  OUString( RTL_CONSTASCII_USTRINGPARAM( "Layout engine not installed" ) ),
                  uno::Reference< uno::XInterface >() );
          }
          mxRoot = uno::Reference< awt::XLayoutRoot >(
              xFactory->createInstanceWithArguments( aParams ),
              uno::UNO_QUERY );
  
          mxNameAccess = uno::Reference< container::XNameAccess >( mxRoot, uno::UNO_QUERY );
      }
  
      ~ContextImpl()
      {
      }
  
      PeerHandle getByName( const OUString &rName )
      {
          uno::Any val = mxNameAccess->getByName( rName );
          PeerHandle xRet;
          val >>= xRet;
          return xRet;
      }
      PeerHandle getTopLevel()
      {
          return mxTopLevel;
      }
      void setTopLevel( PeerHandle xToplevel )
      {
          mxTopLevel = xToplevel;
      }
      PeerHandle getRoot()
      {
          return mxRoot;
      }
  };
  
  Context::Context( const char *pPath )
      : pImpl( new ContextImpl( pPath ) )
  {
  }
  Context::~Context()
  {
      delete pImpl;
      pImpl = NULL;
  }
  
  void Context::setToplevel( PeerHandle xToplevel )
  {
      pImpl->setTopLevel( xToplevel );
  }
  
  PeerHandle Context::getToplevel()
  {
      return pImpl->getTopLevel();
  }
  PeerHandle Context::getRoot()
  {
      return pImpl->getRoot();
  }
  
  PeerHandle Context::GetPeerHandle( const char *id, sal_uInt32 nId ) const
  {
      PeerHandle xHandle;
      xHandle = pImpl->getByName( OUString( id, strlen( id ), RTL_TEXTENCODING_UTF8 ) );
      if ( !xHandle.is() )
      {
          DBG_ERROR1( "Failed to fetch widget '%s'", id );
      }
  
      if ( nId != 0 )
      {
          rtl::OString aStr = rtl::OString::valueOf( (sal_Int32) nId );
          xHandle = GetPeerHandle( aStr.getStr(), 0 );
      }
      return xHandle;
  }
  
  WindowImpl::WindowImpl (Context *context, const PeerHandle &peer, Window *window)
      : mpWindow (window)
      , mpCtx (context)
      , mxWindow (peer, uno::UNO_QUERY)
      , mxVclPeer (peer, uno::UNO_QUERY)
      , mvclWindow (0)
      , bFirstTimeVisible (true)
  {
  }
  
  WindowImpl::~WindowImpl ()
  {
      if (mpWindow)
          mpWindow->mpImpl = 0;
      if (mvclWindow)
      {
          VCLXWindow *v = mvclWindow->GetWindowPeer ();
          v->SetWindow (0);
          mvclWindow->SetComponentInterface (uno::Reference <awt::XWindowPeer> ());
          mvclWindow->SetWindowPeer (uno::Reference <awt::XWindowPeer> (), 0);
          delete mvclWindow;
          mvclWindow = 0;
      }
  }
  
  void WindowImpl::wrapperGone ()
  {
      mvclWindow = 0;
      mpWindow->mpImpl = 0;
      mpWindow = 0;
      mpCtx = 0;
      if ( mxWindow.is() )
      {
          uno::Reference< lang::XComponent > xComp( mxWindow, uno::UNO_QUERY );
          mxWindow.clear ();
          if ( xComp.is() )
              xComp->dispose();
      }
  }
  
  void SAL_CALL WindowImpl::disposing (lang::EventObject const&)
      throw (uno::RuntimeException)
  {
      if (mxWindow.is ())
          mxWindow.clear ();
  }
  
  uno::Any WindowImpl::getProperty (char const* name)
  {
      if ( !mxVclPeer.is() )
          return css::uno::Any();
      return mxVclPeer->getProperty
          ( rtl::OUString( name, strlen( name ), RTL_TEXTENCODING_ASCII_US ) );
  }
  
  void WindowImpl::setProperty (char const *name, uno::Any any)
  {
      if ( !mxVclPeer.is() )
          return;
      mxVclPeer->setProperty
          ( rtl::OUString( name, strlen( name ), RTL_TEXTENCODING_ASCII_US ), any );
  }
  
  void WindowImpl::redraw (bool resize)
  {
      uno::Reference <awt::XWindow> ref (mxWindow, uno::UNO_QUERY);
      ::Window* window = VCLXWindow::GetImplementation (ref)->GetWindow ();
      ::Window* parent = window->GetParent();
      ::Rectangle r = Rectangle (parent->GetPosPixel (),
                                 parent->GetSizePixel ());
      parent->Invalidate (r, INVALIDATE_CHILDREN | INVALIDATE_NOCHILDREN );
      if (resize)
          parent->SetPosSizePixel (0, 0, 1, 1, awt::PosSize::SIZE);
      else
          parent->SetPosSizePixel (0, 0, r.nRight - r.nLeft, r.nBottom - r.nTop,
                                   awt::PosSize::SIZE);
  }
  
  Window::Window( WindowImpl *pImpl )
      : mpImpl( pImpl )
  {
      mpImpl->mvclWindow = GetVCLXWindow () ? GetWindow () : 0;
  }
  
  Window::~Window()
  {
      /* likely to be an UNO object - with floating references */
      if (mpImpl)
          mpImpl->wrapperGone ();
      mpImpl = 0;
  }
  
  IMPL_GET_IMPL( Control );
  
  Control::~Control ()
  {
      SetGetFocusHdl (Link ());
      SetLoseFocusHdl (Link ());
  }
  
  void Window::setRes (ResId const& res)
  {
  #if RESOURCE_PUBLISH_PROTECTED
      // Resources are shut-off from use.  Is that really necessary?
      Resource &r = *GetWindow ();
      r.GetRes (res);
  #else /* !RESOURCE_PUBLISH_PROTECTED */
      //We *must* derive.  Is this also really necessary?
      //Resource r (res);
  
      // ugh, I wonder which solution is cleaner...
      class Resource_open_up : public Resource
      {
      public:
          Resource_open_up (ResId const& r)
              : Resource (r)
          {
          }
          static sal_Int32 GetLongRes (void *p)
          {
              return Resource::GetLongRes (p);
          }
          void* GetClassRes ()
          {
              return Resource::GetClassRes ();
          }
          sal_Int32 ReadLongRes ()
          {
              return Resource::ReadLongRes ();
          }
          UniString ReadStringRes ()
          {
              return Resource::ReadStringRes ();
          }
          rtl::OString ReadByteStringRes()
          {
              return Resource::ReadByteStringRes();
          }
      };
  
      Resource_open_up r (res);
  #endif /* !RESOURCE_PUBLISH_PROTECTED */
      sal_uInt32 mask = r.ReadLongRes ();
      if (mask & WINDOW_HELPID)
          SetHelpId (r.ReadByteStringRes());
      if ( mask & WINDOW_TEXT )
          SetText( r.ReadStringRes ());
  }
  
  void Window::SetParent( ::Window *parent )
  {
      uno::Reference <awt::XWindow> ref( GetPeer(), uno::UNO_QUERY );
      if (VCLXWindow *vcl = VCLXWindow::GetImplementation( ref ))
          if (::Window *window = vcl->GetWindow())
              window->SetParent( parent );
  }
  
  void Window::SetParent( Window *parent )
  {
      /* Let's hear it for C++: poor man's dynamic binding.  */
      parent->ParentSet (this);
  }
  
  void Window::ParentSet (Window *window)
  {
      window->SetParent (GetWindow ());
  }
  
  Context *Window::getContext()
  {
      return mpImpl ? mpImpl->mpCtx : NULL;
  }
  
  PeerHandle Window::GetPeer() const
  {
      if ( !mpImpl )
          return PeerHandle();
      return mpImpl->mxWindow;
  }
  
  uno::Reference<awt::XWindow> Window::GetRef() const
  {
      return uno::Reference <awt::XWindow> ( GetPeer(), uno::UNO_QUERY );
  }
  
  VCLXWindow* Window::GetVCLXWindow() const
  {
      return VCLXWindow::GetImplementation( GetRef() );
  }
  
  ::Window* Window::GetWindow() const
  {
      return GetVCLXWindow()->GetWindow();
  }
  
  ::Window* Window::GetParent() const
  {
      return GetWindow()->GetParent();
  }
  
  void Window::SetHelpId( const rtl::OString& id )
  {
      GetWindow()->SetHelpId( id );
  }
  
  const rtl::OString& Window::GetHelpId() const
  {
      return GetWindow()->GetHelpId();
  }
  
  void Window::EnterWait ()
  {
      GetWindow()->EnterWait ();
  }
  void Window::LeaveWait ()
  {
      GetWindow()->LeaveWait ();
  }
  bool Window::IsWait () const
  {
      return GetWindow()->IsWait ();
  }
  
  bool Window::IsVisible () const
  {
      if (GetWindow ())
          return GetWindow()->IsVisible ();
      return false;
  }
  
  bool Window::HasChildPathFocus (bool systemWindow) const
  {
      return GetWindow()->HasChildPathFocus (systemWindow);
  }
  
  void Window::SetPosPixel (Point const&)
  {
  }
  
  Point Window::GetPosPixel () const
  {
      return Point ();
  }
  
  void Window::SetSizePixel (Size const&)
  {
  }
  
  void Window::SetPosSizePixel (Point const&, Size const&)
  {
  }
  
  Size Window::GetSizePixel () const
  {
      return Size ();
  }
  
  // void Window::Enable (bool enable, bool child);
  // {
  //     GetWindow ()->Enable (enable, child);
  // }
  
  // void Window::Disable (bool child)
  // {
  //     GetWindow ()->Disable (child);
  // }
  
  bool Window::IsEnabled () const
  {
      return GetWindow ()->IsEnabled ();
  //     if (getImpl().mxWindow.is ())
  //         return getImpl ().mxWindow->isEnabled ();
  //     return false;
  }
  
  void Window::EnableInput (bool enable, bool child)
  {
      GetWindow ()->EnableInput (enable, child);
  }
  
  bool Window::IsInputEnabled () const
  {
      return GetWindow ()->IsInputEnabled ();
  }
  
  bool Window::HasFocus () const
  {
      return GetWindow ()->HasFocus ();
  }
  
  Font& Window::GetFont () const
  {
      return const_cast <Font&> (GetWindow ()->GetFont ());
  }
  
  void Window::SetFont (Font const& font)
  {
      GetWindow ()->SetFont (font);
  }
  
  void Window::Invalidate (sal_uInt8 flags)
  {
      GetWindow ()->Invalidate (flags);
  }
  
  struct ToolkitVclPropsMap
  {
      WinBits vclStyle;
      long initAttr;
      const char *propName;
  
      // the value to give the prop to enable/disable it -- not the most brilliant
      // type declaration and storage, but does the work... properties are
      // either a boolean or a short since they are either a directly wrappers for
      // a WinBit, or aggregates related (like Align for WB_LEFT, _RIGHT and _CENTER).
      bool isBoolean;
      short enableProp, disableProp;
  };
  
  #define TYPE_BOOL  true
  #define TYPE_SHORT false
  #define NOTYPE     0
  static const ToolkitVclPropsMap toolkitVclPropsMap[] =
  {
      { WB_BORDER,    awt::WindowAttribute::BORDER,    "Border", TYPE_SHORT, 1, 0 },
      { WB_NOBORDER,    awt::VclWindowPeerAttribute::NOBORDER,    "Border", TYPE_SHORT, 0, 1 },
      { WB_SIZEABLE,    awt::WindowAttribute::SIZEABLE,    NULL, NOTYPE, 0, 0 },
      { WB_MOVEABLE,    awt::WindowAttribute::MOVEABLE,    NULL, NOTYPE, 0, 0 },
      { WB_CLOSEABLE,    awt::WindowAttribute::CLOSEABLE,    NULL, NOTYPE, 0, 0 },
  
      { WB_HSCROLL,    awt::VclWindowPeerAttribute::HSCROLL,    NULL, NOTYPE, 0, 0 },
      { WB_VSCROLL,    awt::VclWindowPeerAttribute::VSCROLL,    NULL, NOTYPE, 0, 0 },
      { WB_LEFT,    awt::VclWindowPeerAttribute::LEFT,    "Align", TYPE_SHORT, 0, 0 },
      { WB_CENTER,    awt::VclWindowPeerAttribute::CENTER,    "Align", TYPE_SHORT, 1, 0 },
      { WB_RIGHT,    awt::VclWindowPeerAttribute::RIGHT,    "Align", TYPE_SHORT, 2, 0 },
      { WB_SPIN,    awt::VclWindowPeerAttribute::SPIN,    NULL, NOTYPE, 0, 0 },
      { WB_SORT,    awt::VclWindowPeerAttribute::SORT,    NULL, NOTYPE, 0, 0 },
      { WB_DROPDOWN,    awt::VclWindowPeerAttribute::DROPDOWN,    "Dropdown",    TYPE_BOOL, 1, 0 },
      { WB_DEFBUTTON,    awt::VclWindowPeerAttribute::DEFBUTTON,    "DefaultButton", TYPE_BOOL, 1, 0 },
      { WB_READONLY,    awt::VclWindowPeerAttribute::READONLY,    NULL, NOTYPE, 0, 0 },
      { WB_CLIPCHILDREN,    awt::VclWindowPeerAttribute::CLIPCHILDREN,    NULL, NOTYPE, 0, 0 },
      { WB_GROUP,    awt::VclWindowPeerAttribute::GROUP,    NULL, NOTYPE, 0, 0 },
  
      { WB_OK,    awt::VclWindowPeerAttribute::OK,    NULL, NOTYPE, 0, 0 },
      { WB_OK_CANCEL,    awt::VclWindowPeerAttribute::OK_CANCEL,    NULL, NOTYPE, 0, 0 },
      { WB_YES_NO,    awt::VclWindowPeerAttribute::YES_NO,    NULL, NOTYPE, 0, 0 },
      { WB_YES_NO_CANCEL,    awt::VclWindowPeerAttribute::YES_NO_CANCEL,    NULL, NOTYPE, 1, 0 },
      { WB_RETRY_CANCEL,    awt::VclWindowPeerAttribute::RETRY_CANCEL,    NULL, NOTYPE, 1, 0 },
      { WB_DEF_OK,    awt::VclWindowPeerAttribute::DEF_OK,    NULL, NOTYPE, 0, 0 },
      { WB_DEF_CANCEL,    awt::VclWindowPeerAttribute::DEF_CANCEL,    NULL, NOTYPE, 1, 0 },
      { WB_DEF_RETRY,    awt::VclWindowPeerAttribute::DEF_RETRY,    NULL, NOTYPE, 0, 0 },
      { WB_DEF_YES,    awt::VclWindowPeerAttribute::DEF_YES,    NULL, NOTYPE, 0, 0 },
      { WB_DEF_NO,    awt::VclWindowPeerAttribute::DEF_NO,    NULL, NOTYPE, 0, 0 },
  
      { WB_AUTOHSCROLL, awt::VclWindowPeerAttribute::AUTOHSCROLL, "AutoHScroll", TYPE_BOOL, 1, 0 },
      { WB_AUTOVSCROLL, awt::VclWindowPeerAttribute::AUTOVSCROLL, "AutoVScroll",    TYPE_BOOL, 1, 0 },
  
      { WB_WORDBREAK,    0,    "MultiLine", TYPE_BOOL, 1, 0 },
      { WB_NOPOINTERFOCUS,    0,    "FocusOnClick", TYPE_BOOL, 1, 0 },
      { WB_TOGGLE,    0,    "Toggle", TYPE_BOOL, 1, 0 },
      { WB_REPEAT,    0,    "Repeat", TYPE_BOOL, 1, 0 },
      { WB_NOHIDESELECTION,    0,    "HideInactiveSelection", TYPE_BOOL, 1, 0 },
  };
  #undef TYPE_BOOL
  #undef TYPE_SHORT
  #undef NOTYPE
  
  static const int toolkitVclPropsMapLen =
      sizeof( toolkitVclPropsMap ) / sizeof( ToolkitVclPropsMap );
  
  void Window::SetStyle( WinBits nStyle )
  {
      uno::Reference< awt::XVclWindowPeer > xPeer = mpImpl->mxVclPeer;
      for (int i = 0; i < toolkitVclPropsMapLen; i++)
      {
          if ( toolkitVclPropsMap[ i ].propName )
          {
              short nValue;
              if ( nStyle & toolkitVclPropsMap[ i ].vclStyle )
                  nValue = toolkitVclPropsMap[ i ].enableProp;
              else
                  nValue = toolkitVclPropsMap[ i ].disableProp;
              uno::Any aValue;
              if ( toolkitVclPropsMap[ i ].isBoolean )
                  aValue = uno::makeAny( (bool) nValue );
              else
                  aValue = uno::makeAny( (short) nValue );
              if ( mpImpl )
                  mpImpl->setProperty( toolkitVclPropsMap[ i ].propName, aValue );
          }
      }
  }
  
  WinBits Window::GetStyle()
  {
      uno::Reference< awt::XVclWindowPeer > xPeer = mpImpl->mxVclPeer;
      WinBits ret = 0;
      if ( !mpImpl )
         return 0;
      for (int i = 0; i < toolkitVclPropsMapLen; i++)
      {
          if ( toolkitVclPropsMap[ i ].propName )
          {
              short nValue = 0;
              if ( toolkitVclPropsMap[ i ].isBoolean )
              {
                  bool bValue = false;
                  mpImpl->getProperty( toolkitVclPropsMap[ i ].propName ) >>= bValue;
                  nValue = bValue ? 1 : 0;
              }
              else
                  mpImpl->getProperty( toolkitVclPropsMap[ i ].propName ) >>= nValue;
              if ( nValue == toolkitVclPropsMap[ i ].enableProp )
                  ret |= toolkitVclPropsMap[i].vclStyle;
          }
      }
      return ret;
  }
  
  /* Unpleasant way to get an xToolkit pointer ... */
  uno::Reference< awt::XToolkit > getToolkit()
  {
      static uno::Reference< awt::XToolkit > xToolkit;
      if (!xToolkit.is())
      {
          // Urgh ...
          xToolkit = uno::Reference< awt::XToolkit >(
              ::comphelper::getProcessServiceFactory()->createInstance(
                  OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.Toolkit" ) ) ),
              uno::UNO_QUERY );
          if ( !xToolkit.is() )
              throw uno::RuntimeException(
                  OUString( RTL_CONSTASCII_USTRINGPARAM( "failed to create toolkit!") ),
                  uno::Reference< uno::XInterface >() );
      }
      return xToolkit;
  }
  
  PeerHandle Window::CreatePeer( Window *parent, WinBits nStyle, const char *pName)
  {
      long nWinAttrbs = 0;
      for (int i = 0; i < toolkitVclPropsMapLen; i++)
          if ( nStyle & toolkitVclPropsMap[ i ].vclStyle )
              nWinAttrbs |= toolkitVclPropsMap[ i ].initAttr;
  
      return layoutimpl::WidgetFactory::createWidget (getToolkit(), parent->GetPeer(), OUString::createFromAscii( pName ), nWinAttrbs);
  }
  
  void Window::Enable( bool bEnable )
  {
      if ( !getImpl()->mxWindow.is() )
          return;
      getImpl()->mxWindow->setEnable( bEnable );
  }
  
  void Window::Show( bool bVisible )
  {
      if ( !getImpl()->mxWindow.is() )
          return;
      getImpl()->mxWindow->setVisible( bVisible );
      if (!bVisible)
          getImpl()->bFirstTimeVisible = true;
      else if (GetParent() && getImpl()->bFirstTimeVisible)
      {
          getImpl()->redraw ();
          getImpl()->bFirstTimeVisible = false;
      }
  }
  
  void Window::GrabFocus()
  {
      if ( !getImpl()->mxWindow.is() )
          return;
      getImpl()->mxWindow->setFocus();
  }
  
  void Window::SetUpdateMode(bool mode)
  {
      GetWindow()->SetUpdateMode( mode );
  }
  
  void Window::SetPointer( Pointer const& pointer )
  {
      GetWindow()->SetPointer( pointer );
  }
  
  Pointer const& Window::GetPointer() const
  {
      return GetWindow()->GetPointer();
  }
  
  void Window::SetText( OUString const& str )
  {
      GetWindow()->SetText( str );
  }
  
  String Window::GetText() const
  {
      return GetWindow()->GetText();
  }
  
  sal_Int32 Window::GetCtrlTextWidth (OUString const&) const
  {
      return 0;
  }
  
  sal_Int32 Window::GetTextHeight () const
  {
      return 0;
  }
  
  Size Window::LogicToPixel( Size const& size, MapMode const&) const
  {
      return size;
  }
  
  ControlImpl::ControlImpl (Context *context, const PeerHandle &peer, Window *window)
      : WindowImpl( context, peer, window )
  {
  }
  
  ControlImpl::~ControlImpl ()
  {
      if ((!!mGetFocusHdl || !!mLoseFocusHdl) && mxWindow.is ())
          /* Disposing will be done @ VCLXWindow::dispose () maFocusListeners.disposeAndClear()
             don't do it twice */
          mxWindow.clear ();
  }
  
  void ControlImpl::SetGetFocusHdl (Link const& link)
  {
      if (!mLoseFocusHdl || !link)
          UpdateListening (link);
      mGetFocusHdl = link;
  }
  
  Link& ControlImpl::GetGetFocusHdl ()
  {
      return mGetFocusHdl;
  }
  
  void ControlImpl::SetLoseFocusHdl (Link const& link)
  {
      if (!mGetFocusHdl || !link)
          UpdateListening (link);
      mLoseFocusHdl = link;
  }
  
  Link& ControlImpl::GetLoseFocusHdl ()
  {
      return mGetFocusHdl;
  }
  
  void ControlImpl::UpdateListening (Link const& link)
  {
      if (!link && (!!mGetFocusHdl || !!mLoseFocusHdl)
          && (!mGetFocusHdl || !mLoseFocusHdl))
          mxWindow->removeFocusListener (this);
      else if (!!link && !mGetFocusHdl && !mLoseFocusHdl)
          mxWindow->addFocusListener (this);
  }
  
  void SAL_CALL ControlImpl::disposing (lang::EventObject const&)
      throw (uno::RuntimeException)
  {
  ///    mxWindow.clear ();
  }
  
  void SAL_CALL ControlImpl::focusGained (awt::FocusEvent const&)
      throw (uno::RuntimeException)
  {
      mGetFocusHdl.Call (mpWindow);
  }
  
  void SAL_CALL ControlImpl::focusLost (awt::FocusEvent const&)
      throw (uno::RuntimeException)
  {
      mLoseFocusHdl.Call (mpWindow);
  }
  
  Link& Control::GetGetFocusHdl ()
  {
      return getImpl()->GetGetFocusHdl ();
  }
  
  void Control::SetGetFocusHdl (Link const& link)
  {
      if (getImpl() && getImpl()->mxWindow.is ())
          getImpl()->SetGetFocusHdl (link);
  }
  
  Link& Control::GetLoseFocusHdl ()
  {
      return getImpl()->GetLoseFocusHdl ();
  }
  
  void Control::SetLoseFocusHdl (Link const& link)
  {
      if (getImpl() && getImpl()->mxWindow.is ())
          getImpl()->SetLoseFocusHdl (link);
  }
  
  class DialogImpl : public WindowImpl
  {
  public:
      uno::Reference< awt::XDialog2 > mxDialog;
      DialogImpl( Context *context, PeerHandle const &peer, Window *window );
  };
  
  DialogImpl::DialogImpl( Context *context, const PeerHandle &peer, Window *window )
      : WindowImpl( context, peer, window )
      , mxDialog( peer, uno::UNO_QUERY )
  {
  }
  
  Dialog::Dialog( Window *parent, const char *xml_file, const char *id, sal_uInt32 nId )
      : Context( xml_file )
      , Window( new DialogImpl( this, Context::GetPeerHandle( id, nId ), this ) )
      , bConstruct (true)
  {
      if ( parent )
          SetParent( parent );
  }
  
  Dialog::Dialog( ::Window *parent, const char *xml_file, const char *id, sal_uInt32 nId )
      : Context( xml_file )
      , Window( new DialogImpl( this, Context::GetPeerHandle( id, nId ), this ) )
  {
      if ( parent )
          SetParent( parent );
  }
  
  Dialog::~Dialog ()
  {
  }
  
  IMPL_GET_WINDOW (Dialog);
  IMPL_GET_IMPL (Dialog);
  
  #define MX_DIALOG if (getImpl()->mxDialog.is ()) getImpl()->mxDialog
  #define RETURN_MX_DIALOG if (getImpl()->mxDialog.is ()) return getImpl()->mxDialog
  
  short Dialog::Execute()
  {
      RETURN_MX_DIALOG->execute ();
      return -1;
  }
  
  void Dialog::EndDialog( long result )
  {
      MX_DIALOG->endDialog (result);
  }
  
  void Dialog::SetText( OUString const& str )
  {
      SetTitle (str);
  }
  
  void Dialog::SetTitle( OUString const& str )
  {
      MX_DIALOG->setTitle (str);
  }
  
  bool Dialog::Close ()
  {
      EndDialog (false);
      return true;
  }
  
  long Dialog::Notify (NotifyEvent& event)
  {
      return GetDialog ()->Notify (event);
  }
  
  void Dialog::Initialize (SfxChildWinInfo*)
  {
  }
  
  #define MESSAGE_BOX_MEMBER_INIT\
      Dialog (parent, xml_file, id)\
          , imageError (this, "FI_ERROR")\
          , imageInfo (this, "FI_INFO")\
          , imageQuery (this, "FI_QUERY")\
          , imageWarning (this, "FI_WARNING")\
          , messageText (this, "FT_MESSAGE")\
          , cancelButton (this, "BTN_CANCEL")\
          , helpButton (this, "BTN_HELP")\
          , ignoreButton (this, "BTN_IGNORE")\
          , noButton (this, "BTN_NO")\
          , retryButton (this, "BTN_RETRY")\
          , yesButton (this, "BTN_YES")
  
  MessageBox::MessageBox (::Window *parent, char const* message,
                          char const* yes, char const* no, const rtl::OString& help_id,
                          char const* xml_file, char const* id)
      : MESSAGE_BOX_MEMBER_INIT
  {
      ignoreButton.Hide ();
      retryButton.Hide ();
      init (message, yes, no, help_id);
  }
  
  MessageBox::MessageBox (::Window *parent, OUString const& message,
                          OUString yes, OUString no, const rtl::OString& help_id,
                          char const* xml_file, char const* id)
      : MESSAGE_BOX_MEMBER_INIT
  {
      ignoreButton.Hide ();
      retryButton.Hide ();
      init (message, yes, no, help_id);
  }
  
  #if !defined (__GNUC__)
  #define __PRETTY_FUNCTION__ __FUNCTION__
  #endif /* !__GNUC__ */
  
  MessageBox::MessageBox (::Window *parent, WinBits bits, char const* message,
                          char const* yes, char const* no, const rtl::OString& help_id,
                          char const* xml_file, char const* id)
      : MESSAGE_BOX_MEMBER_INIT
  {
      // HIG suggests using verbs instead of yes/no/retry etc.
      // This constructor provides client-code compatibility: Client code should be fixed.
  #ifndef __SUNPRO_CC
      OSL_TRACE ("%s: warning, deprecated vcl/Messbox compatibility", __PRETTY_FUNCTION__);
  #endif
      bits_init (bits, OUString::createFromAscii (message), OUString::createFromAscii (yes), OUString::createFromAscii (no), help_id);
  }
  
  MessageBox::MessageBox (::Window *parent, WinBits bits, OUString const& message,
                          OUString yes, OUString no, const rtl::OString& help_id,
                          char const* xml_file, char const* id)
      : MESSAGE_BOX_MEMBER_INIT
  {
      // HIG suggests using verbs instead of yes/no/retry etc.
      // This constructor provides client-code compatibility: Client code should be fixed.
  #ifndef __SUNPRO_CC
      OSL_TRACE ("%s: warning, deprecated vcl/Messbox compatibility", __PRETTY_FUNCTION__);
  #endif
      bits_init (bits, message, yes, no, help_id);
  }
  
  void MessageBox::bits_init (WinBits bits, OUString const& message,
                              OUString yes, OUString no, const rtl::OString& help_id)
  {
  	if ( bits & ( WB_OK_CANCEL | WB_OK ))
          yes = Button::GetStandardText ( BUTTON_OK );
  	if ( bits & (WB_YES_NO | WB_YES_NO_CANCEL ))
  	{
          yes = Button::GetStandardText ( BUTTON_YES );
          no =  Button::GetStandardText ( BUTTON_NO );
  	}
      if (! (bits & (WB_RETRY_CANCEL | WB_YES_NO_CANCEL | WB_ABORT_RETRY_IGNORE )))
          cancelButton.Hide ();
      if (! (bits & (WB_RETRY_CANCEL | WB_ABORT_RETRY_IGNORE)))
          retryButton.Hide ();
      if ( bits & WB_ABORT_RETRY_IGNORE )
          cancelButton.SetText ( Button::GetStandardText (BUTTON_ABORT));
      else
          ignoreButton.Hide ();
  	if ( !(bits & ( WB_OK | WB_OK_CANCEL | WB_YES_NO | WB_YES_NO_CANCEL)))
          yesButton.Hide ();
  	if ( !(bits & ( WB_YES_NO | WB_YES_NO_CANCEL)))
          noButton.Hide ();
  
      init (message, yes, no, help_id);
  }
  
  void MessageBox::init (char const* message, char const* yes, char const* no, const rtl::OString& help_id)
  {
      init ( OUString::createFromAscii (message), OUString::createFromAscii (yes), OUString::createFromAscii (no), help_id);
  }
  
  void MessageBox::init (OUString const& message, OUString const& yes, OUString const& no, const rtl::OString& help_id)
  {
      imageError.Hide ();
      imageInfo.Hide ();
      imageQuery.Hide ();
      imageWarning.Hide ();
      if (message.getLength ())
          messageText.SetText (message);
      if (yes.getLength ())
      {
          yesButton.SetText (yes);
          if (yes != OUString (Button::GetStandardText (BUTTON_OK))
              && yes != OUString (Button::GetStandardText (BUTTON_YES)))
              SetTitle (yes);
          if (no.getLength ())
              noButton.SetText (no);
          else
              noButton.Hide ();
      }
      if( !help_id.isEmpty())
          SetHelpId (help_id);
      else
          helpButton.Hide ();
  }
  
  #undef MESSAGE_BOX_IMPL
  #define MESSAGE_BOX_IMPL(Name)\
      Name##Box::Name##Box (::Window *parent, char const* message,\
                            char const* yes, char const* no, const rtl::OString& help_id,\
                            char const* xml_file, char const* id)\
      : MessageBox (parent, message, yes, no, help_id, xml_file, id)\
      {\
          image##Name.Show ();\
      }\
      Name##Box::Name##Box (::Window *parent, OUString const& message,\
                            OUString yes, OUString no, const rtl::OString& help_id,\
                            char const* xml_file, char const* id)\
      : MessageBox (parent, message, yes, no, help_id, xml_file, id)\
      {\
          image##Name.Show ();\
      }\
      Name##Box::Name##Box (::Window *parent, WinBits bits, char const* message,\
                            char const* yes, char const* no, const rtl::OString& help_id,\
                            char const* xml_file, char const* id)\
      : MessageBox (parent, bits, message, yes, no, help_id, xml_file, id)\
      {\
          image##Name.Show ();\
      }\
      Name##Box::Name##Box (::Window *parent, WinBits bits, OUString const& message,\
                            OUString yes, OUString no, const rtl::OString& help_id,\
                            char const* xml_file, char const* id)\
      : MessageBox (parent, bits, message, yes, no, help_id, xml_file, id)\
      {\
          image##Name.Show ();\
      }
  
  MESSAGE_BOX_IMPL (Error);
  MESSAGE_BOX_IMPL (Info);
  MESSAGE_BOX_IMPL (Query);
  MESSAGE_BOX_IMPL (Warning);
  
  class TabControlImpl
      : public ControlImpl
      , public ::cppu::WeakImplHelper1 <awt::XTabListener>
  {
      Link mActivatePageHdl;
      Link mDeactivatePageHdl;
  
  public:
      uno::Reference <awt::XSimpleTabController> mxTabControl;
      TabControlImpl (Context *context, const PeerHandle &peer, Window *window)
          : ControlImpl (context, peer, window)
          ,  mxTabControl (peer, uno::UNO_QUERY)
      {
      }
  
      virtual void SAL_CALL disposing (lang::EventObject const& e)
          throw (uno::RuntimeException)
      {
          ControlImpl::disposing (e);
          mxTabControl.clear ();
      }
  
      Link& GetActivatePageHdl ()
      {
          return mActivatePageHdl;
      }
  
      void SetActivatePageHdl (Link const& link)
      {
          if (!mDeactivatePageHdl || !link)
              UpdateListening (link);
          mActivatePageHdl = link;
      }
  
      Link& GetDeactivatePageHdl ()
      {
          return mDeactivatePageHdl;
      }
  
      void SetDeactivatePageHdl (Link const& link)
      {
          if (!mActivatePageHdl || !link)
              UpdateListening (link);
          mDeactivatePageHdl = link;
      }
  
      void UpdateListening (Link const& link)
      {
          if (!link && (!!mActivatePageHdl || !!mDeactivatePageHdl))
              mxTabControl->removeTabListener (this);
          else if (!!link && !mActivatePageHdl && !mDeactivatePageHdl)
              mxTabControl->addTabListener (this);
      }
  
      void SAL_CALL activated (sal_Int32)
          throw (uno::RuntimeException)
      {
          mActivatePageHdl.Call (mpWindow);
      }
  
      void SAL_CALL deactivated (sal_Int32)
          throw (uno::RuntimeException)
      {
          mDeactivatePageHdl.Call (mpWindow);
      }
  
      void SAL_CALL inserted (sal_Int32)
          throw (uno::RuntimeException)
      {
      }
  
      void SAL_CALL removed (sal_Int32)
          throw (uno::RuntimeException)
      {
      }
  
      void SAL_CALL changed (sal_Int32, uno::Sequence <beans::NamedValue> const&)
          throw (uno::RuntimeException)
      {
      }
  };
  
  IMPL_GET_WINDOW (TabControl);
  IMPL_GET_LAYOUT_VCLXWINDOW (TabControl);
  
  #define MX_TABCONTROL if (getImpl()->mxTabControl.is ()) getImpl()->mxTabControl
  #define RETURN_MX_TABCONTROL if (getImpl()->mxTabControl.is ()) return getImpl ()->mxTabControl
  
  TabControl::~TabControl ()
  {
      SetActivatePageHdl (Link ());
      SetDeactivatePageHdl (Link ());
  }
  
  void TabControl::InsertPage (sal_uInt16 id, OUString const& title, sal_uInt16 pos)
  {
      (void) pos;
  //    GetTabControl ()->InsertPage (id, title, pos);
  //    GetTabControl ()->SetTabPage (id, new ::TabPage (GetTabControl ()));
  
      MX_TABCONTROL->insertTab ();
      SetCurPageId (id);
  
  #if 1 // colour me loc productive -- NOT
  #define ADD_PROP( seq, i, name, val )\
      { \
          beans::NamedValue value; \
          value.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( name ) ); \
          value.Value = uno::makeAny( val ); \
          seq[i] = value; \
      }
  
      uno::Sequence< beans::NamedValue > seq (1);
      ADD_PROP ( seq, 0, "Title", OUString (title) );
      MX_TABCONTROL->setTabProps (id, seq);
  #else
      GetTabPage (id)->SetText (title);
  #endif
  
  #if 0
      /// This so seems the right solution, but it makes the buttons of the
      /// tabdialog move up
  
      ::TabPage *page = GetTabPage (id);
      if (Window *w = dynamic_cast <Window*> (page))
      {
          w->SetParent (this);
          //GetVCLXTabControl ()->Box_Base::addChild (uno::Reference <awt::XLayoutConstrains> (w->GetPeer (), uno::UNO_QUERY));
          //GetVCLXTabControl ()->Box_Base::AddChild (uno::Reference <awt::XLayoutConstrains> (w->GetPeer (), uno::UNO_QUERY));
          //GetVCLXTabControl ()->AddChild (w);
          //GetVCLXTabControl ()->AddChild (uno::Reference <awt::XLayoutConstrains> (w->GetPeer (), uno::UNO_QUERY));
          //uno::Reference <uno::XInterface> x (page->GetWindowPeer());
          //GetVCLXTabControl ()->AddChild (uno::Reference <awt::XLayoutConstrains> (page->::Window::GetWindowPeer (), uno::UNO_QUERY));
          //GetVCLXTabControl ()->AddChild (uno::Reference <awt::XLayoutConstrains> (page->GetComponentInterface (), uno::UNO_QUERY));
      }
      getImpl()->redraw ();
  #endif
  }
  void TabControl::RemovePage (sal_uInt16 id)
  {
      GetTabControl ()->RemovePage (id);
  }
  sal_uInt16 TabControl::GetPageCount () const
  {
      return GetTabControl ()->GetPageCount ();
  }
  sal_uInt16 TabControl::GetPageId (sal_uInt16 pos) const
  {
      return GetTabControl ()->GetPageId (pos);
  }
  sal_uInt16 TabControl::GetPagePos (sal_uInt16 id) const
  {
      getImpl()->redraw ();
      return GetTabControl ()->GetPagePos (id);
  }
  void TabControl::SetCurPageId (sal_uInt16 id)
  {
      getImpl()->redraw ();
      GetTabControl ()->SetCurPageId (id);
  }
  sal_uInt16 TabControl::GetCurPageId () const
  {
      return GetTabControl ()->GetCurPageId ();
  }
  void TabControl::SetTabPage (sal_uInt16 id, ::TabPage* page)
  {
      GetTabControl ()->SetTabPage (id, page);
  
  #if 0
      /// This so seems the right solution, but it makes the buttons of the
      /// tabdialog move up
      if (Window *w = dynamic_cast <Window*> (page))
      {
          w->SetParent (this);
          //GetVCLXTabControl ()->Box_Base::addChild (uno::Reference <awt::XLayoutConstrains> (w->GetPeer (), uno::UNO_QUERY));
          //GetVCLXTabControl ()->Box_Base::AddChild (uno::Reference <awt::XLayoutConstrains> (w->GetPeer (), uno::UNO_QUERY));
          //GetVCLXTabControl ()->AddChild (w);
          //GetVCLXTabControl ()->AddChild (uno::Reference <awt::XLayoutConstrains> (w->GetPeer (), uno::UNO_QUERY));
          //GetVCLXTabControl ()->AddChild (uno::Reference <awt::XLayoutConstrains> (page->GetWindowPeer (), uno::UNO_QUERY));
          //GetVCLXTabControl ()->AddChild (uno::Reference <awt::XLayoutConstrains> (page->GetComponentInterface (), uno::UNO_QUERY));
      }
  #endif
      getImpl()->redraw ();
  }
  ::TabPage* TabControl::GetTabPage (sal_uInt16 id) const
  {
      return GetTabControl ()->GetTabPage (id);
  }
  void TabControl::SetActivatePageHdl (Link const& link)
  {
      if (getImpl() && getImpl()->mxTabControl.is ())
          getImpl()->SetActivatePageHdl (link);
  }
  Link& TabControl::GetActivatePageHdl () const
  {
      return getImpl()->GetActivatePageHdl ();
  }
  void TabControl::SetDeactivatePageHdl (Link const& link)
  {
      if (getImpl() && getImpl()->mxTabControl.is ())
          getImpl()->SetDeactivatePageHdl (link);
  }
  Link& TabControl::GetDeactivatePageHdl () const
  {
      return getImpl()->GetDeactivatePageHdl ();
  }
  void TabControl::SetTabPageSizePixel (Size const& size)
  {
      GetTabControl ()->SetTabPageSizePixel (size);
  //    GetParent()->SetSizePixel (size);
  //    GetWindow()->SetSizePixel (size);
      //GetVCLXTabControl->SetTabSize (size);
  }
  Size TabControl::GetTabPageSizePixel () const
  {
  #if 0
      //return GetTabControl ()->GetTabPageSizePixel ();
      static size_t const tab_page_first_index = 1;
      for (size_t i = 0; i < GetPageCount (); i++)
      {
          ::TabPage *p = GetTabPage (i + tab_page_first_index);
          //if (dynamic_cast<Windowt*> (p))
          if (i) // URG
              return p->GetOptimalSize (WINDOWSIZE_MINIMUM);
      }
  #endif
      return GetTabControl ()->GetTabPageSizePixel ();
  }
  
  IMPL_CONSTRUCTORS (TabControl, Control, "tabcontrol");
  IMPL_GET_IMPL (TabControl);
  
  class TabPageImpl : public WindowImpl
  {
  public:
      uno::Reference< awt::XWindow > mxTabPage;
      TabPageImpl( Context *context, const PeerHandle &peer, Window *window )
          : WindowImpl( context, peer, window )
          , mxTabPage( peer, uno::UNO_QUERY )
      {
      }
  };
  
  ::Window* TabPage::global_parent = 0;
  TabControl* TabPage::global_tabcontrol = 0;
  
  IMPL_GET_IMPL( TabPage );
  
  TabPage::TabPage( Window *parent, const char *xml_file, const char *id, sal_uInt32 nId)
      : Context( xml_file )
      , Window( new TabPageImpl( this, Context::GetPeerHandle( id, nId ), this ) )
  {
      if ( parent )
          SetParent( parent );
  }
  
  TabPage::TabPage( ::Window *parent, const char *xml_file, const char *id, sal_uInt32 nId)
      : Context( xml_file )
      , Window( new TabPageImpl( this, Context::GetPeerHandle( id, nId ), this ) )
  {
      if ( parent )
          SetParent( parent );
  }
  
  TabPage::~TabPage()
  {
      delete GetTabPage();
  }
  
  IMPL_GET_WINDOW( TabPage );
  
  void TabPage::ActivatePage()
  {
  }
  
  void TabPage::DeactivatePage()
  {
  }
  
  class FixedLineImpl : public ControlImpl
  {
  public:
      FixedLineImpl( Context *context, const PeerHandle &peer, Window *window )
          : ControlImpl( context, peer, window )
      {
      }
  };
  
  IMPL_CONSTRUCTORS( FixedLine, Control, "hfixedline" );
  IMPL_GET_IMPL( FixedLine );
  
  bool FixedLine::IsEnabled() const
  {
      //FIXME
      return true;
  }
  
  class FixedTextImpl : public ControlImpl
  {
  public:
      uno::Reference< awt::XFixedText > mxFixedText;
      FixedTextImpl( Context *context, const PeerHandle &peer, Window *window )
          : ControlImpl( context, peer, window )
          , mxFixedText( peer, uno::UNO_QUERY )
      {
      }
  
      ~FixedTextImpl ();
  
      virtual void SAL_CALL disposing( lang::EventObject const& e )
          throw (uno::RuntimeException);
  };
  
  FixedTextImpl::~FixedTextImpl ()
  {
  }
  
  void SAL_CALL FixedTextImpl::disposing( lang::EventObject const& e )
      throw (uno::RuntimeException)
  {
      ControlImpl::disposing (e);
      mxFixedText.clear ();
  }
  
  FixedText::~FixedText ()
  {
  }
  
  IMPL_CONSTRUCTORS( FixedText, Control, "fixedtext" );
  IMPL_GET_IMPL( FixedText );
  
  void FixedText::SetText( OUString const& rStr )
  {
      if ( !getImpl()->mxFixedText.is() )
          return;
      getImpl()->mxFixedText->setText( rStr );
  }
  
  class FixedInfoImpl : public FixedTextImpl
  {
  public:
      FixedInfoImpl( Context *context, const PeerHandle &peer, Window *window )
          : FixedTextImpl( context, peer, window )
      {
      }
  };
  
  IMPL_CONSTRUCTORS( FixedInfo, FixedText, "fixedinfo" );
  IMPL_GET_IMPL( FixedInfo );
  
  class ProgressBarImpl : public ControlImpl
  {
  public:
      uno::Reference< awt::XProgressBar > mxProgressBar;
      ProgressBarImpl( Context *context, const PeerHandle &peer, Window *window )
          : ControlImpl( context, peer, window )
          , mxProgressBar( peer, uno::UNO_QUERY )
      {
      }
  
      virtual void SAL_CALL disposing( lang::EventObject const& e )
          throw (uno::RuntimeException)
      {
          ControlImpl::disposing (e);
          mxProgressBar.clear ();
      }
  };
  
  
  class FixedImageImpl: public ControlImpl
  {
  public:
      uno::Reference< graphic::XGraphic > mxGraphic;
      FixedImageImpl( Context *context, const PeerHandle &peer, Window *window)
  //                    const char *pName )
          : ControlImpl( context, peer, window )
            //, mxGraphic( layoutimpl::loadGraphic( pName ) )
          , mxGraphic( peer, uno::UNO_QUERY )
      {
          if ( !mxGraphic.is() )
          {
              DBG_ERROR( "ERROR: failed to load image: `%s'" /*, pName*/ );
          }
  #if 0
          else
              getImpl()->mxGraphic->...();
  #endif
      }
  };
  
  IMPL_CONSTRUCTORS( FixedImage, Control, "fixedimage" );
  IMPL_GET_IMPL( FixedImage )
  
  void FixedImage::setImage( ::Image const& i )
  {
      (void) i;
      if ( !getImpl()->mxGraphic.is() )
          return;
      //FIXME: hack moved to proplist
      //getImpl()->mxGraphic =
  }
  
  #if 0
  
  FixedImage::FixedImage( const char *pName )
      : pImpl( new FixedImageImpl( pName ) )
  {
  }
  
  FixedImage::~FixedImage()
  {
      delete pImpl;
  }
  
  #endif
  
  
  IMPL_CONSTRUCTORS( ProgressBar, Control, "ProgressBar" );
  IMPL_GET_IMPL( ProgressBar );
  
  void ProgressBar::SetForegroundColor( util::Color color )
  {
      if ( !getImpl()->mxProgressBar.is() )
          return;
      getImpl()->mxProgressBar->setForegroundColor( color );
  }
  
  void ProgressBar::SetBackgroundColor( util::Color color )
  {
      if ( !getImpl()->mxProgressBar.is() )
          return;
      getImpl()->mxProgressBar->setBackgroundColor( color );
  }
  
  void ProgressBar::SetValue( sal_Int32 i )
  {
      if ( !getImpl()->mxProgressBar.is() )
          return;
      getImpl()->mxProgressBar->setValue( i );
  }
  
  void ProgressBar::SetRange( sal_Int32 min, sal_Int32 max )
  {
      if ( !getImpl()->mxProgressBar.is() )
          return;
      getImpl()->mxProgressBar->setRange( min, max );
  }
  
  sal_Int32 ProgressBar::GetValue()
  {
      if ( !getImpl()->mxProgressBar.is() )
          return 0;
      return getImpl()->mxProgressBar->getValue();
  }
  
  class PluginImpl: public ControlImpl
  {
  public:
      ::Control *mpPlugin;
  
      PluginImpl( Context *context, const PeerHandle &peer, Window *window, :: Control *plugin )
          : ControlImpl( context, peer, window )
          , mpPlugin( plugin )
      {
          uno::Reference <awt::XWindow> ref( mxWindow, uno::UNO_QUERY );
          layoutimpl::VCLXPlugin *vcl
              = static_cast<layoutimpl::VCLXPlugin*>( VCLXWindow::GetImplementation( ref ) );
          ::Window *parent = vcl->mpWindow->GetParent();
          vcl->SetWindow( plugin );
          vcl->SetPlugin( mpPlugin );
          plugin->SetParent( parent );
          plugin->SetStyle( vcl->mStyle );
          plugin->SetCreatedWithToolkit( true );
          plugin->SetComponentInterface( vcl );
          plugin->Show();
      }
  };
  
  Plugin::Plugin( Context *context, char const *id, ::Control *plugin )
      : Control( new PluginImpl( context, context->GetPeerHandle( id, 0 ), this, plugin ) )
      , mpPlugin( plugin )
  {
  }
  
  IMPL_GET_IMPL( Plugin );
  
  class LocalizedStringImpl : public WindowImpl
  {
  public:
      layoutimpl::LocalizedString *mpString;
      OUString maString;
      LocalizedStringImpl( Context *context, const PeerHandle &peer, Window *window )
          : WindowImpl( context, peer, window )
          , mpString( static_cast<layoutimpl::LocalizedString*>( VCLXWindow::GetImplementation( uno::Reference <awt::XWindow> ( mxWindow, uno::UNO_QUERY ) ) ) )
          , maString ()
      {
      }
      OUString getText()
      {
          if (mpString)
              maString = mpString->getText ();
          return maString;
      }
      void setText( OUString const& s )
      {
          if (mpString)
              mpString->setText( s );
      }
  };
  
  IMPL_GET_IMPL( LocalizedString );
  
  LocalizedString::LocalizedString( Context *context, char const* id )
      : Window( new LocalizedStringImpl( context, context->GetPeerHandle( id, 0 ), this ) )
  {
  }
  
  String LocalizedString::getString ()
  {
      return getImpl()->getText ();
  }
  
  OUString LocalizedString::getOUString ()
  {
      return getImpl()->getText ();
  }
  
  LocalizedString::operator OUString ()
  {
      return getOUString ();
  }
  
  LocalizedString::operator OUString const& ()
  {
      getOUString ();
      return getImpl()->maString;
  }
  
  LocalizedString::operator String()
  {
      getOUString ();
      return getImpl()->maString;
  }
  
  String LocalizedString::GetToken (sal_uInt16 i, sal_Char c)
  {
      return getString ().GetToken (i, c);
  }
  
  OUString LocalizedString::operator= (OUString const& s)
  {
      getImpl()->setText( s );
      return getImpl()->getText();
  }
  
  OUString LocalizedString::operator+= (OUString const& b)
  {
      OUString a = getImpl()->getText ();
      a += b;
      getImpl()->setText (a);
      return getImpl()->getText ();
  }
  
  OUString LocalizedString::operator+= (sal_Unicode const b)
  {
      String a = getImpl()->getText ();
      a += b;
      getImpl()->setText (a);
      return getImpl()->getText ();
  }
  
  class InPlugImpl : public WindowImpl
  {
  public:
      InPlugImpl (Context *context, const PeerHandle &peer, Window *window)
          : WindowImpl (context, peer, window)
      {
      }
  };
  
  IMPL_GET_IMPL (InPlug);
  
  static char const *FIXME_set_parent (::Window *parent, char const *xml_file)
  {
      layout::TabPage::global_parent = parent;
      return xml_file;
  }
  
  InPlug::InPlug (Window *parent, char const* xml_file, char const* id, sal_uInt32 nId)
      : Context (FIXME_set_parent (parent ? parent->GetWindow () : 0, xml_file))
      , layout::Window (new InPlugImpl (this, Context::GetPeerHandle (id, nId), this))
  {
      if (parent)
          SetParent (parent);
      if (::Window *w = dynamic_cast< ::Window* > (this))
          w->SetComponentInterface (GetVCLXWindow ());
  }
  
  InPlug::InPlug (::Window *parent, char const* xml_file, char const* id, sal_uInt32 nId)
      : Context (FIXME_set_parent (parent, xml_file))
      , layout::Window (new InPlugImpl (this, Context::GetPeerHandle (id, nId), this))
  {
      if (parent)
          layout::Window::SetParent (parent);
      if (::Window *w = dynamic_cast< ::Window* > (this))
          w->SetComponentInterface (GetVCLXWindow ());
  }
  
  void InPlug::ParentSet (Window *window)
  {
      window->SetParent (dynamic_cast< ::Window* > (this));
  
      /// FIXME: for standalone run of layout::SfxTabDialog
      SetParent (window->GetParent ());
  }
  
  } // namespace layout
  