diff options
author | Frank Schoenheit [fs] <frank.schoenheit@sun.com> | 2010-04-09 09:37:17 +0200 |
---|---|---|
committer | Frank Schoenheit [fs] <frank.schoenheit@sun.com> | 2010-04-09 09:37:17 +0200 |
commit | 5d5e24f5bc71d413f051746063573a72db65ab7d (patch) | |
tree | aaad06c8859ffd54160a928ab8b753a9d4d1faca /svtools | |
parent | 0768a7d2726ce4f0772b52d95eeb23143336655c (diff) | |
parent | bc05d94bb339e0f25bb329ad0c6b27d779d3e664 (diff) |
slidecopy: merge CWS wth MWS-m76
Diffstat (limited to 'svtools')
45 files changed, 5752 insertions, 166 deletions
diff --git a/svtools/inc/svtools/accessiblefactory.hxx b/svtools/inc/svtools/accessiblefactory.hxx index b435d3da96a7..9606e93a2fa0 100644..100755 --- a/svtools/inc/svtools/accessiblefactory.hxx +++ b/svtools/inc/svtools/accessiblefactory.hxx @@ -61,6 +61,10 @@ namespace svt { //........................................................................ + class ToolPanelDeck; + class IToolPanelDeck; + class PanelTabBar; + /** a function which is able to create a factory for the standard Accessible/Context components needed for standard toolkit controls @@ -162,6 +166,18 @@ namespace svt sal_Int32 _nRowPos, sal_uInt16 _nColPos ) const = 0; + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > + createAccessibleToolPanelDeck( + const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& i_rAccessibleParent, + ::svt::ToolPanelDeck& i_rPanelDeck + ) = 0; + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > + createAccessibleToolPanelTabBar( + const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& i_rAccessibleParent, + ::svt::IToolPanelDeck& i_rPanelDeck, + ::svt::PanelTabBar& i_rTabBar + ) = 0; }; //........................................................................ diff --git a/svtools/inc/svtools/accessibletable.hxx b/svtools/inc/svtools/accessibletable.hxx index b08a7f04f1da..457b63a0a488 100644..100755 --- a/svtools/inc/svtools/accessibletable.hxx +++ b/svtools/inc/svtools/accessibletable.hxx @@ -100,7 +100,7 @@ public: AccessibleTableControlObjType eObjType ) const= 0; // Window - virtual Rectangle GetWindowExtentsRelative( Window *pRelativeWindow ) = 0; + virtual Rectangle GetWindowExtentsRelative( Window *pRelativeWindow ) const = 0; virtual void GrabFocus()= 0; virtual XACC GetAccessible( BOOL bCreate = TRUE )= 0; virtual Window* GetAccessibleParentWindow() const= 0; diff --git a/svtools/inc/svtools/accessibletableprovider.hxx b/svtools/inc/svtools/accessibletableprovider.hxx index fd29c72f35be..d14aecce9f58 100644 --- a/svtools/inc/svtools/accessibletableprovider.hxx +++ b/svtools/inc/svtools/accessibletableprovider.hxx @@ -132,7 +132,7 @@ public: virtual BOOL GetGlyphBoundRects( const Point& rOrigin, const String& rStr, int nIndex, int nLen, int nBase, MetricVector& rVector ) = 0; // Window - virtual Rectangle GetWindowExtentsRelative( Window *pRelativeWindow ) = 0; + virtual Rectangle GetWindowExtentsRelative( Window *pRelativeWindow ) const = 0; virtual void GrabFocus() = 0; virtual XACC GetAccessible( BOOL bCreate = TRUE ) = 0; virtual Window* GetAccessibleParentWindow() const = 0; diff --git a/svtools/inc/svtools/brwbox.hxx b/svtools/inc/svtools/brwbox.hxx index 9adeaf7efd05..8a8e4c04ecad 100644 --- a/svtools/inc/svtools/brwbox.hxx +++ b/svtools/inc/svtools/brwbox.hxx @@ -848,7 +848,7 @@ public: virtual sal_Bool IsCellVisible( sal_Int32 _nRow, sal_uInt16 _nColumn ) const; virtual String GetAccessibleCellText(long _nRow, USHORT _nColPos) const; virtual BOOL GetGlyphBoundRects( const Point& rOrigin, const String& rStr, int nIndex, int nLen, int nBase, MetricVector& rVector ); - virtual Rectangle GetWindowExtentsRelative( Window *pRelativeWindow ); + virtual Rectangle GetWindowExtentsRelative( Window *pRelativeWindow ) const; virtual void GrabFocus(); virtual XACC GetAccessible( BOOL bCreate = TRUE ); virtual Window* GetAccessibleParentWindow() const; diff --git a/svtools/inc/svtools/svtabbx.hxx b/svtools/inc/svtools/svtabbx.hxx index 8b8092260e33..89fd92a4fc09 100644 --- a/svtools/inc/svtools/svtabbx.hxx +++ b/svtools/inc/svtools/svtabbx.hxx @@ -251,7 +251,7 @@ public: virtual BOOL GetGlyphBoundRects( const Point& rOrigin, const String& rStr, int nIndex, int nLen, int nBase, MetricVector& rVector ); // Window - virtual Rectangle GetWindowExtentsRelative( Window *pRelativeWindow ); + virtual Rectangle GetWindowExtentsRelative( Window *pRelativeWindow ) const; virtual void GrabFocus(); virtual XACC GetAccessible( BOOL bCreate = TRUE ); virtual Window* GetAccessibleParentWindow() const; diff --git a/svtools/inc/svtools/table/tablecontrol.hxx b/svtools/inc/svtools/table/tablecontrol.hxx index c1381e3b3c0b..cbe22da4a9d5 100644 --- a/svtools/inc/svtools/table/tablecontrol.hxx +++ b/svtools/inc/svtools/table/tablecontrol.hxx @@ -180,7 +180,7 @@ namespace svt { namespace table AccessibleTableControlObjType eObjType ) const; //// Window - virtual Rectangle GetWindowExtentsRelative( Window *pRelativeWindow ); + virtual Rectangle GetWindowExtentsRelative( Window *pRelativeWindow ) const; virtual void GrabFocus(); virtual XACC GetAccessible( BOOL bCreate = TRUE ); virtual Window* GetAccessibleParentWindow() const; diff --git a/svtools/inc/svtools/toolpanel/decklayouter.hxx b/svtools/inc/svtools/toolpanel/decklayouter.hxx new file mode 100755 index 000000000000..da03d7c6c3aa --- /dev/null +++ b/svtools/inc/svtools/toolpanel/decklayouter.hxx @@ -0,0 +1,104 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + +#ifndef SVT_DECKLAYOUTER_HXX +#define SVT_DECKLAYOUTER_HXX + +#include <com/sun/star/uno/Reference.hxx> + +#include <rtl/ref.hxx> + +#include <boost/optional.hpp> + +namespace com { namespace sun { namespace star { namespace accessibility { + class XAccessible; +} } } } +class Rectangle; +class Point; + +//........................................................................ +namespace svt +{ +//........................................................................ + + //==================================================================== + //= IDeckLayouter + //==================================================================== + class IDeckLayouter : public ::rtl::IReference + { + public: + /** re-arranges the elements of the tool deck, taking into account the + available space for the complete deck. + + @param i_rDeckPlayground + the playground for the complete tool panel deck + @return + the content area for a single tool panel + */ + virtual ::Rectangle Layout( const ::Rectangle& i_rDeckPlayground ) = 0; + + /** destroys the instance + + Since the layouter is ref-counted, but might keep references to non-ref-counted objects + (in particular, the ToolPanelDeck, which is a VCL-Window, and thus cannot be ref-counted), + Destroy is the definitive way to dispose the instance. Technically, it's still alive afterwards, + but non-functional. + */ + virtual void Destroy() = 0; + + /** assuming that a layouter neesds to provide some kind of panel selector control, this method + requests to set the focus to this control. + */ + virtual void SetFocusToPanelSelector() = 0; + + /** returns the number of components in the XAccessible hierarchy which are needed to represent all elements + the layouter is responsible form. + + Note that the implementation must guarantee that the count is fixed over the life time of the layouter. + */ + virtual size_t GetAccessibleChildCount() const = 0; + + /** retrieves the XAccessible implementation for the <code>i_nChildIndex</code>'th child in the XAccessible + hierarchy. + */ + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > + GetAccessibleChild( + const size_t i_nChildIndex, + const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& i_rParentAccessible + ) = 0; + + virtual ~IDeckLayouter() + { + } + }; + + typedef ::rtl::Reference< IDeckLayouter > PDeckLayouter; + +//........................................................................ +} // namespace svt +//........................................................................ + +#endif // SVT_DECKLAYOUTER_HXX diff --git a/svtools/inc/svtools/toolpanel/paneltabbar.hxx b/svtools/inc/svtools/toolpanel/paneltabbar.hxx new file mode 100644 index 000000000000..668935d8a739 --- /dev/null +++ b/svtools/inc/svtools/toolpanel/paneltabbar.hxx @@ -0,0 +1,102 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + +#ifndef SVT_PANELTABBAR_HXX +#define SVT_PANELTABBAR_HXX + +#include "svtools/svtdllapi.h" +#include "svtools/toolpanel/tabalignment.hxx" +#include "svtools/toolpanel/tabitemcontent.hxx" + +#include <vcl/ctrl.hxx> + +#include <memory> +#include <boost/optional.hpp> + +class PushButton; + +//........................................................................ +namespace svt +{ +//........................................................................ + + class PanelTabBar_Impl; + class IToolPanelDeck; + + //==================================================================== + //= PanelTabBar + //==================================================================== + /** a tab bar for selecting panels + + At the moment, this control aligns the tabs vertically, this might be extended to also support a horizontal + layout in the future. + */ + class SVT_DLLPUBLIC PanelTabBar : public Control + { + public: + PanelTabBar( Window& i_rParentWindow, IToolPanelDeck& i_rPanelDeck, const TabAlignment i_eAlignment, const TabItemContent i_eItemContent ); + ~PanelTabBar(); + + // attribute access + TabItemContent GetTabItemContent() const; + void SetTabItemContent( const TabItemContent& i_eItemContent ); + + ::boost::optional< size_t > GetFocusedPanelItem() const; + void FocusPanelItem( const size_t i_nItemPos ); + Rectangle GetItemScreenRect( const size_t i_nItemPos ) const; + bool IsVertical() const; + IToolPanelDeck& GetPanelDeck() const; + PushButton& GetScrollButton( const bool i_bForward ); + + // Window overridables + virtual Size GetOptimalSize( WindowSizeType i_eType ) const; + + protected: + // Window overridables + virtual void Paint( const Rectangle& i_rRect ); + virtual void Resize(); + virtual void MouseMove( const MouseEvent& i_rMouseEvent ); + virtual void MouseButtonDown( const MouseEvent& i_rMouseEvent ); + virtual void MouseButtonUp( const MouseEvent& i_rMouseEvent ); + virtual void RequestHelp( const HelpEvent& i_rHelpEvent ); + virtual void GetFocus(); + virtual void LoseFocus(); + virtual void KeyInput( const KeyEvent& i_rKeyEvent ); + virtual void DataChanged( const DataChangedEvent& i_rDataChanedEvent ); + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > + GetComponentInterface( BOOL i_bCreate ); + + private: + ::std::auto_ptr< PanelTabBar_Impl > m_pImpl; + }; + +//........................................................................ +} // namespace svt +//........................................................................ + +#endif // SVT_PANELTABBAR_HXX + diff --git a/svtools/inc/svtools/toolpanel/refbase.hxx b/svtools/inc/svtools/toolpanel/refbase.hxx new file mode 100644 index 000000000000..991d6e619090 --- /dev/null +++ b/svtools/inc/svtools/toolpanel/refbase.hxx @@ -0,0 +1,80 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + +#ifndef SVT_REFBASE_HXX +#define SVT_REFBASE_HXX + +#include "svtools/svtdllapi.h" + +#include <rtl/ref.hxx> + +//........................................................................ +namespace svt +{ +//........................................................................ + + //==================================================================== + //= RefBase + //==================================================================== + class SVT_DLLPUBLIC RefBase : public ::rtl::IReference + { + protected: + RefBase() + :m_refCount( 0 ) + { + } + + virtual ~RefBase() + { + } + + virtual oslInterlockedCount SAL_CALL acquire(); + virtual oslInterlockedCount SAL_CALL release(); + + private: + oslInterlockedCount m_refCount; + }; + +#define DECLARE_IREFERENCE() \ + virtual oslInterlockedCount SAL_CALL acquire(); \ + virtual oslInterlockedCount SAL_CALL release(); + + +#define IMPLEMENT_IREFERENCE( classname ) \ + oslInterlockedCount classname::acquire() \ + { \ + return RefBase::acquire(); \ + } \ + oslInterlockedCount classname::release() \ + { \ + return RefBase::release(); \ + } + +//........................................................................ +} // namespace svt +//........................................................................ + +#endif // SVT_REFBASE_HXX diff --git a/svtools/inc/svtools/toolpanel/tabalignment.hxx b/svtools/inc/svtools/toolpanel/tabalignment.hxx new file mode 100644 index 000000000000..cc3f17469ffe --- /dev/null +++ b/svtools/inc/svtools/toolpanel/tabalignment.hxx @@ -0,0 +1,47 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + +#ifndef SVT_TABALIGNMENT_HXX +#define SVT_TABALIGNMENT_HXX + +//........................................................................ +namespace svt +{ +//........................................................................ + + enum TabAlignment + { + TABS_LEFT, + TABS_RIGHT, + TABS_TOP, + TABS_BOTTOM + }; + +//........................................................................ +} // namespace svt +//........................................................................ + +#endif // SVT_TABALIGNMENT_HXX diff --git a/svtools/inc/svtools/toolpanel/tabitemcontent.hxx b/svtools/inc/svtools/toolpanel/tabitemcontent.hxx new file mode 100644 index 000000000000..a1cf9deae9f4 --- /dev/null +++ b/svtools/inc/svtools/toolpanel/tabitemcontent.hxx @@ -0,0 +1,48 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + +#ifndef SVT_TABITEMCONTENT_HXX +#define SVT_TABITEMCONTENT_HXX + +//........................................................................ +namespace svt +{ +//........................................................................ + + enum TabItemContent + { + TABITEM_IMAGE_AND_TEXT, + TABITEM_IMAGE_ONLY, + TABITEM_TEXT_ONLY, + + TABITEM_AUTO + }; + +//........................................................................ +} // namespace svt +//........................................................................ + +#endif // SVT_TABITEMCONTENT_HXX diff --git a/svtools/inc/svtools/toolpanel/tablayouter.hxx b/svtools/inc/svtools/toolpanel/tablayouter.hxx new file mode 100755 index 000000000000..92b36acf9114 --- /dev/null +++ b/svtools/inc/svtools/toolpanel/tablayouter.hxx @@ -0,0 +1,112 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + +#ifndef SVT_TABLAYOUTER_HXX +#define SVT_TABLAYOUTER_HXX + +#include "svtools/svtdllapi.h" +#include "svtools/toolpanel/decklayouter.hxx" +#include "svtools/toolpanel/tabalignment.hxx" +#include "svtools/toolpanel/tabitemcontent.hxx" +#include "svtools/toolpanel/refbase.hxx" + +#include <memory> + +#include <boost/noncopyable.hpp> + +class Window; + +//........................................................................ +namespace svt +{ +//........................................................................ + + class IToolPanelDeck; + + struct TabDeckLayouter_Data; + + //==================================================================== + //= TabDeckLayouter + //==================================================================== + class SVT_DLLPUBLIC TabDeckLayouter :public RefBase + ,public IDeckLayouter + ,public ::boost::noncopyable + { + public: + /** creates a new layouter + @param i_rParent + is the parent window for any VCL windows the layouter needs to create. + @param i_rPanels + is the panel deck which the layouter is responsible for. + @param i_eAlignment + specifies the alignment of the panel selector + @param TabItemContent + specifies the content to show on the tab items + */ + TabDeckLayouter( + Window& i_rParent, + IToolPanelDeck& i_rPanels, + const TabAlignment i_eAlignment, + const TabItemContent i_eItemContent + ); + ~TabDeckLayouter(); + + // attribute access + TabItemContent GetTabItemContent() const; + void SetTabItemContent( const TabItemContent& i_eItemContent ); + TabAlignment GetTabAlignment() const; + + // helpers for the A11Y implementation + ::boost::optional< size_t > + GetFocusedPanelItem() const; + void FocusPanelItem( const size_t i_nItemPos ); + bool IsPanelSelectorEnabled() const; + bool IsPanelSelectorVisible() const; + Rectangle GetItemScreenRect( const size_t i_nItemPos ) const; + + // IDeckLayouter + virtual Rectangle Layout( const Rectangle& i_rDeckPlayground ); + virtual void Destroy(); + virtual void SetFocusToPanelSelector(); + virtual size_t GetAccessibleChildCount() const; + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > + GetAccessibleChild( + const size_t i_nChildIndex, + const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& i_rParentAccessible + ); + + // IReference + DECLARE_IREFERENCE() + + private: + ::std::auto_ptr< TabDeckLayouter_Data > m_pData; + }; + +//........................................................................ +} // namespace svt +//........................................................................ + +#endif // SVT_TABLAYOUTER_HXX diff --git a/svtools/inc/svtools/toolpanel/toolpanel.hxx b/svtools/inc/svtools/toolpanel/toolpanel.hxx new file mode 100644 index 000000000000..d4d009b5c169 --- /dev/null +++ b/svtools/inc/svtools/toolpanel/toolpanel.hxx @@ -0,0 +1,143 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + +#ifndef SVT_TOOLPANEL_HXX +#define SVT_TOOLPANEL_HXX + +#include "svtools/svtdllapi.h" +#include "svtools/toolpanel/refbase.hxx" + +#include <rtl/ustring.hxx> +#include <vcl/image.hxx> + +#include <boost/noncopyable.hpp> + +class Rectangle; +class Window; +namespace com { namespace sun { namespace star { namespace accessibility { + class XAccessible; +} } } } + +//........................................................................ +namespace svt +{ +//........................................................................ + + //==================================================================== + //= IToolPanel + //==================================================================== + /** abstract interface for a single tool panel + */ + class SVT_DLLPUBLIC IToolPanel : public ::rtl::IReference + { + public: + /// retrieves the display name of the panel + virtual ::rtl::OUString GetDisplayName() const = 0; + + /// retrieves the image associated with the panel, if any + virtual Image GetImage() const = 0; + + /** activates the panel + + Usually, this means the panel's Window is created (if not previosly done so) and shown. + + @param i_rParentWindow + the parent window to anchor the panel window at. Subsequent calls to the Activate + method will always get the same parent window. The complete area of this window is + available, and should be used, for the panel window. + */ + virtual void Activate( Window& i_rParentWindow ) = 0; + + /** deactivates the panel + + There are different ways how an implementation could deactivate a panel. The easiest way + would be to simply hide the associated Window. Alternatively, you could completely destroy it, + or decide to cache it by re-parenting it to another (temporary, invisible) window. + */ + virtual void Deactivate() = 0; + + /** sets a new size for the panel's Window + + The panel window is always expected to be positioned at (0,0), relative to the parent window + which was passed to the Activate member. Resizing the panel window is necessary when the size of + this parent window changes. Effectively, this method is a means of convenience, to relief panel + implementations from reacting on size changes of their parent window themselves. + */ + virtual void SetSizePixel( const Size& i_rPanelWindowSize ) = 0; + + /// sets the focus to the panel window + virtual void GrabFocus() = 0; + + /** release any resources associated with the panel. + + In particular, implementations should ultimately destroy the VCL window which implements the panel + window. No subsequent calls to any other method will happen after Destroy has been called. + */ + virtual void Dispose() = 0; + + /** creates an XAccessible for the tool panel + + Implementations are allowed to create a new instance each time this method is called, the caller + is responsible for caching the XAccessible implementation, if this is desired. + */ + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > + CreatePanelAccessible( + const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& i_rParentAccessible + ) = 0; + + virtual ~IToolPanel() + { + } + }; + + typedef ::rtl::Reference< IToolPanel > PToolPanel; + + //==================================================================== + //= ToolPanelBase + //==================================================================== + /** base class for tool panel implementations, adding ref count implementation to the IToolPanel interface, + but still being abstract + */ + class SVT_DLLPUBLIC ToolPanelBase :public IToolPanel + ,public RefBase + ,public ::boost::noncopyable + { + protected: + ToolPanelBase(); + ~ToolPanelBase(); + + public: + DECLARE_IREFERENCE() + + private: + oslInterlockedCount m_refCount; + }; + +//........................................................................ +} // namespace svt +//........................................................................ + +#endif // SVT_TOOLPANEL_HXX diff --git a/svtools/inc/svtools/toolpanel/toolpaneldeck.hxx b/svtools/inc/svtools/toolpanel/toolpaneldeck.hxx new file mode 100755 index 000000000000..358464211255 --- /dev/null +++ b/svtools/inc/svtools/toolpanel/toolpaneldeck.hxx @@ -0,0 +1,192 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + +#ifndef SVT_TOOLPANELDECK_HXX +#define SVT_TOOLPANELDECK_HXX + +#include "svtools/svtdllapi.h" +#include "svtools/toolpanel/toolpanel.hxx" +#include "svtools/toolpanel/decklayouter.hxx" + +#include <vcl/ctrl.hxx> + +#include <boost/optional.hpp> +#include <memory> + +//........................................................................ +namespace svt +{ +//........................................................................ + + class ToolPanelCollection; + class ToolPanelDeck_Impl; + + //==================================================================== + //= IToolPanelDeckListener + //==================================================================== + class SAL_NO_VTABLE IToolPanelDeckListener + { + public: + /** called when a panel has been inserted into the deck + */ + virtual void PanelInserted( const PToolPanel& i_pPanel, const size_t i_nPosition ) = 0; + + /** called when a panel has been removed from the deck + */ + virtual void PanelRemoved( const size_t i_nPosition ) = 0; + + /** called when the active panel of the deck changed + */ + virtual void ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive ) = 0; + + /** called when a new layouter has been set at a tool panel deck. + + The method is called after the old layouter has been disposed (i.e. its Destroy method has been + invoked), and after the complete deck has been re-layouter. + */ + virtual void LayouterChanged( const PDeckLayouter& i_rNewLayouter ) = 0; + + /** called when the tool panel deck which the listener registered at is dying. The listener is required to + release all references to the deck then. + */ + virtual void Dying() = 0; + }; + + //==================================================================== + //= IToolPanelDeck + //==================================================================== + class SVT_DLLPUBLIC IToolPanelDeck + { + public: + /** returns the number of panels in the container + */ + virtual size_t GetPanelCount() const = 0; + + /** retrieves the panel with the given index. Invalid indexes will be reported via an assertion in the + non-product version, and silently ignored in the product version, with a NULL panel being returned. + */ + virtual PToolPanel GetPanel( const size_t i_nPos ) const = 0; + + /** returns the number of the currently active panel. + */ + virtual ::boost::optional< size_t > + GetActivePanel() const = 0; + + /** activates the panel with the given number. If the given number is larger or equal to the number of panels + in the deck, this will be reported via an assertion in non-product builds, and otherwise ignored. + @param i_rPanel + the number of the panel to activate. If this is not set, the currently active panel is de-activated, + and no new panel is activated at all. Whether or not this makes sense for your application is at + your own discretion. + */ + virtual void ActivatePanel( const ::boost::optional< size_t >& i_rPanel ) = 0; + + /** inserts a new panel into the container. NULL panels are not allowed, as are positions greater than the + current panel count. Violations of this will be reported via an assertion in the non-product version, and + silently ignored in the product version. + */ + virtual size_t InsertPanel( const PToolPanel& i_pPanel, const size_t i_nPosition ) = 0; + + /** removes a panel specified by its position. + + Note: It is the responsibility of the caller to ensure that the panel is destroyed appropriately. That is, + the tool panel deck will <em>not</em> invoke <member>IToolPanel::Dispose</member> on the removed panel. + The advantage is that the panel might be re-used later, with the disadvantage that the owner of the panel + deck must know whether Dispose must be invoked after removal, or whether the panel will properly + dispose itself when its ref count drops to 0. + */ + virtual PToolPanel RemovePanel( const size_t i_nPosition ) = 0; + + /** adds a new listener to be notified when the container content changes. The caller is responsible + for life time control, i.e. removing the listener before it actually dies. + */ + virtual void AddListener( IToolPanelDeckListener& i_rListener ) = 0; + + /** removes a container listener previously added via addListener. + */ + virtual void RemoveListener( IToolPanelDeckListener& i_rListener ) = 0; + }; + + //==================================================================== + //= ToolPanelDeck + //==================================================================== + class SVT_DLLPUBLIC ToolPanelDeck :public Control + ,public IToolPanelDeck + { + public: + ToolPanelDeck( Window& i_rParent, const WinBits i_nStyle ); + ~ToolPanelDeck(); + + // attributes + PDeckLayouter GetLayouter() const; + void SetLayouter( const PDeckLayouter& i_pNewLayouter ); + + /** returns the window which acts as anchor for the panel windows. + + This is a single dedicated window, which is passed to the IToolPanel::ActivatePanel method + whenever a panel is activated, to act as parent window for the panel's VCL-Window. + */ + Window& GetPanelWindowAnchor(); + + /** sets the window which should act as parent in the A11Y object hierarchy. + + Calling this method has no effect if CreateAccessible had always been called. + */ + void SetAccessibleParentWindow( Window* i_pAccessibleParent ); + Window* GetAccessibleParentWindow() const; + + // IToolPanelDeck + virtual size_t GetPanelCount() const; + virtual PToolPanel GetPanel( const size_t i_nPos ) const; + virtual ::boost::optional< size_t > + GetActivePanel() const; + virtual void ActivatePanel( const ::boost::optional< size_t >& i_rPanel ); + virtual size_t InsertPanel( const PToolPanel& i_pPanel, const size_t i_nPosition ); + virtual PToolPanel RemovePanel( const size_t i_nPosition ); + virtual void AddListener( IToolPanelDeckListener& i_rListener ); + virtual void RemoveListener( IToolPanelDeckListener& i_rListener ); + + protected: + // Window overridables + virtual void Resize(); + virtual long Notify( NotifyEvent& i_rNotifyEvent ); + virtual void GetFocus(); + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > + GetComponentInterface( BOOL i_bCreate ); + + private: + ::std::auto_ptr< ToolPanelDeck_Impl > m_pImpl; + + private: + using Window::GetAccessibleParentWindow; + }; + +//........................................................................ +} // namespace svt +//........................................................................ + +#endif // SVT_TOOLPANELDECK_HXX diff --git a/svtools/prj/build.lst b/svtools/prj/build.lst index 4b2cd9f9b26b..1fd12bb50b6c 100644 --- a/svtools/prj/build.lst +++ b/svtools/prj/build.lst @@ -21,9 +21,11 @@ st svtools\source\plugapp nmake - all st_papp st_inc NULL st svtools\source\svhtml nmake - all st_html st_inc NULL st svtools\source\svrtf nmake - all st_rtf st_inc NULL st svtools\source\table nmake - all st_table st_inc NULL +st svtools\source\toolpanel nmake - all st_toolpanel st_inc NULL st svtools\source\uno nmake - all st_uno st_inc NULL st svtools\source\urlobj nmake - all st__url st_inc NULL -st svtools\util nmake - all st_util st_svtgraphic st__brw st__ctr st_conf st_ctl st_dial st_edit st__misc st__url st_html st_papp st_rtf st_table st_uno st_vfilt st_vigif st_vixbm st_vixpm st_vjpeg st_vwmf st_svtjava NULL +st svtools\util nmake - all st_util st_svtgraphic st__brw st__ctr st_conf st_ctl st_dial st_edit st__misc st__url st_html st_papp st_rtf st_table st_toolpanel st_uno st_vfilt st_vigif st_vixbm st_vixpm st_vjpeg st_vwmf st_svtjava NULL st svtools\source\hatchwindow nmake - all st_hatchwin st_inc NULL st svtools\source\productregistration nmake - all st_prodreg st_util st_inc NULL st svtools\workben\unodialog nmake - all st_workben_udlg st_util NULL +st svtools\workben\toolpanel nmake - all st_workben_toolpanel st_util st_toolpanel NULL diff --git a/svtools/prj/d.lst b/svtools/prj/d.lst index 0a3ccd8a9819..fa3fbb2371dd 100644 --- a/svtools/prj/d.lst +++ b/svtools/prj/d.lst @@ -1,6 +1,7 @@ mkdir: %COMMON_DEST%\bin%_EXT%\hid mkdir: %COMMON_DEST%\res%_EXT% mkdir: %_DEST%\inc%_EXT%\svtools +mkdir: %_DEST%\inc%_EXT%\svtools\toolpanel ..\%COMMON_OUTDIR%\misc\*.hid %COMMON_DEST%\bin%_EXT%\hid\*.hid ..\%__SRC%\srs\ehdl.srs %_DEST%\res%_EXT%\svtools.srs @@ -29,6 +30,8 @@ mkdir: %_DEST%\inc%_EXT%\svtools ..\inc\*.h %_DEST%\inc%_EXT%\svtools\*.h ..\inc\*.hrc %_DEST%\inc%_EXT%\svtools\*.hrc +..\inc\svtools\toolpanel\*.* %_DEST%\inc%_EXT%\svtools\toolpanel\*.hrc + dos: sh -c "if test %OS% = MACOSX; then macosx-create-bundle %_DEST%\bin%_EXT%\bmp=%__PRJROOT%\%__SRC%\bin%_EXT%; fi" *.xml %_DEST%\xml%_EXT%\*.xml diff --git a/svtools/source/brwbox/brwbox3.cxx b/svtools/source/brwbox/brwbox3.cxx index 449d5642e034..102af1b6e1a1 100644 --- a/svtools/source/brwbox/brwbox3.cxx +++ b/svtools/source/brwbox/brwbox3.cxx @@ -542,7 +542,7 @@ BOOL BrowseBox::GetGlyphBoundRects( const Point& rOrigin, const String& rStr, in return Control::GetGlyphBoundRects( rOrigin, rStr, nIndex, nLen, nBase, rVector ); } // ----------------------------------------------------------------------------- -Rectangle BrowseBox::GetWindowExtentsRelative( Window *pRelativeWindow ) +Rectangle BrowseBox::GetWindowExtentsRelative( Window *pRelativeWindow ) const { return Control::GetWindowExtentsRelative( pRelativeWindow ); } diff --git a/svtools/source/contnr/svtabbx.cxx b/svtools/source/contnr/svtabbx.cxx index 9d4ad1ba15b5..9640ca7a310f 100644 --- a/svtools/source/contnr/svtabbx.cxx +++ b/svtools/source/contnr/svtabbx.cxx @@ -1232,7 +1232,7 @@ BOOL SvHeaderTabListBox::GetGlyphBoundRects( const Point& rOrigin, const String& return Control::GetGlyphBoundRects( rOrigin, rStr, nIndex, nLen, nBase, rVector ); } // ----------------------------------------------------------------------- -Rectangle SvHeaderTabListBox::GetWindowExtentsRelative( Window *pRelativeWindow ) +Rectangle SvHeaderTabListBox::GetWindowExtentsRelative( Window *pRelativeWindow ) const { return Control::GetWindowExtentsRelative( pRelativeWindow ); } diff --git a/svtools/source/misc/svtaccessiblefactory.cxx b/svtools/source/misc/svtaccessiblefactory.cxx index 1a8284642698..b20863db3208 100644..100755 --- a/svtools/source/misc/svtaccessiblefactory.cxx +++ b/svtools/source/misc/svtaccessiblefactory.cxx @@ -209,6 +209,24 @@ namespace svt { return NULL; } + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > + createAccessibleToolPanelDeck( + const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& /*i_rAccessibleParent*/, + ::svt::ToolPanelDeck& /*i_rPanelDeck*/ + ) + { + return NULL; + } + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > + createAccessibleToolPanelTabBar( + const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& /*i_rAccessibleParent*/, + ::svt::IToolPanelDeck& /*i_rPanelDeck*/, + ::svt::PanelTabBar& /*i_rTabBar*/ + ) + { + return NULL; + } }; //---------------------------------------------------------------- diff --git a/svtools/source/table/tablecontrol.cxx b/svtools/source/table/tablecontrol.cxx index 71c753d3ea86..262c32ae8ebc 100644 --- a/svtools/source/table/tablecontrol.cxx +++ b/svtools/source/table/tablecontrol.cxx @@ -394,7 +394,7 @@ void TableControl::FillAccessibleStateSet( } } -Rectangle TableControl::GetWindowExtentsRelative( Window *pRelativeWindow ) +Rectangle TableControl::GetWindowExtentsRelative( Window *pRelativeWindow ) const { return Control::GetWindowExtentsRelative( pRelativeWindow ); } diff --git a/svtools/source/toolpanel/dummypanel.cxx b/svtools/source/toolpanel/dummypanel.cxx new file mode 100644 index 000000000000..dae50723d4f1 --- /dev/null +++ b/svtools/source/toolpanel/dummypanel.cxx @@ -0,0 +1,101 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + +#include "precompiled_svtools.hxx" + +#include "dummypanel.hxx" + +//........................................................................ +namespace svt +{ +//........................................................................ + + using ::com::sun::star::uno::Reference; + using ::com::sun::star::accessibility::XAccessible; + + //==================================================================== + //= DummyPanel + //==================================================================== + //-------------------------------------------------------------------- + DummyPanel::DummyPanel() + { + } + + //-------------------------------------------------------------------- + DummyPanel::~DummyPanel() + { + } + + //-------------------------------------------------------------------- + IMPLEMENT_IREFERENCE( DummyPanel ) + + //-------------------------------------------------------------------- + void DummyPanel::Activate( Window& ) + { + } + + //-------------------------------------------------------------------- + void DummyPanel::Deactivate() + { + } + + //-------------------------------------------------------------------- + void DummyPanel::SetSizePixel( const Size& ) + { + } + + //-------------------------------------------------------------------- + ::rtl::OUString DummyPanel::GetDisplayName() const + { + return ::rtl::OUString(); + } + + //-------------------------------------------------------------------- + Image DummyPanel::GetImage() const + { + return Image(); + } + + //-------------------------------------------------------------------- + void DummyPanel::GrabFocus() + { + } + + //-------------------------------------------------------------------- + void DummyPanel::Dispose() + { + } + + //-------------------------------------------------------------------- + Reference< XAccessible > DummyPanel::CreatePanelAccessible( const Reference< XAccessible >& i_rParentAccessible ) + { + (void)i_rParentAccessible; + return NULL; + } + +//........................................................................ +} // namespace svt +//........................................................................ diff --git a/svtools/source/toolpanel/dummypanel.hxx b/svtools/source/toolpanel/dummypanel.hxx new file mode 100644 index 000000000000..b37e5cca19af --- /dev/null +++ b/svtools/source/toolpanel/dummypanel.hxx @@ -0,0 +1,69 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + +#ifndef DUMMYPANEL_HXX +#define DUMMYPANEL_HXX + +#include "svtools/toolpanel/toolpanel.hxx" +#include "svtools/toolpanel/refbase.hxx" + +//........................................................................ +namespace svt +{ +//........................................................................ + + //==================================================================== + //= DummyPanel + //==================================================================== + /// is a dummy implementation of the IToolPanel interface + class DummyPanel :public RefBase + ,public IToolPanel + { + public: + DummyPanel(); + ~DummyPanel(); + + // IToolPanel + virtual ::rtl::OUString GetDisplayName() const; + virtual Image GetImage() const; + virtual void Activate( Window& i_rParentWindow ); + virtual void Deactivate(); + virtual void SetSizePixel( const Size& i_rPanelWindowSize ); + virtual void GrabFocus(); + virtual void Dispose(); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > + CreatePanelAccessible( + const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& i_rParentAccessible + ); + + DECLARE_IREFERENCE() + }; + +//........................................................................ +} // namespace svt +//........................................................................ + +#endif // DUMMYPANEL_HXX diff --git a/svtools/source/toolpanel/makefile.mk b/svtools/source/toolpanel/makefile.mk new file mode 100755 index 000000000000..9d293b56d231 --- /dev/null +++ b/svtools/source/toolpanel/makefile.mk @@ -0,0 +1,65 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.16 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=svtools +TARGET=toolpanel + +# --- Settings ----------------------------------------------------- + +ENABLE_EXCEPTIONS=TRUE + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/svt.pmk + +# --- Files -------------------------------------------------------- + +SRS1NAME=$(TARGET) +SRC1FILES=\ + toolpanel.src + +SLOFILES=\ + $(SLO)$/dummypanel.obj \ + $(SLO)$/paneldecklisteners.obj \ + $(SLO)$/paneltabbar.obj \ + $(SLO)$/paneltabbarpeer.obj \ + $(SLO)$/refbase.obj \ + $(SLO)$/tabbargeometry.obj \ + $(SLO)$/tablayouter.obj \ + $(SLO)$/toolpanel.obj \ + $(SLO)$/toolpanelcollection.obj \ + $(SLO)$/toolpaneldeck.obj \ + $(SLO)$/toolpaneldeckpeer.obj \ + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/svtools/source/toolpanel/paneldecklisteners.cxx b/svtools/source/toolpanel/paneldecklisteners.cxx new file mode 100755 index 000000000000..32ba9b5c6a24 --- /dev/null +++ b/svtools/source/toolpanel/paneldecklisteners.cxx @@ -0,0 +1,137 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + +#include "precompiled_svtools.hxx" + +#include "paneldecklisteners.hxx" +#include "svtools/toolpanel/toolpaneldeck.hxx" + +//........................................................................ +namespace svt +{ +//........................................................................ + + //==================================================================== + //= PanelDeckListeners + //==================================================================== + //-------------------------------------------------------------------- + PanelDeckListeners::PanelDeckListeners() + { + } + + //-------------------------------------------------------------------- + PanelDeckListeners::~PanelDeckListeners() + { + } + + //-------------------------------------------------------------------- + void PanelDeckListeners::PanelInserted( const PToolPanel& i_pPanel, const size_t i_nPosition ) + { + ::std::vector< IToolPanelDeckListener* > aListeners( m_aListeners ); + for ( ::std::vector< IToolPanelDeckListener* >::const_iterator loop = aListeners.begin(); + loop != aListeners.end(); + ++loop + ) + { + (*loop)->PanelInserted( i_pPanel, i_nPosition ); + } + } + + //-------------------------------------------------------------------- + void PanelDeckListeners::PanelRemoved( const size_t i_nPosition ) + { + ::std::vector< IToolPanelDeckListener* > aListeners( m_aListeners ); + for ( ::std::vector< IToolPanelDeckListener* >::const_iterator loop = aListeners.begin(); + loop != aListeners.end(); + ++loop + ) + { + (*loop)->PanelRemoved( i_nPosition ); + } + } + + //-------------------------------------------------------------------- + void PanelDeckListeners::ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive ) + { + ::std::vector< IToolPanelDeckListener* > aListeners( m_aListeners ); + for ( ::std::vector< IToolPanelDeckListener* >::const_iterator loop = aListeners.begin(); + loop != aListeners.end(); + ++loop + ) + { + (*loop)->ActivePanelChanged( i_rOldActive, i_rNewActive ); + } + } + + //-------------------------------------------------------------------- + void PanelDeckListeners::LayouterChanged( const PDeckLayouter& i_rNewLayouter ) + { + ::std::vector< IToolPanelDeckListener* > aListeners( m_aListeners ); + for ( ::std::vector< IToolPanelDeckListener* >::const_iterator loop = aListeners.begin(); + loop != aListeners.end(); + ++loop + ) + { + (*loop)->LayouterChanged( i_rNewLayouter ); + } + } + + //-------------------------------------------------------------------- + void PanelDeckListeners::Dying() + { + while ( !m_aListeners.empty() ) + { + IToolPanelDeckListener* pListener( *m_aListeners.begin() ); + m_aListeners.erase( m_aListeners.begin() ); + pListener->Dying(); + } + } + + //-------------------------------------------------------------------- + void PanelDeckListeners::AddListener( IToolPanelDeckListener& i_rListener ) + { + m_aListeners.push_back( &i_rListener ); + } + + //-------------------------------------------------------------------- + void PanelDeckListeners::RemoveListener( IToolPanelDeckListener& i_rListener ) + { + for ( ::std::vector< IToolPanelDeckListener* >::iterator lookup = m_aListeners.begin(); + lookup != m_aListeners.end(); + ++lookup + ) + { + if ( *lookup == &i_rListener ) + { + m_aListeners.erase( lookup ); + return; + } + } + } + +//........................................................................ +} // namespace svt +//........................................................................ diff --git a/svtools/source/toolpanel/paneldecklisteners.hxx b/svtools/source/toolpanel/paneldecklisteners.hxx new file mode 100755 index 000000000000..bc7e2ae7db88 --- /dev/null +++ b/svtools/source/toolpanel/paneldecklisteners.hxx @@ -0,0 +1,72 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + +#ifndef PANELDECKLISTENERS_HXX +#define PANELDECKLISTENERS_HXX + +#include "svtools/toolpanel/toolpaneldeck.hxx" + +#include <boost/optional.hpp> +#include <vector> + +//........................................................................ +namespace svt +{ +//........................................................................ + + class IToolPanelDeckListener; + + //==================================================================== + //= PanelDeckListeners + //==================================================================== + /** implements a container for IToolPanelDeckListeners + */ + class PanelDeckListeners + { + public: + PanelDeckListeners(); + ~PanelDeckListeners(); + + // IToolPanelDeckListener equivalents, forward the events to all registered listeners + void PanelInserted( const PToolPanel& i_pPanel, const size_t i_nPosition ); + void PanelRemoved( const size_t i_nPosition ); + void ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive ); + void LayouterChanged( const PDeckLayouter& i_rNewLayouter ); + void Dying(); + + // listener maintainance + void AddListener( IToolPanelDeckListener& i_rListener ); + void RemoveListener( IToolPanelDeckListener& i_rListener ); + + private: + ::std::vector< IToolPanelDeckListener* > m_aListeners; + }; + +//........................................................................ +} // namespace svt +//........................................................................ + +#endif // PANELDECKLISTENERS_HXX diff --git a/svtools/source/toolpanel/paneltabbar.cxx b/svtools/source/toolpanel/paneltabbar.cxx new file mode 100755 index 000000000000..95e6caa311e4 --- /dev/null +++ b/svtools/source/toolpanel/paneltabbar.cxx @@ -0,0 +1,1356 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + +#include "precompiled_svtools.hxx" + +#include "svtools/toolpanel/paneltabbar.hxx" +#include "svtools/toolpanel/toolpaneldeck.hxx" +#include "svtools/svtdata.hxx" + +#include "tabitemdescriptor.hxx" +#include "paneltabbarpeer.hxx" +#include "tabbargeometry.hxx" + +#include <vcl/button.hxx> +#include <vcl/help.hxx> +#include <vcl/virdev.hxx> +#include <tools/diagnose_ex.h> +#include <svl/svtools.hrc> + +#include <boost/optional.hpp> +#include <vector> + +// space around an item +#define ITEM_OUTER_SPACE 2 * 3 +// spacing before and after an item's text +#define ITEM_TEXT_FLOW_SPACE 5 +// space between item icon and icon text +#define ITEM_ICON_TEXT_DISTANCE 4 + +//........................................................................ +namespace svt +{ +//........................................................................ + + using ::com::sun::star::uno::Reference; + using ::com::sun::star::awt::XWindowPeer; + + typedef sal_uInt16 ItemFlags; + + #define ITEM_STATE_NORMAL 0x00 + #define ITEM_STATE_ACTIVE 0x01 + #define ITEM_STATE_HOVERED 0x02 + #define ITEM_STATE_FOCUSED 0x04 + #define ITEM_POSITION_FIRST 0x08 + #define ITEM_POSITION_LAST 0x10 + + //================================================================================================================== + //= helper + //================================================================================================================== + namespace + { + ControlState lcl_ItemToControlState( const ItemFlags i_nItemFlags ) + { + ControlState nState = CTRL_STATE_ENABLED; + if ( i_nItemFlags & ITEM_STATE_FOCUSED ) nState |= CTRL_STATE_FOCUSED | CTRL_STATE_PRESSED; + if ( i_nItemFlags & ITEM_STATE_HOVERED ) nState |= CTRL_STATE_ROLLOVER; + if ( i_nItemFlags & ITEM_STATE_ACTIVE ) nState |= CTRL_STATE_SELECTED; + return nState; + } + } + + //================================================================================================================== + //= ITabBarRenderer + //================================================================================================================== + class SAL_NO_VTABLE ITabBarRenderer + { + public: + /** fills the background of our target device + */ + virtual void renderBackground() const = 0; + virtual Rectangle calculateDecorations( const Rectangle& i_rContentArea, const ItemFlags i_nItemFlags ) const = 0; + virtual void preRenderItem( const Rectangle& i_rContentRect, const ItemFlags i_nItemFlags ) const = 0; + virtual void postRenderItem( Window& i_rActualWindow, const Rectangle& i_rItemRect, const ItemFlags i_nItemFlags ) const = 0; + + // TODO: postRenderItem takes the "real" window, i.e. effectively the tab bar. This is because + // DrawSelectionBackground needs to be applied after everything else is painted, and is available at the Window + // class, but not at the OutputDevice. This makes the API somewhat weird, as we're now mixing operations on the + // target device, done in a normalized geometry, with operations on the window, done in a transformed geometry. + // So, we should get rid of postRenderItem completely. + }; + typedef ::boost::shared_ptr< ITabBarRenderer > PTabBarRenderer; + + //================================================================================================================== + //= VCLItemRenderer - declaration + //================================================================================================================== + class VCLItemRenderer : public ITabBarRenderer + { + public: + VCLItemRenderer( OutputDevice& i_rTargetDevice ) + :m_rTargetDevice( i_rTargetDevice ) + { + } + + // ITabBarRenderer + virtual void renderBackground() const; + virtual Rectangle calculateDecorations( const Rectangle& i_rContentArea, const ItemFlags i_nItemFlags ) const; + virtual void preRenderItem( const Rectangle& i_rContentRect, const ItemFlags i_nItemFlags ) const; + virtual void postRenderItem( Window& i_rActualWindow, const Rectangle& i_rItemRect, const ItemFlags i_nItemFlags ) const; + + protected: + OutputDevice& getTargetDevice() const { return m_rTargetDevice; } + + private: + OutputDevice& m_rTargetDevice; + }; + + //================================================================================================================== + //= VCLItemRenderer - implementation + //================================================================================================================== + //------------------------------------------------------------------------------------------------------------------ + void VCLItemRenderer::renderBackground() const + { + getTargetDevice().DrawRect( Rectangle( Point(), getTargetDevice().GetOutputSizePixel() ) ); + } + + //------------------------------------------------------------------------------------------------------------------ + Rectangle VCLItemRenderer::calculateDecorations( const Rectangle& i_rContentArea, const ItemFlags i_nItemFlags ) const + { + (void)i_nItemFlags; + // no decorations at all + return i_rContentArea; + } + + //------------------------------------------------------------------------------------------------------------------ + void VCLItemRenderer::preRenderItem( const Rectangle& i_rContentRect, const ItemFlags i_nItemFlags ) const + { + (void)i_rContentRect; + (void)i_nItemFlags; + } + + //------------------------------------------------------------------------------------------------------------------ + void VCLItemRenderer::postRenderItem( Window& i_rActualWindow, const Rectangle& i_rItemRect, const ItemFlags i_nItemFlags ) const + { + const bool bActive = ( ( i_nItemFlags & ITEM_STATE_ACTIVE ) != 0 ); + const bool bHovered = ( ( i_nItemFlags & ITEM_STATE_HOVERED ) != 0 ); + const bool bFocused = ( ( i_nItemFlags & ITEM_STATE_FOCUSED ) != 0 ); + if ( bActive || bHovered || bFocused ) + { + Rectangle aSelectionRect( i_rItemRect ); + aSelectionRect.Left() += ITEM_OUTER_SPACE / 2; + aSelectionRect.Top() += ITEM_OUTER_SPACE / 2; + aSelectionRect.Right() -= ITEM_OUTER_SPACE / 2; + aSelectionRect.Bottom() -= ITEM_OUTER_SPACE / 2; + i_rActualWindow.DrawSelectionBackground( + aSelectionRect, + ( bHovered || bFocused ) ? ( bActive ? 1 : 2 ) : 0 /* hilight */, + bActive /* check */, + TRUE /* border */, + FALSE /* ext border only */, + 0 /* corner radius */, + NULL, + NULL + ); + } + } + + //================================================================================================================== + //= NWFToolboxItemRenderer - declaration + //================================================================================================================== + class NWFToolboxItemRenderer : public ITabBarRenderer + { + public: + NWFToolboxItemRenderer( OutputDevice& i_rTargetDevice ) + :m_rTargetDevice( i_rTargetDevice ) + { + } + + // ITabBarRenderer + virtual void renderBackground() const; + virtual Rectangle calculateDecorations( const Rectangle& i_rContentArea, const ItemFlags i_nItemFlags ) const; + virtual void preRenderItem( const Rectangle& i_rContentRect, const ItemFlags i_nItemFlags ) const; + virtual void postRenderItem( Window& i_rActualWindow, const Rectangle& i_rItemRect, const ItemFlags i_nItemFlags ) const; + + protected: + OutputDevice& getTargetDevice() const { return m_rTargetDevice; } + + private: + OutputDevice& m_rTargetDevice; + }; + + //================================================================================================================== + //= NWFToolboxItemRenderer - implementation + //================================================================================================================== + //------------------------------------------------------------------------------------------------------------------ + void NWFToolboxItemRenderer::renderBackground() const + { + getTargetDevice().DrawRect( Rectangle( Point(), getTargetDevice().GetOutputSizePixel() ) ); + } + + //------------------------------------------------------------------------------------------------------------------ + Rectangle NWFToolboxItemRenderer::calculateDecorations( const Rectangle& i_rContentArea, const ItemFlags i_nItemFlags ) const + { + // don't ask GetNativeControlRegion, this will not deliver proper results in all cases. + // Instead, simply assume that both the content and the bounding region are the same. +// const ControlState nState( lcl_ItemToControlState( i_nItemFlags ); +// const ImplControlValue aControlValue; +// bool bNativeOK = m_rTargetWindow.GetNativeControlRegion( +// CTRL_TOOLBAR, PART_BUTTON, +// i_rContentArea, nState, +// aControlValue, ::rtl::OUString(), +// aBoundingRegion, aContentRegion +// ); + (void)i_nItemFlags; + return Rectangle( + Point( i_rContentArea.Left() - 1, i_rContentArea.Top() - 1 ), + Size( i_rContentArea.GetWidth() + 2, i_rContentArea.GetHeight() + 2 ) + ); + } + + //------------------------------------------------------------------------------------------------------------------ + void NWFToolboxItemRenderer::preRenderItem( const Rectangle& i_rContentRect, const ItemFlags i_nItemFlags ) const + { + const ControlState nState = lcl_ItemToControlState( i_nItemFlags ); + + ImplControlValue aControlValue; + aControlValue.setTristateVal( ( i_nItemFlags & ITEM_STATE_ACTIVE ) ? BUTTONVALUE_ON : BUTTONVALUE_OFF ); + + bool bNativeOK = getTargetDevice().DrawNativeControl( CTRL_TOOLBAR, PART_BUTTON, i_rContentRect, nState, aControlValue, rtl::OUString() ); + (void)bNativeOK; + OSL_ENSURE( bNativeOK, "NWFToolboxItemRenderer::preRenderItem: inconsistent NWF implementation!" ); + // IsNativeControlSupported returned true, previously, otherwise we would not be here ... + } + + //------------------------------------------------------------------------------------------------------------------ + void NWFToolboxItemRenderer::postRenderItem( Window& i_rActualWindow, const Rectangle& i_rItemRect, const ItemFlags i_nItemFlags ) const + { + (void)i_rActualWindow; + (void)i_rItemRect; + (void)i_nItemFlags; + } + + //================================================================================================================== + //= NWFTabItemRenderer - declaration + //================================================================================================================== + class NWFTabItemRenderer : public ITabBarRenderer + { + public: + NWFTabItemRenderer( OutputDevice& i_rTargetDevice ) + :m_rTargetDevice( i_rTargetDevice ) + { + } + + // ITabBarRenderer + virtual void renderBackground() const; + virtual Rectangle calculateDecorations( const Rectangle& i_rContentArea, const ItemFlags i_nItemFlags ) const; + virtual void preRenderItem( const Rectangle& i_rContentRect, const ItemFlags i_nItemFlags ) const; + virtual void postRenderItem( Window& i_rActualWindow, const Rectangle& i_rItemRect, const ItemFlags i_nItemFlags ) const; + + protected: + OutputDevice& getTargetDevice() const { return m_rTargetDevice; } + + private: + OutputDevice& m_rTargetDevice; + }; + + //================================================================================================================== + //= NWFTabItemRenderer - implementation + //================================================================================================================== + //------------------------------------------------------------------------------------------------------------------ + void NWFTabItemRenderer::renderBackground() const + { + Rectangle aBackground( Point(), getTargetDevice().GetOutputSizePixel() ); + getTargetDevice().DrawRect( aBackground ); + + aBackground.Top() = aBackground.Bottom(); + getTargetDevice().DrawNativeControl( CTRL_TAB_PANE, PART_ENTIRE_CONTROL, aBackground, + CTRL_STATE_ENABLED, ImplControlValue(), ::rtl::OUString() ); + } + + //------------------------------------------------------------------------------------------------------------------ + Rectangle NWFTabItemRenderer::calculateDecorations( const Rectangle& i_rContentArea, const ItemFlags i_nItemFlags ) const + { + const ControlState nState( lcl_ItemToControlState( i_nItemFlags ) ); + + TabitemValue tiValue; + ImplControlValue aControlValue( (void*)(&tiValue) ); + + Region aBoundingRegion, aContentRegion; + bool bNativeOK = getTargetDevice().GetNativeControlRegion( + CTRL_TAB_ITEM, PART_ENTIRE_CONTROL, + i_rContentArea, nState, + aControlValue, ::rtl::OUString(), + aBoundingRegion, aContentRegion + ); + (void)bNativeOK; + OSL_ENSURE( bNativeOK, "NWFTabItemRenderer::calculateDecorations: GetNativeControlRegion not implemented for CTRL_TAB_ITEM?!" ); + + return aBoundingRegion.GetBoundRect(); + } + + //------------------------------------------------------------------------------------------------------------------ + void NWFTabItemRenderer::preRenderItem( const Rectangle& i_rContentRect, const ItemFlags i_nItemFlags ) const + { + const ControlState nState = lcl_ItemToControlState( i_nItemFlags ); + + TabitemValue tiValue; + if ( i_nItemFlags & ITEM_POSITION_FIRST ) + tiValue.mnAlignment |= TABITEM_FIRST_IN_GROUP; + if ( i_nItemFlags & ITEM_POSITION_LAST ) + tiValue.mnAlignment |= TABITEM_LAST_IN_GROUP; + + ImplControlValue aControlValue( (void *)(&tiValue) ); + + bool bNativeOK = getTargetDevice().DrawNativeControl( CTRL_TAB_ITEM, PART_ENTIRE_CONTROL, i_rContentRect, nState, aControlValue, rtl::OUString() ); + (void)bNativeOK; + OSL_ENSURE( bNativeOK, "NWFTabItemRenderer::preRenderItem: inconsistent NWF implementation!" ); + // IsNativeControlSupported returned true, previously, otherwise we would not be here ... + } + + //------------------------------------------------------------------------------------------------------------------ + void NWFTabItemRenderer::postRenderItem( Window& i_rActualWindow, const Rectangle& i_rItemRect, const ItemFlags i_nItemFlags ) const + { + (void)i_rActualWindow; + (void)i_rItemRect; + (void)i_nItemFlags; + } + + //================================================================================================================== + //= PanelTabBar_Impl + //================================================================================================================== + class PanelTabBar_Impl : public IToolPanelDeckListener + { + public: + PanelTabBar_Impl( PanelTabBar& i_rTabBar, IToolPanelDeck& i_rPanelDeck, const TabAlignment i_eAlignment, const TabItemContent i_eItemContent ); + + ~PanelTabBar_Impl() + { + m_rPanelDeck.RemoveListener( *this ); + } + + // IToolPanelDeckListener + virtual void PanelInserted( const PToolPanel& i_pPanel, const size_t i_nPosition ) + { + (void)i_pPanel; + (void)i_nPosition; + m_bItemsDirty = true; + m_rTabBar.Invalidate(); + + Relayout(); + } + + virtual void PanelRemoved( const size_t i_nPosition ) + { + m_bItemsDirty = true; + m_rTabBar.Invalidate(); + + if ( i_nPosition < m_nScrollPosition ) + --m_nScrollPosition; + + Relayout(); + } + + virtual void ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive ); + virtual void LayouterChanged( const PDeckLayouter& i_rNewLayouter ); + virtual void Dying(); + + void UpdateScrollButtons() + { + m_aScrollBack.Enable( m_nScrollPosition > 0 ); + m_aScrollForward.Enable( m_nScrollPosition < m_aItems.size() - 1 ); + } + + void Relayout(); + void EnsureItemsCache(); + ::boost::optional< size_t > FindItemForPoint( const Point& i_rPoint ) const; + void DrawItem( const size_t i_nItemIndex, const Rectangle& i_rBoundaries ) const; + void InvalidateItem( const size_t i_nItemIndex, const ItemFlags i_nAdditionalItemFlags = 0 ) const; + void CopyFromRenderDevice( const Rectangle& i_rLogicalRect ) const; + Rectangle GetActualLogicalItemRect( const Rectangle& i_rLogicalItemRect ) const; + Rectangle GetItemScreenRect( const size_t i_nItemPos ) const; + + void FocusItem( const ::boost::optional< size_t >& i_rItemPos ); + + inline bool IsVertical() const + { + return ( ( m_eTabAlignment == TABS_LEFT ) + || ( m_eTabAlignment == TABS_RIGHT ) + ); + } + + protected: + DECL_LINK( OnScroll, const PushButton* ); + + void impl_calcItemRects(); + Size impl_calculateItemContentSize( const PToolPanel& i_pPanel, const TabItemContent i_eItemContent ) const; + void impl_renderItemContent( const PToolPanel& i_pPanel, const Rectangle& i_rContentArea, const TabItemContent i_eItemContent ) const; + ItemFlags impl_getItemFlags( const size_t i_nItemIndex ) const; + + public: + PanelTabBar& m_rTabBar; + TabBarGeometry m_aGeometry; + NormalizedArea m_aNormalizer; + TabAlignment m_eTabAlignment; + IToolPanelDeck& m_rPanelDeck; + + VirtualDevice m_aRenderDevice; + PTabBarRenderer m_pRenderer; + + ::boost::optional< size_t > m_aHoveredItem; + ::boost::optional< size_t > m_aFocusedItem; + bool m_bMouseButtonDown; + + ItemDescriptors m_aItems; + bool m_bItemsDirty; + + PushButton m_aScrollBack; + PushButton m_aScrollForward; + + size_t m_nScrollPosition; + }; + + //================================================================================================================== + //= helper + //================================================================================================================== + namespace + { + //-------------------------------------------------------------------------------------------------------------- + #if OSL_DEBUG_LEVEL > 0 + static void lcl_checkConsistency( const PanelTabBar_Impl& i_rImpl ) + { + if ( !i_rImpl.m_bItemsDirty ) + { + if ( i_rImpl.m_rPanelDeck.GetPanelCount() != i_rImpl.m_aItems.size() ) + { + OSL_ENSURE( false, "lcl_checkConsistency: inconsistent array sizes!" ); + return; + } + for ( size_t i = 0; i < i_rImpl.m_rPanelDeck.GetPanelCount(); ++i ) + { + if ( i_rImpl.m_rPanelDeck.GetPanel( i ).get() != i_rImpl.m_aItems[i].pPanel.get() ) + { + OSL_ENSURE( false, "lcl_checkConsistency: array elements are inconsistent!" ); + return; + } + } + } + } + + #define DBG_CHECK( data ) \ + lcl_checkConsistency( data ); + #else + #define DBG_CHECK( data ) \ + (void)data; + #endif + + //-------------------------------------------------------------------------------------------------------------- + class ClipItemRegion + { + public: + ClipItemRegion( const PanelTabBar_Impl& i_rImpl ) + :m_rDevice( i_rImpl.m_rTabBar ) + { + m_rDevice.Push( PUSH_CLIPREGION ); + m_rDevice.SetClipRegion( i_rImpl.m_aNormalizer.getTransformed( i_rImpl.m_aGeometry.getItemsRect(), i_rImpl.m_eTabAlignment ) ); + } + + ~ClipItemRegion() + { + m_rDevice.Pop(); + } + + private: + OutputDevice& m_rDevice; + }; + } + + //================================================================================================================== + //= PanelTabBar_Impl - implementation + //================================================================================================================== + //------------------------------------------------------------------------------------------------------------------ + PanelTabBar_Impl::PanelTabBar_Impl( PanelTabBar& i_rTabBar, IToolPanelDeck& i_rPanelDeck, const TabAlignment i_eAlignment, const TabItemContent i_eItemContent ) + :m_rTabBar( i_rTabBar ) + ,m_aGeometry( i_eItemContent ) + ,m_aNormalizer() + ,m_eTabAlignment( i_eAlignment ) + ,m_rPanelDeck( i_rPanelDeck ) + ,m_aRenderDevice( i_rTabBar ) + ,m_pRenderer() + ,m_aHoveredItem() + ,m_aFocusedItem() + ,m_bMouseButtonDown( false ) + ,m_aItems() + ,m_bItemsDirty( true ) + ,m_aScrollBack( &i_rTabBar, WB_BEVELBUTTON ) + ,m_aScrollForward( &i_rTabBar, WB_BEVELBUTTON ) + ,m_nScrollPosition( 0 ) + { +#ifdef WNT + if ( m_aRenderDevice.IsNativeControlSupported( CTRL_TAB_ITEM, PART_ENTIRE_CONTROL ) ) + // this mode requires the NWF framework to be able to render those items onto a virtual + // device. For some frameworks (some GTK themes, in particular), this is known to fail. + // So, be on the safe side for the moment. + m_pRenderer.reset( new NWFTabItemRenderer( m_aRenderDevice ) ); + else +#endif + if ( m_aRenderDevice.IsNativeControlSupported( CTRL_TOOLBAR, PART_BUTTON ) ) + m_pRenderer.reset( new NWFToolboxItemRenderer( m_aRenderDevice ) ); + else + m_pRenderer.reset( new VCLItemRenderer( m_aRenderDevice ) ); + + m_aRenderDevice.SetLineColor(); + + m_rPanelDeck.AddListener( *this ); + + m_aScrollBack.SetSymbol( IsVertical() ? SYMBOL_ARROW_UP : SYMBOL_ARROW_LEFT ); + m_aScrollBack.Show(); + m_aScrollBack.SetClickHdl( LINK( this, PanelTabBar_Impl, OnScroll ) ); + m_aScrollBack.SetAccessibleDescription( String( SvtResId( STR_SVT_ACC_BEGIN + 0 ) ) ); + m_aScrollBack.SetAccessibleName( m_aScrollBack.GetAccessibleDescription() ); + + m_aScrollForward.SetSymbol( IsVertical() ? SYMBOL_ARROW_DOWN : SYMBOL_ARROW_RIGHT ); + m_aScrollForward.Show(); + m_aScrollForward.SetClickHdl( LINK( this, PanelTabBar_Impl, OnScroll ) ); + m_aScrollForward.SetAccessibleDescription( String( SvtResId( STR_SVT_ACC_BEGIN + 1 ) ) ); + m_aScrollForward.SetAccessibleName( m_aScrollForward.GetAccessibleDescription() ); + } + + //------------------------------------------------------------------------------------------------------------------ + void PanelTabBar_Impl::impl_calcItemRects() + { + m_aItems.resize(0); + + Point aCompletePos( m_aGeometry.getFirstItemPosition() ); + Point aIconOnlyPos( aCompletePos ); + Point aTextOnlyPos( aCompletePos ); + + for ( size_t i = 0; + i < m_rPanelDeck.GetPanelCount(); + ++i + ) + { + PToolPanel pPanel( m_rPanelDeck.GetPanel( i ) ); + + ItemDescriptor aItem; + aItem.pPanel = pPanel; + + Rectangle aContentArea; + + const Size aCompleteSize( impl_calculateItemContentSize( pPanel, TABITEM_IMAGE_AND_TEXT ) ); + const Size aIconOnlySize( impl_calculateItemContentSize( pPanel, TABITEM_IMAGE_ONLY ) ); + const Size aTextOnlySize( impl_calculateItemContentSize( pPanel, TABITEM_TEXT_ONLY ) ); + + // TODO: have one method calculating all sizes? + + // remember the three areas + aItem.aCompleteArea = Rectangle( aCompletePos, aCompleteSize ); + aItem.aIconOnlyArea = Rectangle( aIconOnlyPos, aIconOnlySize ); + aItem.aTextOnlyArea = Rectangle( aTextOnlyPos, aTextOnlySize ); + + m_aItems.push_back( aItem ); + + aCompletePos = aItem.aCompleteArea.TopRight(); + aIconOnlyPos = aItem.aIconOnlyArea.TopRight(); + aTextOnlyPos = aItem.aTextOnlyArea.TopRight(); + } + + m_bItemsDirty = false; + } + + //------------------------------------------------------------------------------------------------------------------ + Size PanelTabBar_Impl::impl_calculateItemContentSize( const PToolPanel& i_pPanel, const TabItemContent i_eItemContent ) const + { + // calculate the size needed for the content + OSL_ENSURE( i_eItemContent != TABITEM_AUTO, "PanelTabBar_Impl::impl_calculateItemContentSize: illegal TabItemContent value!" ); + + const Image aImage( i_pPanel->GetImage() ); + const bool bUseImage = !!aImage && ( i_eItemContent != TABITEM_TEXT_ONLY ); + + const ::rtl::OUString sItemText( i_pPanel->GetDisplayName() ); + const bool bUseText = ( sItemText.getLength() != 0 ) && ( i_eItemContent != TABITEM_IMAGE_ONLY ); + + Size aItemContentSize; + if ( bUseImage ) + { + aItemContentSize = aImage.GetSizePixel(); + } + + if ( bUseText ) + { + if ( bUseImage ) + aItemContentSize.Width() += ITEM_ICON_TEXT_DISTANCE; + + // add space for text + const Size aTextSize( m_rTabBar.GetCtrlTextWidth( sItemText ), m_rTabBar.GetTextHeight() ); + aItemContentSize.Width() += aTextSize.Width(); + aItemContentSize.Height() = ::std::max( aItemContentSize.Height(), aTextSize.Height() ); + + aItemContentSize.Width() += 2 * ITEM_TEXT_FLOW_SPACE; + } + + if ( !bUseImage && !bUseText ) + { + // have a minimal size - this is pure heuristics, but if it doesn't suit your needs, then give your panels + // a name and or image! :) + aItemContentSize = Size( 16, 16 ); + } + + aItemContentSize.Width() += 2 * ITEM_OUTER_SPACE; + aItemContentSize.Height() += 2 * ITEM_OUTER_SPACE; + + return aItemContentSize; + } + + //------------------------------------------------------------------------------------------------------------------ + void PanelTabBar_Impl::impl_renderItemContent( const PToolPanel& i_pPanel, const Rectangle& i_rContentArea, const TabItemContent i_eItemContent ) const + { + OSL_ENSURE( i_eItemContent != TABITEM_AUTO, "PanelTabBar_Impl::impl_renderItemContent: illegal TabItemContent value!" ); + + Rectangle aRenderArea( i_rContentArea ); + if ( IsVertical() ) + { + aRenderArea.Top() += ITEM_OUTER_SPACE; + } + else + { + aRenderArea.Left() += ITEM_OUTER_SPACE; + } + + // draw the image + const Image aItemImage( i_pPanel->GetImage() ); + const Size aImageSize( aItemImage.GetSizePixel() ); + const bool bUseImage = !!aItemImage && ( i_eItemContent != TABITEM_TEXT_ONLY ); + + if ( bUseImage ) + { + Point aImagePos; + if ( IsVertical() ) + { + aImagePos.X() = aRenderArea.Left() + ( aRenderArea.GetWidth() - aImageSize.Width() ) / 2; + aImagePos.Y() = aRenderArea.Top(); + } + else + { + aImagePos.X() = aRenderArea.Left(); + aImagePos.Y() = aRenderArea.Top() + ( aRenderArea.GetHeight() - aImageSize.Height() ) / 2; + } + m_rTabBar.DrawImage( aImagePos, aItemImage ); + } + + const ::rtl::OUString sItemText( i_pPanel->GetDisplayName() ); + const bool bUseText = ( sItemText.getLength() != 0 ) && ( i_eItemContent != TABITEM_IMAGE_ONLY ); + + if ( bUseText ) + { + if ( IsVertical() ) + { + if ( bUseImage ) + aRenderArea.Top() += aImageSize.Height() + ITEM_ICON_TEXT_DISTANCE; + aRenderArea.Top() += ITEM_TEXT_FLOW_SPACE; + } + else + { + if ( bUseImage ) + aRenderArea.Left() += aImageSize.Width() + ITEM_ICON_TEXT_DISTANCE; + aRenderArea.Left() += ITEM_TEXT_FLOW_SPACE; + } + + // draw the text + const Size aTextSize( m_rTabBar.GetCtrlTextWidth( sItemText ), m_rTabBar.GetTextHeight() ); + Point aTextPos( aRenderArea.TopLeft() ); + if ( IsVertical() ) + { + m_rTabBar.Push( PUSH_FONT ); + + Font aFont( m_rTabBar.GetFont() ); + aFont.SetOrientation( 2700 ); + aFont.SetVertical( TRUE ); + m_rTabBar.SetFont( aFont ); + + aTextPos.X() += aTextSize.Height(); + aTextPos.X() += ( aRenderArea.GetWidth() - aTextSize.Height() ) / 2; + } + else + { + aTextPos.Y() += ( aRenderArea.GetHeight() - aTextSize.Height() ) / 2; + } + + m_rTabBar.DrawText( aTextPos, sItemText ); + + if ( IsVertical() ) + { + m_rTabBar.Pop(); + } + } + } + + //------------------------------------------------------------------------------------------------------------------ + void PanelTabBar_Impl::CopyFromRenderDevice( const Rectangle& i_rLogicalRect ) const + { + BitmapEx aBitmap( m_aRenderDevice.GetBitmapEx( + i_rLogicalRect.TopLeft(), + Size( + i_rLogicalRect.GetSize().Width(), + i_rLogicalRect.GetSize().Height() + ) + ) ); + if ( IsVertical() ) + { + aBitmap.Rotate( 2700, COL_BLACK ); + if ( m_eTabAlignment == TABS_LEFT ) + aBitmap.Mirror( BMP_MIRROR_HORZ ); + } + else if ( m_eTabAlignment == TABS_BOTTOM ) + { + aBitmap.Mirror( BMP_MIRROR_VERT ); + } + + const Rectangle aActualRect( m_aNormalizer.getTransformed( i_rLogicalRect, m_eTabAlignment ) ); + m_rTabBar.DrawBitmapEx( aActualRect.TopLeft(), aBitmap ); + } + + //------------------------------------------------------------------------------------------------------------------ + void PanelTabBar_Impl::InvalidateItem( const size_t i_nItemIndex, const ItemFlags i_nAdditionalItemFlags ) const + { + const ItemDescriptor& rItem( m_aItems[ i_nItemIndex ] ); + const ItemFlags nItemFlags( impl_getItemFlags( i_nItemIndex ) | i_nAdditionalItemFlags ); + + const Rectangle aNormalizedContent( GetActualLogicalItemRect( rItem.GetCurrentRect() ) ); + const Rectangle aNormalizedBounds( m_pRenderer->calculateDecorations( aNormalizedContent, nItemFlags ) ); + + const Rectangle aActualBounds = m_aNormalizer.getTransformed( aNormalizedBounds, m_eTabAlignment ); + m_rTabBar.Invalidate( aActualBounds ); + } + + //------------------------------------------------------------------------------------------------------------------ + ItemFlags PanelTabBar_Impl::impl_getItemFlags( const size_t i_nItemIndex ) const + { + ItemFlags nItemFlags( ITEM_STATE_NORMAL ); + if ( m_aHoveredItem == i_nItemIndex ) + { + nItemFlags |= ITEM_STATE_HOVERED; + if ( m_bMouseButtonDown ) + nItemFlags |= ITEM_STATE_ACTIVE; + } + + if ( m_rPanelDeck.GetActivePanel() == i_nItemIndex ) + nItemFlags |= ITEM_STATE_ACTIVE; + + if ( m_aFocusedItem == i_nItemIndex ) + nItemFlags |= ITEM_STATE_FOCUSED; + + if ( 0 == i_nItemIndex ) + nItemFlags |= ITEM_POSITION_FIRST; + + if ( m_rPanelDeck.GetPanelCount() - 1 == i_nItemIndex ) + nItemFlags |= ITEM_POSITION_LAST; + + return nItemFlags; + } + + //------------------------------------------------------------------------------------------------------------------ + void PanelTabBar_Impl::DrawItem( const size_t i_nItemIndex, const Rectangle& i_rBoundaries ) const + { + const ItemDescriptor& rItem( m_aItems[ i_nItemIndex ] ); + const ItemFlags nItemFlags( impl_getItemFlags( i_nItemIndex ) ); + + // the normalized bounding and content rect + const Rectangle aNormalizedContent( GetActualLogicalItemRect( rItem.GetCurrentRect() ) ); + const Rectangle aNormalizedBounds( m_pRenderer->calculateDecorations( aNormalizedContent, nItemFlags ) ); + + // check whether the item actually overlaps with the painting area + if ( !i_rBoundaries.IsEmpty() ) + { + const Rectangle aItemRect( GetActualLogicalItemRect( rItem.GetCurrentRect() ) ); + if ( !aItemRect.IsOver( i_rBoundaries ) ) + return; + } + + m_rTabBar.SetUpdateMode( FALSE ); + + // the aligned bounding and content rect + const Rectangle aActualBounds = m_aNormalizer.getTransformed( aNormalizedBounds, m_eTabAlignment ); + const Rectangle aActualContent = m_aNormalizer.getTransformed( aNormalizedContent, m_eTabAlignment ); + + // render item "background" layer + m_pRenderer->preRenderItem( aNormalizedContent, nItemFlags ); + + // copy from the virtual device to ourself + CopyFromRenderDevice( aNormalizedBounds ); + + // render the actual item content + impl_renderItemContent( rItem.pPanel, aActualContent, rItem.eContent ); + + // render item "foreground" layer + m_pRenderer->postRenderItem( m_rTabBar, aActualBounds, nItemFlags ); + + m_rTabBar.SetUpdateMode( TRUE ); + } + + //------------------------------------------------------------------------------------------------------------------ + void PanelTabBar_Impl::EnsureItemsCache() + { + if ( m_bItemsDirty == false ) + { + DBG_CHECK( *this ); + return; + } + impl_calcItemRects(); + OSL_POSTCOND( m_bItemsDirty == false, "PanelTabBar_Impl::EnsureItemsCache: cache still dirty!" ); + DBG_CHECK( *this ); + } + + //------------------------------------------------------------------------------------------------------------------ + void PanelTabBar_Impl::Relayout() + { + EnsureItemsCache(); + + const Size aOutputSize( m_rTabBar.GetOutputSizePixel() ); + m_aNormalizer = NormalizedArea( Rectangle( Point(), aOutputSize ), IsVertical() ); + const Size aLogicalOutputSize( m_aNormalizer.getReferenceSize() ); + + // forward actual output size to our render device + m_aRenderDevice.SetOutputSizePixel( aLogicalOutputSize ); + + // re-calculate the size of the scroll buttons and of the items + m_aGeometry.relayout( aLogicalOutputSize, m_aItems ); + + if ( m_aGeometry.getButtonBackRect().IsEmpty() ) + { + m_aScrollBack.Hide(); + } + else + { + const Rectangle aButtonBack( m_aNormalizer.getTransformed( m_aGeometry.getButtonBackRect(), m_eTabAlignment ) ); + m_aScrollBack.SetPosSizePixel( aButtonBack.TopLeft(), aButtonBack.GetSize() ); + m_aScrollBack.Show(); + } + + if ( m_aGeometry.getButtonForwardRect().IsEmpty() ) + { + m_aScrollForward.Hide(); + } + else + { + const Rectangle aButtonForward( m_aNormalizer.getTransformed( m_aGeometry.getButtonForwardRect(), m_eTabAlignment ) ); + m_aScrollForward.SetPosSizePixel( aButtonForward.TopLeft(), aButtonForward.GetSize() ); + m_aScrollForward.Show(); + } + + UpdateScrollButtons(); + } + + //------------------------------------------------------------------------------------------------------------------ + ::boost::optional< size_t > PanelTabBar_Impl::FindItemForPoint( const Point& i_rPoint ) const + { + Point aPoint( IsVertical() ? i_rPoint.Y() : i_rPoint.X(), IsVertical() ? i_rPoint.X() : i_rPoint.Y() ); + + if ( !m_aGeometry.getItemsRect().IsInside( aPoint ) ) + return ::boost::optional< size_t >(); + + size_t i=0; + for ( ItemDescriptors::const_iterator item = m_aItems.begin(); + item != m_aItems.end(); + ++item, ++i + ) + { + Rectangle aItemRect( GetActualLogicalItemRect( item->GetCurrentRect() ) ); + if ( aItemRect.IsInside( aPoint ) ) + { + return ::boost::optional< size_t >( i ); + } + } + return ::boost::optional< size_t >(); + } + + //------------------------------------------------------------------------------------------------------------------ + Rectangle PanelTabBar_Impl::GetItemScreenRect( const size_t i_nItemPos ) const + { + ENSURE_OR_RETURN( i_nItemPos < m_aItems.size(), "PanelTabBar_Impl::GetItemScreenRect: invalid item pos!", Rectangle() ); + const ItemDescriptor& rItem( m_aItems[ i_nItemPos ] ); + const Rectangle aItemRect( m_aNormalizer.getTransformed( + GetActualLogicalItemRect( rItem.GetCurrentRect() ), + m_eTabAlignment ) ); + + const Rectangle aTabBarRect( m_rTabBar.GetWindowExtentsRelative( NULL ) ); + return Rectangle( + Point( aTabBarRect.Left() + aItemRect.Left(), aTabBarRect.Top() + aItemRect.Top() ), + aItemRect.GetSize() + ); + } + + //------------------------------------------------------------------------------------------------------------------ + void PanelTabBar_Impl::FocusItem( const ::boost::optional< size_t >& i_rItemPos ) + { + // reset old focus item + if ( !!m_aFocusedItem ) + InvalidateItem( *m_aFocusedItem ); + m_aFocusedItem.reset(); + + // mark the active icon as focused + if ( !!i_rItemPos ) + { + m_aFocusedItem = i_rItemPos; + InvalidateItem( *m_aFocusedItem ); + } + } + + //------------------------------------------------------------------------------------------------------------------ + IMPL_LINK( PanelTabBar_Impl, OnScroll, const PushButton*, i_pButton ) + { + if ( i_pButton == &m_aScrollBack ) + { + OSL_ENSURE( m_nScrollPosition > 0, "PanelTabBar_Impl::OnScroll: inconsistency!" ); + --m_nScrollPosition; + m_rTabBar.Invalidate(); + } + else if ( i_pButton == &m_aScrollForward ) + { + OSL_ENSURE( m_nScrollPosition < m_aItems.size() - 1, "PanelTabBar_Impl::OnScroll: inconsistency!" ); + ++m_nScrollPosition; + m_rTabBar.Invalidate(); + } + + UpdateScrollButtons(); + + return 0L; + } + + //------------------------------------------------------------------------------------------------------------------ + Rectangle PanelTabBar_Impl::GetActualLogicalItemRect( const Rectangle& i_rLogicalItemRect ) const + { + // care for the offset imposed by our geometry, i.e. whether or not we have scroll buttons + Rectangle aItemRect( i_rLogicalItemRect ); + aItemRect.Move( m_aGeometry.getItemsRect().Left() - m_aGeometry.getButtonBackRect().Left(), 0 ); + + // care for the current scroll position + OSL_ENSURE( m_nScrollPosition < m_aItems.size(), "GetActualLogicalItemRect: invalid scroll position!" ); + if ( ( m_nScrollPosition > 0 ) && ( m_nScrollPosition < m_aItems.size() ) ) + { + long nOffsetX = m_aItems[ m_nScrollPosition ].GetCurrentRect().Left() - m_aItems[ 0 ].GetCurrentRect().Left(); + long nOffsetY = m_aItems[ m_nScrollPosition ].GetCurrentRect().Top() - m_aItems[ 0 ].GetCurrentRect().Top(); + aItemRect.Move( -nOffsetX, -nOffsetY ); + } + + return aItemRect; + } + + //================================================================================================================== + //= PanelTabBar_Impl + //================================================================================================================== + //------------------------------------------------------------------------------------------------------------------ + void PanelTabBar_Impl::ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive ) + { + EnsureItemsCache(); + + if ( !!i_rOldActive ) + InvalidateItem( *i_rOldActive, ITEM_STATE_ACTIVE ); + if ( !!i_rNewActive ) + InvalidateItem( *i_rNewActive ); + } + + //------------------------------------------------------------------------------------------------------------------ + void PanelTabBar_Impl::LayouterChanged( const PDeckLayouter& i_rNewLayouter ) + { + // not interested in + (void)i_rNewLayouter; + } + + //------------------------------------------------------------------------------------------------------------------ + void PanelTabBar_Impl::Dying() + { + // not interested in - the notifier is a member of this instance here, so we're dying ourself at the moment + } + + //================================================================================================================== + //= PanelTabBar + //================================================================================================================== + //------------------------------------------------------------------------------------------------------------------ + PanelTabBar::PanelTabBar( Window& i_rParentWindow, IToolPanelDeck& i_rPanelDeck, const TabAlignment i_eAlignment, const TabItemContent i_eItemContent ) + :Control( &i_rParentWindow, 0 ) + ,m_pImpl( new PanelTabBar_Impl( *this, i_rPanelDeck, i_eAlignment, i_eItemContent ) ) + { + DBG_CHECK( *m_pImpl ); + } + + //------------------------------------------------------------------------------------------------------------------ + PanelTabBar::~PanelTabBar() + { + } + + //------------------------------------------------------------------------------------------------------------------ + TabItemContent PanelTabBar::GetTabItemContent() const + { + return m_pImpl->m_aGeometry.getItemContent(); + } + + //------------------------------------------------------------------------------------------------------------------ + void PanelTabBar::SetTabItemContent( const TabItemContent& i_eItemContent ) + { + m_pImpl->m_aGeometry.setItemContent( i_eItemContent ); + m_pImpl->Relayout(); + Invalidate(); + } + + //------------------------------------------------------------------------------------------------------------------ + IToolPanelDeck& PanelTabBar::GetPanelDeck() const + { + DBG_CHECK( *m_pImpl ); + return m_pImpl->m_rPanelDeck; + } + + //------------------------------------------------------------------------------------------------------------------ + Size PanelTabBar::GetOptimalSize( WindowSizeType i_eType ) const + { + m_pImpl->EnsureItemsCache(); + Size aOptimalSize( m_pImpl->m_aGeometry.getOptimalSize( m_pImpl->m_aItems, i_eType == WINDOWSIZE_MINIMUM ) ); + if ( m_pImpl->IsVertical() ) + ::std::swap( aOptimalSize.Width(), aOptimalSize.Height() ); + return aOptimalSize; + } + + //------------------------------------------------------------------------------------------------------------------ + void PanelTabBar::Resize() + { + Control::Resize(); + m_pImpl->Relayout(); + } + + //------------------------------------------------------------------------------------------------------------------ + void PanelTabBar::Paint( const Rectangle& i_rRect ) + { + m_pImpl->EnsureItemsCache(); + + // background + const Rectangle aNormalizedPaintArea( m_pImpl->m_aNormalizer.getNormalized( i_rRect, m_pImpl->m_eTabAlignment ) ); + m_pImpl->m_aRenderDevice.Push( PUSH_CLIPREGION ); + m_pImpl->m_aRenderDevice.SetClipRegion( aNormalizedPaintArea ); + m_pImpl->m_pRenderer->renderBackground(); + m_pImpl->m_aRenderDevice.Pop(); + m_pImpl->CopyFromRenderDevice( aNormalizedPaintArea ); + + // ensure the items really paint into their own playground only + ClipItemRegion aClipItems( *m_pImpl ); + + const Rectangle aLogicalPaintRect( m_pImpl->m_aNormalizer.getNormalized( i_rRect, m_pImpl->m_eTabAlignment ) ); + + const ::boost::optional< size_t > aActivePanel( m_pImpl->m_rPanelDeck.GetActivePanel() ); + const ::boost::optional< size_t > aHoveredPanel( m_pImpl->m_aHoveredItem ); + + // items: + // 1. paint all non-active, non-hovered items + size_t i=0; + for ( ItemDescriptors::const_iterator item = m_pImpl->m_aItems.begin(); + item != m_pImpl->m_aItems.end(); + ++item, ++i + ) + { + if ( i == aActivePanel ) + continue; + + if ( aHoveredPanel == i ) + continue; + + m_pImpl->DrawItem( i, aLogicalPaintRect ); + } + + // 2. paint the item which is hovered, /without/ the mouse button pressed down + if ( !!aHoveredPanel && !m_pImpl->m_bMouseButtonDown ) + m_pImpl->DrawItem( *aHoveredPanel, aLogicalPaintRect ); + + // 3. paint the active item + if ( !!aActivePanel ) + m_pImpl->DrawItem( *aActivePanel, aLogicalPaintRect ); + + // 4. paint the item which is hovered, /with/ the mouse button pressed down + if ( !!aHoveredPanel && m_pImpl->m_bMouseButtonDown ) + m_pImpl->DrawItem( *aHoveredPanel, aLogicalPaintRect ); + } + + //------------------------------------------------------------------------------------------------------------------ + void PanelTabBar::MouseMove( const MouseEvent& i_rMouseEvent ) + { + m_pImpl->EnsureItemsCache(); + + ::boost::optional< size_t > aOldItem( m_pImpl->m_aHoveredItem ); + ::boost::optional< size_t > aNewItem( m_pImpl->FindItemForPoint( i_rMouseEvent.GetPosPixel() ) ); + + if ( i_rMouseEvent.IsLeaveWindow() ) + aNewItem.reset(); + + if ( aOldItem != aNewItem ) + { + if ( !!aOldItem ) + m_pImpl->InvalidateItem( *aOldItem ); + + m_pImpl->m_aHoveredItem = aNewItem; + + if ( !!aNewItem ) + m_pImpl->InvalidateItem( *aNewItem ); + } + } + + //------------------------------------------------------------------------------------------------------------------ + void PanelTabBar::MouseButtonDown( const MouseEvent& i_rMouseEvent ) + { + Control::MouseButtonDown( i_rMouseEvent ); + + if ( !i_rMouseEvent.IsLeft() ) + return; + + m_pImpl->EnsureItemsCache(); + + ::boost::optional< size_t > aHitItem( m_pImpl->FindItemForPoint( i_rMouseEvent.GetPosPixel() ) ); + if ( !aHitItem ) + return; + + CaptureMouse(); + m_pImpl->m_bMouseButtonDown = true; + + m_pImpl->InvalidateItem( *aHitItem ); + } + + //------------------------------------------------------------------------------------------------------------------ + void PanelTabBar::MouseButtonUp( const MouseEvent& i_rMouseEvent ) + { + Control::MouseButtonUp( i_rMouseEvent ); + + if ( m_pImpl->m_bMouseButtonDown ) + { + ::boost::optional< size_t > aHitItem( m_pImpl->FindItemForPoint( i_rMouseEvent.GetPosPixel() ) ); + if ( !!aHitItem ) + { + // re-draw that item now that we're not in mouse-down mode anymore + m_pImpl->InvalidateItem( *aHitItem ); + // activate the respective panel + m_pImpl->m_rPanelDeck.ActivatePanel( *aHitItem ); + } + + OSL_ENSURE( IsMouseCaptured(), "PanelTabBar::MouseButtonUp: inconsistency!" ); + if ( IsMouseCaptured() ) + ReleaseMouse(); + m_pImpl->m_bMouseButtonDown = false; + } + } + + //------------------------------------------------------------------------------------------------------------------ + void PanelTabBar::RequestHelp( const HelpEvent& i_rHelpEvent ) + { + m_pImpl->EnsureItemsCache(); + + ::boost::optional< size_t > aHelpItem( m_pImpl->FindItemForPoint( ScreenToOutputPixel( i_rHelpEvent.GetMousePosPixel() ) ) ); + if ( !aHelpItem ) + return; + + const ItemDescriptor& rItem( m_pImpl->m_aItems[ *aHelpItem ] ); + if ( rItem.eContent != TABITEM_IMAGE_ONLY ) + // if the text is displayed for the item, we do not need to show it as tooltip + return; + + const ::rtl::OUString sItemText( rItem.pPanel->GetDisplayName() ); + if ( i_rHelpEvent.GetMode() == HELPMODE_BALLOON ) + Help::ShowBalloon( this, OutputToScreenPixel( rItem.GetCurrentRect().Center() ), rItem.GetCurrentRect(), sItemText ); + else + Help::ShowQuickHelp( this, rItem.GetCurrentRect(), sItemText ); + } + + //------------------------------------------------------------------------------------------------------------------ + void PanelTabBar::GetFocus() + { + Control::GetFocus(); + if ( !m_pImpl->m_aFocusedItem ) + m_pImpl->FocusItem( m_pImpl->m_rPanelDeck.GetActivePanel() ); + } + + //------------------------------------------------------------------------------------------------------------------ + void PanelTabBar::LoseFocus() + { + Control::LoseFocus(); + + if ( !!m_pImpl->m_aFocusedItem ) + { + m_pImpl->InvalidateItem( *m_pImpl->m_aFocusedItem ); + } + + m_pImpl->m_aFocusedItem.reset(); + } + + //------------------------------------------------------------------------------------------------------------------ + class KeyInputHandler + { + public: + KeyInputHandler( Control& i_rControl, const KeyEvent& i_rKeyEvent ) + :m_rControl( i_rControl ) + ,m_rKeyEvent( i_rKeyEvent ) + ,m_bHandled( false ) + { + } + + ~KeyInputHandler() + { + if ( !m_bHandled ) + m_rControl.Control::KeyInput( m_rKeyEvent ); + } + + void setHandled() + { + m_bHandled = true; + } + + private: + Control& m_rControl; + const KeyEvent& m_rKeyEvent; + bool m_bHandled; + }; + + //------------------------------------------------------------------------------------------------------------------ + void PanelTabBar::KeyInput( const KeyEvent& i_rKeyEvent ) + { + KeyInputHandler aKeyInputHandler( *this, i_rKeyEvent ); + + const KeyCode& rKeyCode( i_rKeyEvent.GetKeyCode() ); + if ( rKeyCode.GetModifier() != 0 ) + // only interested in mere key presses + return; + + // if there are less than 2 panels, we cannot travel them ... + const size_t nPanelCount( m_pImpl->m_rPanelDeck.GetPanelCount() ); + if ( nPanelCount < 2 ) + return; + + OSL_PRECOND( !!m_pImpl->m_aFocusedItem, "PanelTabBar::KeyInput: we should have a focused item here!" ); + // if we get KeyInput events, we should have the focus. In this case, m_aFocusedItem should not be empty, + // except if there are no panels, but then we bail out of this method here earlier ... + + bool bFocusNext = false; + bool bFocusPrev = false; + + switch ( rKeyCode.GetCode() ) + { + case KEY_UP: bFocusPrev = true; break; + case KEY_DOWN: bFocusNext = true; break; + case KEY_LEFT: + if ( IsRTLEnabled() ) + bFocusNext = true; + else + bFocusPrev = true; + break; + case KEY_RIGHT: + if ( IsRTLEnabled() ) + bFocusPrev = true; + else + bFocusNext = true; + break; + case KEY_RETURN: + m_pImpl->m_rPanelDeck.ActivatePanel( *m_pImpl->m_aFocusedItem ); + break; + } + + if ( !bFocusNext && !bFocusPrev ) + return; + + m_pImpl->InvalidateItem( *m_pImpl->m_aFocusedItem ); + if ( bFocusNext ) + { + m_pImpl->m_aFocusedItem.reset( ( *m_pImpl->m_aFocusedItem + 1 ) % nPanelCount ); + } + else + { + m_pImpl->m_aFocusedItem.reset( ( *m_pImpl->m_aFocusedItem + nPanelCount - 1 ) % nPanelCount ); + } + m_pImpl->InvalidateItem( *m_pImpl->m_aFocusedItem ); + + // don't delegate to base class + aKeyInputHandler.setHandled(); + } + + //------------------------------------------------------------------------------------------------------------------ + void PanelTabBar::DataChanged( const DataChangedEvent& i_rDataChanedEvent ) + { + Control::DataChanged( i_rDataChanedEvent ); + + if ( ( i_rDataChanedEvent.GetType() == DATACHANGED_SETTINGS ) + && ( ( i_rDataChanedEvent.GetFlags() & SETTINGS_STYLE ) != 0 ) + ) + { + Invalidate(); + } + } + + //------------------------------------------------------------------------------------------------------------------ + bool PanelTabBar::IsVertical() const + { + return m_pImpl->IsVertical(); + } + + //------------------------------------------------------------------------------------------------------------------ + PushButton& PanelTabBar::GetScrollButton( const bool i_bForward ) + { + return i_bForward ? m_pImpl->m_aScrollForward : m_pImpl->m_aScrollBack; + } + + //------------------------------------------------------------------------------------------------------------------ + ::boost::optional< size_t > PanelTabBar::GetFocusedPanelItem() const + { + return m_pImpl->m_aFocusedItem; + } + + //------------------------------------------------------------------------------------------------------------------ + void PanelTabBar::FocusPanelItem( const size_t i_nItemPos ) + { + ENSURE_OR_RETURN_VOID( i_nItemPos < m_pImpl->m_rPanelDeck.GetPanelCount(), "PanelTabBar::FocusPanelItem: illegal item pos!" ); + + if ( !HasChildPathFocus() ) + GrabFocus(); + + m_pImpl->FocusItem( i_nItemPos ); + OSL_POSTCOND( !!m_pImpl->m_aFocusedItem, "PanelTabBar::FocusPanelItem: have the focus, but no focused item?" ); + if ( !!m_pImpl->m_aFocusedItem ) + m_pImpl->InvalidateItem( *m_pImpl->m_aFocusedItem ); + m_pImpl->m_aFocusedItem.reset( i_nItemPos ); + } + + //------------------------------------------------------------------------------------------------------------------ + Rectangle PanelTabBar::GetItemScreenRect( const size_t i_nItemPos ) const + { + return m_pImpl->GetItemScreenRect( i_nItemPos ); + } + + //------------------------------------------------------------------------------------------------------------------ + Reference< XWindowPeer > PanelTabBar::GetComponentInterface( BOOL i_bCreate ) + { + Reference< XWindowPeer > xWindowPeer( Control::GetComponentInterface( FALSE ) ); + if ( !xWindowPeer.is() && i_bCreate ) + { + xWindowPeer.set( new PanelTabBarPeer( *this ) ); + SetComponentInterface( xWindowPeer ); + } + return xWindowPeer; + } + +//........................................................................ +} // namespace svt +//........................................................................ diff --git a/svtools/source/toolpanel/paneltabbarpeer.cxx b/svtools/source/toolpanel/paneltabbarpeer.cxx new file mode 100644 index 000000000000..d8329109ffb4 --- /dev/null +++ b/svtools/source/toolpanel/paneltabbarpeer.cxx @@ -0,0 +1,101 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "precompiled_svtools.hxx" + +#include "paneltabbarpeer.hxx" +#include "svtools/toolpanel/paneltabbar.hxx" + +/** === begin UNO includes === **/ +#include <com/sun/star/lang/DisposedException.hpp> +/** === end UNO includes === **/ + +#include <tools/diagnose_ex.h> + +//........................................................................ +namespace svt +{ +//........................................................................ + + /** === begin UNO using === **/ + using ::com::sun::star::uno::Reference; + using ::com::sun::star::uno::XInterface; + using ::com::sun::star::uno::UNO_QUERY; + using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::uno::UNO_SET_THROW; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::uno::RuntimeException; + using ::com::sun::star::uno::Any; + using ::com::sun::star::uno::makeAny; + using ::com::sun::star::uno::Sequence; + using ::com::sun::star::uno::Type; + using ::com::sun::star::accessibility::XAccessibleContext; + using ::com::sun::star::lang::DisposedException; + /** === end UNO using === **/ + + //================================================================================================================== + //= PanelTabBarPeer + //================================================================================================================== + //------------------------------------------------------------------------------------------------------------------ + PanelTabBarPeer::PanelTabBarPeer( PanelTabBar& i_rTabBar ) + :VCLXWindow() + ,m_pTabBar( &i_rTabBar ) + { + } + + //------------------------------------------------------------------------------------------------------------------ + PanelTabBarPeer::~PanelTabBarPeer() + { + } + + //------------------------------------------------------------------------------------------------------------------ + Reference< XAccessibleContext > PanelTabBarPeer::CreateAccessibleContext() + { + ::vos::OGuard aSolarGuard( GetMutex() ); + if ( m_pTabBar == NULL ) + throw DisposedException( ::rtl::OUString(), *this ); + + + + Window* pAccessibleParent( m_pTabBar->GetAccessibleParentWindow() ); + ENSURE_OR_RETURN( pAccessibleParent != NULL, "no accessible parent => no accessible context", NULL ); + Reference< XAccessible > xAccessibleParent( pAccessibleParent->GetAccessible(), UNO_SET_THROW ); + return m_aAccessibleFactory.getFactory().createAccessibleToolPanelTabBar( xAccessibleParent, m_pTabBar->GetPanelDeck(), *m_pTabBar ); + } + + //------------------------------------------------------------------------------------------------------------------ + void SAL_CALL PanelTabBarPeer::dispose() throw(RuntimeException) + { + { + ::vos::OGuard aSolarGuard( GetMutex() ); + m_pTabBar = NULL; + } + VCLXWindow::dispose(); + } + +//........................................................................ +} // namespace svt +//........................................................................ diff --git a/svtools/source/toolpanel/paneltabbarpeer.hxx b/svtools/source/toolpanel/paneltabbarpeer.hxx new file mode 100644 index 000000000000..7c2e5188d994 --- /dev/null +++ b/svtools/source/toolpanel/paneltabbarpeer.hxx @@ -0,0 +1,69 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SVT_PANELTABBARPEER_HXX +#define SVT_PANELTABBARPEER_HXX + +#include "svtaccessiblefactory.hxx" + +/** === begin UNO includes === **/ +/** === end UNO includes === **/ + +#include <toolkit/awt/vclxwindow.hxx> + +//...................................................................................................................... +namespace svt +{ +//...................................................................................................................... + + class PanelTabBar; + //==================================================================== + //= PanelTabBarPeer + //==================================================================== + class PanelTabBarPeer : public VCLXWindow + { + public: + PanelTabBarPeer( PanelTabBar& i_rTabBar ); + + protected: + ~PanelTabBarPeer(); + + // VCLXWindow overridables + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > CreateAccessibleContext(); + + // XComponent + void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException); + + private: + AccessibleFactoryAccess m_aAccessibleFactory; + PanelTabBar* m_pTabBar; + }; + +//........................................................................ +} // namespace svt +//........................................................................ + +#endif // SVT_PANELTABBARPEER_HXX diff --git a/svtools/source/toolpanel/refbase.cxx b/svtools/source/toolpanel/refbase.cxx new file mode 100644 index 000000000000..f41aa2d9bb9c --- /dev/null +++ b/svtools/source/toolpanel/refbase.cxx @@ -0,0 +1,56 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + +#include "precompiled_svtools.hxx" + +#include "svtools/toolpanel/refbase.hxx" + +//........................................................................ +namespace svt +{ +//........................................................................ + + //==================================================================== + //= RefBase + //==================================================================== + //-------------------------------------------------------------------- + oslInterlockedCount SAL_CALL RefBase::acquire() + { + return osl_incrementInterlockedCount( &m_refCount ); + } + + //-------------------------------------------------------------------- + oslInterlockedCount SAL_CALL RefBase::release() + { + oslInterlockedCount newCount = osl_decrementInterlockedCount( &m_refCount ); + if ( 0 == newCount ) + delete this; + return newCount; + } + +//........................................................................ +} // namespace svt +//........................................................................ diff --git a/svtools/source/toolpanel/tabbargeometry.cxx b/svtools/source/toolpanel/tabbargeometry.cxx new file mode 100644 index 000000000000..45c40cee6ef2 --- /dev/null +++ b/svtools/source/toolpanel/tabbargeometry.cxx @@ -0,0 +1,328 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + +#include "precompiled_svtools.hxx" + +#include "tabbargeometry.hxx" + +#include <basegfx/range/b2drange.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/numeric/ftools.hxx> + +#include <vcl/window.hxx> + +#include <algorithm> + +// the width (or height, depending on alignment) of the scroll buttons +#define BUTTON_FLOW_WIDTH 20 +// the space between the scroll buttons and the items +#define BUTTON_FLOW_SPACE 2 +// outer space to apply between the tab bar borders and any content. Note that those refer to a "normalized" geometry, +// i.e. if the tab bar were aligned at the top +#define OUTER_SPACE_LEFT 2 +#define OUTER_SPACE_TOP 4 +#define OUTER_SPACE_RIGHT 4 +#define OUTER_SPACE_BOTTOM 2 + +// outer space to apply between the area for the items, and the actual items. They refer to a normalized geometry. +#define ITEMS_INSET_LEFT 4 +#define ITEMS_INSET_TOP 3 +#define ITEMS_INSET_RIGHT 4 +#define ITEMS_INSET_BOTTOM 0 + +//...................................................................................................................... +namespace svt +{ +//...................................................................................................................... + + //================================================================================================================== + //= helper + //================================================================================================================== + namespace + { + //-------------------------------------------------------------------------------------------------------------- + static void lcl_transform( Rectangle& io_rRect, const ::basegfx::B2DHomMatrix& i_rTransformation ) + { + ::basegfx::B2DRange aRect( io_rRect.Left(), io_rRect.Top(), io_rRect.Right(), io_rRect.Bottom() ); + aRect.transform( i_rTransformation ); + io_rRect.Left() = long( aRect.getMinX() ); + io_rRect.Top() = long( aRect.getMinY() ); + io_rRect.Right() = long( aRect.getMaxX() ); + io_rRect.Bottom() = long( aRect.getMaxY() ); + } + + //-------------------------------------------------------------------------------------------------------------- + /** transforms the given, possible rotated playground, + */ + void lcl_rotate( const Rectangle& i_rReference, Rectangle& io_rArea, const bool i_bRight ) + { + // step 1: move the to-be-upper-left corner (left/bottom) of the rectangle to (0,0) + ::basegfx::B2DHomMatrix aTransformation; + aTransformation.translate( + i_bRight ? -i_rReference.Left() : -i_rReference.Right(), + i_bRight ? -i_rReference.Bottom() : -i_rReference.Top() + ); + + // step 2: rotate by -90 degrees + aTransformation.rotate( i_bRight ? +F_PI2 : -F_PI2 ); + // note: + // on the screen, the ordinate goes top-down, while basegfx calculates in a system where the + // ordinate goes bottom-up; thus the "wrong" sign before F_PI2 here + + // step 3: move back to original coordinates + aTransformation.translate( i_rReference.Left(), i_rReference.Top() ); + + // apply transformation + lcl_transform( io_rArea, aTransformation ); + } + } + + //------------------------------------------------------------------------------------------------------------------ + void lcl_mirrorHorizontally( const Rectangle& i_rReferenceArea, Rectangle& io_rArea ) + { + io_rArea.Left() = i_rReferenceArea.Left() + i_rReferenceArea.Right() - io_rArea.Left(); + io_rArea.Right() = i_rReferenceArea.Left() + i_rReferenceArea.Right() - io_rArea.Right(); + ::std::swap( io_rArea.Left(), io_rArea.Right() ); + } + + //------------------------------------------------------------------------------------------------------------------ + void lcl_mirrorVertically( const Rectangle& i_rReferenceArea, Rectangle& io_rArea ) + { + io_rArea.Top() = i_rReferenceArea.Top() + i_rReferenceArea.Bottom() - io_rArea.Top(); + io_rArea.Bottom() = i_rReferenceArea.Top() + i_rReferenceArea.Bottom() - io_rArea.Bottom(); + ::std::swap( io_rArea.Top(), io_rArea.Bottom() ); + } + + //================================================================================================================== + //= NormalizedArea + //================================================================================================================== + //------------------------------------------------------------------------------------------------------------------ + NormalizedArea::NormalizedArea() + :m_aReference() + { + } + + //------------------------------------------------------------------------------------------------------------------ + NormalizedArea::NormalizedArea( const Rectangle& i_rReference, const bool i_bIsVertical ) + :m_aReference( i_bIsVertical ? Rectangle( i_rReference.TopLeft(), Size( i_rReference.GetHeight(), i_rReference.GetWidth() ) ) : i_rReference ) + { + } + + //------------------------------------------------------------------------------------------------------------------ + Rectangle NormalizedArea::getTransformed( const Rectangle& i_rArea, const TabAlignment i_eTargetAlignment ) const + { + Rectangle aResult( i_rArea ); + + if ( ( i_eTargetAlignment == TABS_RIGHT ) + || ( i_eTargetAlignment == TABS_LEFT ) + ) + { + lcl_rotate( m_aReference, aResult, true ); + + if ( i_eTargetAlignment == TABS_LEFT ) + { + Rectangle aReference( m_aReference ); + aReference.Transpose(); + lcl_mirrorHorizontally( aReference, aResult ); + } + } + else + if ( i_eTargetAlignment == TABS_BOTTOM ) + { + lcl_mirrorVertically( m_aReference, aResult ); + } + + return aResult; + } + + //------------------------------------------------------------------------------------------------------------------ + Rectangle NormalizedArea::getNormalized( const Rectangle& i_rArea, const TabAlignment i_eTargetAlignment ) const + { + Rectangle aResult( i_rArea ); + + if ( ( i_eTargetAlignment == TABS_RIGHT ) + || ( i_eTargetAlignment == TABS_LEFT ) + ) + { + Rectangle aReference( m_aReference ); + lcl_rotate( m_aReference, aReference, true ); + + if ( i_eTargetAlignment == TABS_LEFT ) + { + lcl_mirrorHorizontally( aReference, aResult ); + } + + lcl_rotate( aReference, aResult, false ); + } + else + if ( i_eTargetAlignment == TABS_BOTTOM ) + { + lcl_mirrorVertically( m_aReference, aResult ); + } + return aResult; + } + + //================================================================================================================== + //= TabBarGeometry + //================================================================================================================== + //------------------------------------------------------------------------------------------------------------------ + TabBarGeometry::TabBarGeometry( const TabItemContent i_eItemContent ) + :m_eTabItemContent( i_eItemContent ) + ,m_aItemsInset() + ,m_aButtonBackRect() + ,m_aItemsRect() + ,m_aButtonForwardRect() + { + m_aItemsInset.Left() = ITEMS_INSET_LEFT; + m_aItemsInset.Top() = ITEMS_INSET_TOP; + m_aItemsInset.Right() = ITEMS_INSET_RIGHT; + m_aItemsInset.Bottom() = ITEMS_INSET_BOTTOM; + } + + //------------------------------------------------------------------------------------------------------------------ + TabBarGeometry::~TabBarGeometry() + { + } + + //------------------------------------------------------------------------------------------------------------------ + bool TabBarGeometry::impl_fitItems( ItemDescriptors& io_rItems ) const + { + if ( io_rItems.empty() ) + // nothing to do, "no items" perfectly fit into any space we have ... + return true; + + // the available size + Size aOutputSize( getItemsRect().GetSize() ); + // shrunk by the outer space + aOutputSize.Width() -= m_aItemsInset.Right(); + aOutputSize.Height() -= m_aItemsInset.Bottom(); + const Rectangle aFitInto( Point( 0, 0 ), aOutputSize ); + + TabItemContent eItemContent( getItemContent() ); + if ( eItemContent == TABITEM_AUTO ) + { + // the "content modes" to try + TabItemContent eTryThis[] = + { + TABITEM_IMAGE_ONLY, // assumed to have the smallest rects + TABITEM_TEXT_ONLY, + TABITEM_IMAGE_AND_TEXT // assumed to have the largest rects + }; + + + // determine which of the different version fits + eItemContent = eTryThis[0]; + size_t nTryIndex = 2; + while ( nTryIndex > 0 ) + { + const Point aBottomRight( io_rItems.rbegin()->GetRect( eTryThis[ nTryIndex ] ).BottomRight() ); + if ( aFitInto.IsInside( aBottomRight ) ) + { + eItemContent = eTryThis[ nTryIndex ]; + break; + } + --nTryIndex; + } + } + + // propagate to the items + for ( ItemDescriptors::iterator item = io_rItems.begin(); + item != io_rItems.end(); + ++item + ) + { + item->eContent = eItemContent; + } + + const ItemDescriptor& rLastItem( *io_rItems.rbegin() ); + const Point aLastItemBottomRight( rLastItem.GetCurrentRect().BottomRight() ); + return aFitInto.Left() <= aLastItemBottomRight.X() + && aFitInto.Right() >= aLastItemBottomRight.X(); + } + + //------------------------------------------------------------------------------------------------------------------ + Size TabBarGeometry::getOptimalSize( ItemDescriptors& io_rItems, const bool i_bMinimalSize ) const + { + if ( io_rItems.empty() ) + return Size( + m_aItemsInset.Left() + m_aItemsInset.Right(), + m_aItemsInset.Top() + m_aItemsInset.Bottom() + ); + + // the rect of the last item + const Rectangle& rLastItemRect( i_bMinimalSize ? io_rItems.rbegin()->aIconOnlyArea : io_rItems.rbegin()->aCompleteArea ); + return Size( + rLastItemRect.Left() + 1 + m_aItemsInset.Right(), + rLastItemRect.Top() + 1 + rLastItemRect.Bottom() + m_aItemsInset.Bottom() + ); + } + + //------------------------------------------------------------------------------------------------------------------ + void TabBarGeometry::relayout( const Size& i_rActualOutputSize, ItemDescriptors& io_rItems ) + { + // assume all items fit + Point aButtonBackPos( OUTER_SPACE_LEFT, OUTER_SPACE_TOP ); + m_aButtonBackRect = Rectangle( aButtonBackPos, Size( 1, 1 ) ); + m_aButtonBackRect.SetEmpty(); + + Point aButtonForwardPos( i_rActualOutputSize.Width(), OUTER_SPACE_TOP ); + m_aButtonForwardRect = Rectangle( aButtonForwardPos, Size( 1, 1 ) ); + m_aButtonForwardRect.SetEmpty(); + + Point aItemsPos( OUTER_SPACE_LEFT, 0 ); + Size aItemsSize( i_rActualOutputSize.Width() - OUTER_SPACE_LEFT - OUTER_SPACE_RIGHT, i_rActualOutputSize.Height() ); + m_aItemsRect = Rectangle( aItemsPos, aItemsSize ); + + if ( !impl_fitItems( io_rItems ) ) + { + // assumption was wrong, the items do not fit => calculate rects for the scroll buttons + const Size aButtonSize( BUTTON_FLOW_WIDTH, i_rActualOutputSize.Height() - OUTER_SPACE_TOP - OUTER_SPACE_BOTTOM ); + + aButtonBackPos = Point( OUTER_SPACE_LEFT, OUTER_SPACE_TOP ); + m_aButtonBackRect = Rectangle( aButtonBackPos, aButtonSize ); + + aButtonForwardPos = Point( i_rActualOutputSize.Width() - BUTTON_FLOW_WIDTH - OUTER_SPACE_RIGHT, OUTER_SPACE_TOP ); + m_aButtonForwardRect = Rectangle( aButtonForwardPos, aButtonSize ); + + aItemsPos.X() = aButtonBackPos.X() + aButtonSize.Width() + BUTTON_FLOW_SPACE; + aItemsSize.Width() = aButtonForwardPos.X() - BUTTON_FLOW_SPACE - aItemsPos.X(); + m_aItemsRect = Rectangle( aItemsPos, aItemsSize ); + + // fit items, again. In the TABITEM_AUTO case, the smaller playground for the items might lead to another + // item content. + impl_fitItems( io_rItems ); + } + } + + //------------------------------------------------------------------------------------------------------------------ + Point TabBarGeometry::getFirstItemPosition() const + { + return Point( m_aItemsInset.Left(), m_aItemsInset.Top() ); + } + +//...................................................................................................................... +} // namespace svt +//...................................................................................................................... diff --git a/svtools/source/toolpanel/tabbargeometry.hxx b/svtools/source/toolpanel/tabbargeometry.hxx new file mode 100644 index 000000000000..059d69a3e233 --- /dev/null +++ b/svtools/source/toolpanel/tabbargeometry.hxx @@ -0,0 +1,137 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + +#ifndef TABBARGEOMETRY_HXX +#define TABBARGEOMETRY_HXX + +#include "svtools/toolpanel/tabalignment.hxx" + +#include "tabitemdescriptor.hxx" + +#include <tools/gen.hxx> +#include <tools/svborder.hxx> + +//...................................................................................................................... +namespace svt +{ +//...................................................................................................................... + + //================================================================================================================== + //= NormalizedArea + //================================================================================================================== + /** a rectangle which automatically translates between unrotated and rotated geometry. + + It can be operated as if it were an unrotated area, but is able to provide corrdinates of rotated objects, + relative to its playground. + */ + class NormalizedArea + { + public: + NormalizedArea(); + NormalizedArea( const Rectangle& i_rReference, const bool i_bIsVertical ); + + /** transforms a rectangle, relative to our playground, into a coordinate system defined by the given alignment + @param i_rArea + the area which is to be transformed. + */ + Rectangle getTransformed( + const Rectangle& i_rArea, + const TabAlignment i_eTargetAlignment + ) const; + + /** normalizes an already transformed rectangle + @param i_rArea + the area which is to be normalized. + */ + Rectangle getNormalized( + const Rectangle& i_rArea, + const TabAlignment i_eTargetAlignment + ) const; + + + Size getReferenceSize() const { return m_aReference.GetSize(); } + const Rectangle& + getReference() const { return m_aReference; } + + private: + // the normalized reference area + Rectangle m_aReference; + }; + + //================================================================================================================== + //= TabBarGeometry + //================================================================================================================== + class TabBarGeometry_Impl; + class TabBarGeometry + { + public: + TabBarGeometry( const TabItemContent i_eItemContent ); + ~TabBarGeometry(); + + // retrieves the rectangle to be occupied by the button for scrolling backward through the items + const Rectangle& getButtonBackRect() const { return m_aButtonBackRect; } + // retrieves the rectangle to be occupied by the items + const Rectangle& getItemsRect() const { return m_aItemsRect; } + // retrieves the rectangle to be occupied by the button for scrolling forward through the items + const Rectangle& getButtonForwardRect() const { return m_aButtonForwardRect; } + + inline TabItemContent + getItemContent() const { return m_eTabItemContent; } + inline void setItemContent( const TabItemContent i_eItemContent ) { m_eTabItemContent = i_eItemContent; } + + /** adjusts the sizes of the buttons and the item's playground, plus the sizes of the items + */ + void relayout( const Size& i_rActualOutputSize, ItemDescriptors& io_rItems ); + + /** calculates the optimal size of the tab bar, depending on the item's sizes + */ + Size getOptimalSize( ItemDescriptors& io_rItems, const bool i_bMinimalSize ) const; + + /** retrieves the position where the first item should start, relative to the item rect + */ + Point getFirstItemPosition() const; + + private: + bool impl_fitItems( ItemDescriptors& io_rItems ) const; + + private: + /// specifies the content to be displayed in the tab items + TabItemContent m_eTabItemContent; + /// specifies the inset to be used in the items area, depends on the actual alignment + SvBorder m_aItemsInset; + // the (logical) rectangle to be used for the "back" button, empty if the button is not needed + Rectangle m_aButtonBackRect; + // the (logical) rectangle to be used for the items + Rectangle m_aItemsRect; + // the (logical) rectangle to be used for the "forward" button, empty if the button is not needed + Rectangle m_aButtonForwardRect; + }; + +//...................................................................................................................... +} // namespace svt +//...................................................................................................................... + +#endif // TABBARGEOMETRY_HXX diff --git a/svtools/source/toolpanel/tabitemdescriptor.hxx b/svtools/source/toolpanel/tabitemdescriptor.hxx new file mode 100644 index 000000000000..8005816b0fe2 --- /dev/null +++ b/svtools/source/toolpanel/tabitemdescriptor.hxx @@ -0,0 +1,90 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + +#ifndef TABITEMDESCRIPTOR_HXX +#define TABITEMDESCRIPTOR_HXX + +#include "svtools/toolpanel/toolpanel.hxx" +#include "svtools/toolpanel/tabitemcontent.hxx" + +#include <tools/gen.hxx> +#include <osl/diagnose.h> + +#include <vector> + +//........................................................................ +namespace svt +{ +//........................................................................ + + //================================================================================================================== + //= ItemDescriptor + //================================================================================================================== + struct ItemDescriptor + { + PToolPanel pPanel; + Rectangle aCompleteArea; // bounding area if the both text and icon are to be rendererd + Rectangle aIconOnlyArea; // bounding area if the icon is to be rendererd + Rectangle aTextOnlyArea; // bounding area if the text is to be rendererd + TabItemContent eContent; + // content to be used for this particular item. Might differ from item content which has been set + // up for the complete control, in case not the complete content fits into the available space. + + ItemDescriptor() + :pPanel() + ,aCompleteArea() + ,aIconOnlyArea() + ,aTextOnlyArea() + ,eContent( TABITEM_IMAGE_AND_TEXT ) + { + } + + const Rectangle& GetRect( const TabItemContent i_eItemContent ) const + { + OSL_ENSURE( i_eItemContent != TABITEM_AUTO, "ItemDescriptor::GetRect: illegal value!" ); + + return ( i_eItemContent == TABITEM_IMAGE_AND_TEXT ) + ? aCompleteArea + : ( ( i_eItemContent == TABITEM_TEXT_ONLY ) + ? aTextOnlyArea + : aIconOnlyArea + ); + } + + const Rectangle& GetCurrentRect() const + { + return GetRect( eContent ); + } + }; + + typedef ::std::vector< ItemDescriptor > ItemDescriptors; + + +//........................................................................ +} // namespace svt +//........................................................................ + +#endif // TABITEMDESCRIPTOR_HXX diff --git a/svtools/source/toolpanel/tablayouter.cxx b/svtools/source/toolpanel/tablayouter.cxx new file mode 100755 index 000000000000..f68bbc1bbd0f --- /dev/null +++ b/svtools/source/toolpanel/tablayouter.cxx @@ -0,0 +1,262 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + +#include "precompiled_svtools.hxx" + +#include "svtools/toolpanel/tablayouter.hxx" +#include "svtools/toolpanel/toolpaneldeck.hxx" +#include "svtools/toolpanel/paneltabbar.hxx" +#include "svtaccessiblefactory.hxx" + +#include <tools/gen.hxx> +#include <tools/diagnose_ex.h> + +//........................................................................ +namespace svt +{ +//........................................................................ + + using ::com::sun::star::uno::Reference; + using ::com::sun::star::accessibility::XAccessible; + + //==================================================================== + //= TabDeckLayouter_Data + //==================================================================== + struct TabDeckLayouter_Data + { + TabAlignment eAlignment; + IToolPanelDeck& rPanels; + ::std::auto_ptr< PanelTabBar > pTabBar; + AccessibleFactoryAccess aAccessibleFactory; + + TabDeckLayouter_Data( Window& i_rParent, IToolPanelDeck& i_rPanels, + const TabAlignment i_eAlignment, const TabItemContent i_eItemContent ) + :eAlignment( i_eAlignment ) + ,rPanels( i_rPanels ) + ,pTabBar( new PanelTabBar( i_rParent, i_rPanels, i_eAlignment, i_eItemContent ) ) + { + pTabBar->Show(); + } + }; + + //==================================================================== + //= helper + //==================================================================== + namespace + { + static bool lcl_isVerticalTabBar( const TabAlignment i_eAlignment ) + { + return ( i_eAlignment == TABS_RIGHT ) + || ( i_eAlignment == TABS_LEFT ); + } + + static bool lcl_checkDisposed( const TabDeckLayouter_Data& i_rData ) + { + if ( !i_rData.pTabBar.get() ) + { + OSL_ENSURE( false, "lcl_checkDisposed: already disposed!" ); + return true; + } + return false; + } + } + + //==================================================================== + //= TabDeckLayouter + //==================================================================== + //-------------------------------------------------------------------- + TabDeckLayouter::TabDeckLayouter( Window& i_rParent, IToolPanelDeck& i_rPanels, + const TabAlignment i_eAlignment, const TabItemContent i_eItemContent ) + :m_pData( new TabDeckLayouter_Data( i_rParent, i_rPanels, i_eAlignment, i_eItemContent ) ) + { + } + + //-------------------------------------------------------------------- + TabDeckLayouter::~TabDeckLayouter() + { + } + + //-------------------------------------------------------------------- + IMPLEMENT_IREFERENCE( TabDeckLayouter ) + + //-------------------------------------------------------------------- + TabItemContent TabDeckLayouter::GetTabItemContent() const + { + if ( lcl_checkDisposed( *m_pData ) ) + return TABITEM_IMAGE_AND_TEXT; + return m_pData->pTabBar->GetTabItemContent(); + } + + //-------------------------------------------------------------------- + void TabDeckLayouter::SetTabItemContent( const TabItemContent& i_eItemContent ) + { + if ( lcl_checkDisposed( *m_pData ) ) + return; + m_pData->pTabBar->SetTabItemContent( i_eItemContent ); + } + + //-------------------------------------------------------------------- + TabAlignment TabDeckLayouter::GetTabAlignment() const + { + if ( lcl_checkDisposed( *m_pData ) ) + return TABS_RIGHT; + return m_pData->eAlignment; + } + + //-------------------------------------------------------------------- + ::boost::optional< size_t > TabDeckLayouter::GetFocusedPanelItem() const + { + if ( lcl_checkDisposed( *m_pData ) ) + return ::boost::optional< size_t >(); + return m_pData->pTabBar->GetFocusedPanelItem(); + } + + //-------------------------------------------------------------------- + void TabDeckLayouter::FocusPanelItem( const size_t i_nItemPos ) + { + if ( lcl_checkDisposed( *m_pData ) ) + return; + m_pData->pTabBar->FocusPanelItem( i_nItemPos ); + } + + //-------------------------------------------------------------------- + bool TabDeckLayouter::IsPanelSelectorEnabled() const + { + if ( lcl_checkDisposed( *m_pData ) ) + return false; + return m_pData->pTabBar->IsEnabled(); + } + + //-------------------------------------------------------------------- + bool TabDeckLayouter::IsPanelSelectorVisible() const + { + if ( lcl_checkDisposed( *m_pData ) ) + return false; + return m_pData->pTabBar->IsVisible(); + } + + //-------------------------------------------------------------------- + Rectangle TabDeckLayouter::GetItemScreenRect( const size_t i_nItemPos ) const + { + if ( lcl_checkDisposed( *m_pData ) ) + return Rectangle(); + return m_pData->pTabBar->GetItemScreenRect( i_nItemPos ); + } + + //-------------------------------------------------------------------- + Rectangle TabDeckLayouter::Layout( const Rectangle& i_rDeckPlayground ) + { + if ( lcl_checkDisposed( *m_pData ) ) + return i_rDeckPlayground; + + const Size aPreferredSize( m_pData->pTabBar->GetOptimalSize( WINDOWSIZE_PREFERRED ) ); + if ( lcl_isVerticalTabBar( m_pData->eAlignment ) ) + { + Size aTabBarSize = ( aPreferredSize.Width() < i_rDeckPlayground.GetWidth() ) + ? aPreferredSize + : m_pData->pTabBar->GetOptimalSize( WINDOWSIZE_MINIMUM ); + aTabBarSize.Height() = i_rDeckPlayground.GetHeight(); + + Rectangle aPanelRect( i_rDeckPlayground ); + if ( m_pData->eAlignment == TABS_RIGHT ) + { + aPanelRect.Right() -= aTabBarSize.Width(); + Point aTabBarTopLeft( aPanelRect.TopRight() ); + aTabBarTopLeft.X() += 1; + m_pData->pTabBar->SetPosSizePixel( aTabBarTopLeft, aTabBarSize ); + } + else + { + m_pData->pTabBar->SetPosSizePixel( aPanelRect.TopLeft(), aTabBarSize ); + aPanelRect.Left() += aTabBarSize.Width(); + } + if ( aPanelRect.Left() >= aPanelRect.Right() ) + aPanelRect = Rectangle(); + + return aPanelRect; + } + + Size aTabBarSize = ( aPreferredSize.Height() < i_rDeckPlayground.GetHeight() ) + ? aPreferredSize + : m_pData->pTabBar->GetOptimalSize( WINDOWSIZE_MINIMUM ); + aTabBarSize.Width() = i_rDeckPlayground.GetWidth(); + + Rectangle aPanelRect( i_rDeckPlayground ); + if ( m_pData->eAlignment == TABS_TOP ) + { + m_pData->pTabBar->SetPosSizePixel( aPanelRect.TopLeft(), aTabBarSize ); + aPanelRect.Top() += aTabBarSize.Height(); + } + else + { + aPanelRect.Bottom() -= aTabBarSize.Height(); + Point aTabBarTopLeft( aPanelRect.BottomLeft() ); + aTabBarTopLeft.Y() -= 1; + m_pData->pTabBar->SetPosSizePixel( aTabBarTopLeft, aTabBarSize ); + } + if ( aPanelRect.Top() >= aPanelRect.Bottom() ) + aPanelRect = Rectangle(); + + return aPanelRect; + } + + //-------------------------------------------------------------------- + void TabDeckLayouter::Destroy() + { + m_pData->pTabBar.reset(); + } + + //-------------------------------------------------------------------- + void TabDeckLayouter::SetFocusToPanelSelector() + { + if ( lcl_checkDisposed( *m_pData ) ) + return; + m_pData->pTabBar->GrabFocus(); + } + + //-------------------------------------------------------------------- + size_t TabDeckLayouter::GetAccessibleChildCount() const + { + if ( lcl_checkDisposed( *m_pData ) ) + return 0; + + return 1; + } + + //-------------------------------------------------------------------- + Reference< XAccessible > TabDeckLayouter::GetAccessibleChild( const size_t i_nChildIndex, const Reference< XAccessible >& i_rParentAccessible ) + { + (void)i_nChildIndex; + (void)i_rParentAccessible; + if ( lcl_checkDisposed( *m_pData ) ) + return NULL; + + return m_pData->pTabBar->GetAccessible( TRUE ); + } + +//........................................................................ +} // namespace svt +//........................................................................ diff --git a/svtools/source/toolpanel/toolpanel.cxx b/svtools/source/toolpanel/toolpanel.cxx new file mode 100644 index 000000000000..35446d1ffe2b --- /dev/null +++ b/svtools/source/toolpanel/toolpanel.cxx @@ -0,0 +1,52 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + +#include "svtools/toolpanel/toolpanel.hxx" + +//........................................................................ +namespace svt +{ +//........................................................................ + + //==================================================================== + //= ToolPanelBase + //==================================================================== + //-------------------------------------------------------------------- + ToolPanelBase::ToolPanelBase() + { + } + + //-------------------------------------------------------------------- + ToolPanelBase::~ToolPanelBase() + { + } + + //-------------------------------------------------------------------- + IMPLEMENT_IREFERENCE( ToolPanelBase ) + +//........................................................................ +} // namespace svt +//........................................................................ diff --git a/svtools/source/uno/unoifac2.hrc b/svtools/source/toolpanel/toolpanel.src index a31d07e0bd27..4861fbfd14ac 100644 --- a/svtools/source/uno/unoifac2.hrc +++ b/svtools/source/toolpanel/toolpanel.src @@ -1,5 +1,4 @@ /************************************************************************* - * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. @@ -25,28 +24,16 @@ * ************************************************************************/ -#ifndef _SVT_UNO_UNOIFAC_HRC_ -#define _SVT_UNO_UNOIFAC_HRC_ - - -#ifndef _SOLAR_HRC -#include <svl/solar.hrc> -#endif - -//! Um den berblick ber alle benutzten HelpID's zu behalten sind diese -//! zentral in <helpid.hrc> -#ifndef _SVT_HELPID_HRC -#include <svtools/helpid.hrc> -#endif - -// RID's fuer das Kontextmenu der Textkomponente -#define RID_CONTEXTMENU (RID_APP_START + 1024) -#define RID_OPEN_LINK (RID_APP_START + 10) -#define RID_OPEN_LINK_NEW (RID_APP_START + 11) -#define RID_DOWNLOAD (RID_APP_START + 12) -#define RID_ADD_BOOKMARK (RID_APP_START + 13) -#define RID_COPY_LINK (RID_APP_START + 14) - +#include <svl/svtools.hrc> -#endif +// the following string ID is a hack, until MBA's promised patch appears, which splits svl/svtools.hrc +// into two files, one for svl, one or svtools +String STR_SVT_ACC_BEGIN + 0 +{ + Text [ en-US ] = "Tab Panel Scroll Button, backward"; +}; +String STR_SVT_ACC_BEGIN + 1 +{ + Text [ en-US ] = "Tab Panel Scroll Button, forward"; +}; diff --git a/svtools/source/toolpanel/toolpanelcollection.cxx b/svtools/source/toolpanel/toolpanelcollection.cxx new file mode 100644 index 000000000000..baefbd92400f --- /dev/null +++ b/svtools/source/toolpanel/toolpanelcollection.cxx @@ -0,0 +1,193 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + +#include "precompiled_svtools.hxx" + +#include "toolpanelcollection.hxx" +#include "paneldecklisteners.hxx" + +#include <tools/diagnose_ex.h> + +#include <vector> + +//........................................................................ +namespace svt +{ +//........................................................................ + + //==================================================================== + //= ToolPanelCollection_Data + //==================================================================== + struct ToolPanelCollection_Data + { + ::std::vector< PToolPanel > aPanels; + ::boost::optional< size_t > aActivePanel; + PanelDeckListeners aListeners; + }; + + //==================================================================== + //= ToolPanelCollection + //==================================================================== + //-------------------------------------------------------------------- + ToolPanelCollection::ToolPanelCollection() + :m_pData( new ToolPanelCollection_Data ) + { + } + + //-------------------------------------------------------------------- + ToolPanelCollection::~ToolPanelCollection() + { + m_pData->aListeners.Dying(); + } + + //-------------------------------------------------------------------- + size_t ToolPanelCollection::GetPanelCount() const + { + return m_pData->aPanels.size(); + } + + //-------------------------------------------------------------------- + ::boost::optional< size_t > ToolPanelCollection::GetActivePanel() const + { + return m_pData->aActivePanel; + } + + //-------------------------------------------------------------------- + void ToolPanelCollection::ActivatePanel( const ::boost::optional< size_t >& i_rPanel ) + { + if ( !!i_rPanel ) + { + OSL_ENSURE( *i_rPanel < GetPanelCount(), "ToolPanelCollection::ActivatePanel: illegal panel no.!" ); + if ( *i_rPanel >= GetPanelCount() ) + return; + } + + if ( m_pData->aActivePanel == i_rPanel ) + return; + + const ::boost::optional< size_t > aOldPanel( m_pData->aActivePanel ); + m_pData->aActivePanel = i_rPanel; + + // notify listeners + m_pData->aListeners.ActivePanelChanged( aOldPanel, m_pData->aActivePanel ); + } + + //-------------------------------------------------------------------- + PToolPanel ToolPanelCollection::GetPanel( const size_t i_nPos ) const + { + OSL_ENSURE( i_nPos < m_pData->aPanels.size(), "ToolPanelCollection::GetPanel: illegal position!" ); + if ( i_nPos >= m_pData->aPanels.size() ) + return PToolPanel(); + return m_pData->aPanels[ i_nPos ]; + } + + //-------------------------------------------------------------------- + size_t ToolPanelCollection::InsertPanel( const PToolPanel& i_pPanel, const size_t i_nPosition ) + { + OSL_ENSURE( i_pPanel.get(), "ToolPanelCollection::InsertPanel: illegal panel!" ); + if ( !i_pPanel.get() ) + return 0; + + // insert + const size_t position = i_nPosition < m_pData->aPanels.size() ? i_nPosition : m_pData->aPanels.size(); + m_pData->aPanels.insert( m_pData->aPanels.begin() + position, i_pPanel ); + + // update active panel + if ( !!m_pData->aActivePanel ) + { + if ( i_nPosition <= *m_pData->aActivePanel ) + ++*m_pData->aActivePanel; + } + + // notifications + m_pData->aListeners.PanelInserted( i_pPanel, i_nPosition ); + + return position; + } + + //-------------------------------------------------------------------- + PToolPanel ToolPanelCollection::RemovePanel( const size_t i_nPosition ) + { + OSL_ENSURE( i_nPosition < m_pData->aPanels.size(), "ToolPanelCollection::RemovePanel: illegal position!" ); + if ( i_nPosition >= m_pData->aPanels.size() ) + return NULL; + + // if the active panel is going to be removed, activate another one (before the actual removal) + if ( m_pData->aActivePanel == i_nPosition ) + { + const ::boost::optional< size_t > aOldActive( m_pData->aActivePanel ); + + if ( i_nPosition + 1 < GetPanelCount() ) + { + ++*m_pData->aActivePanel; + } + else if ( i_nPosition > 0 ) + { + --*m_pData->aActivePanel; + } + else + { + m_pData->aActivePanel.reset(); + } + + m_pData->aListeners.ActivePanelChanged( aOldActive, m_pData->aActivePanel ); + } + + // remember the removed panel for the aller + PToolPanel pRemovedPanel( m_pData->aPanels[ i_nPosition ] ); + + // actually remove + m_pData->aPanels.erase( m_pData->aPanels.begin() + i_nPosition ); + + if ( !!m_pData->aActivePanel ) + { + if ( i_nPosition < *m_pData->aActivePanel ) + { + --*m_pData->aActivePanel; + } + } + + // notify removed panel + m_pData->aListeners.PanelRemoved( i_nPosition ); + + return pRemovedPanel; + } + + //-------------------------------------------------------------------- + void ToolPanelCollection::AddListener( IToolPanelDeckListener& i_rListener ) + { + m_pData->aListeners.AddListener( i_rListener ); + } + + //-------------------------------------------------------------------- + void ToolPanelCollection::RemoveListener( IToolPanelDeckListener& i_rListener ) + { + m_pData->aListeners.RemoveListener( i_rListener ); + } + +//........................................................................ +} // namespace svt +//........................................................................ diff --git a/svtools/source/toolpanel/toolpanelcollection.hxx b/svtools/source/toolpanel/toolpanelcollection.hxx new file mode 100644 index 000000000000..2bdba38546c9 --- /dev/null +++ b/svtools/source/toolpanel/toolpanelcollection.hxx @@ -0,0 +1,69 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + +#ifndef TOOLPANELCOLLECTION_HXX +#define TOOLPANELCOLLECTION_HXX + +#include "svtools/toolpanel/toolpaneldeck.hxx" + +#include <memory> + +//........................................................................ +namespace svt +{ +//........................................................................ + + struct ToolPanelCollection_Data; + + //==================================================================== + //= ToolPanelCollection + //==================================================================== + class ToolPanelCollection : public IToolPanelDeck + { + public: + ToolPanelCollection(); + ~ToolPanelCollection(); + + // IToolPanelDeck + virtual size_t GetPanelCount() const; + virtual PToolPanel GetPanel( const size_t i_nPos ) const; + virtual ::boost::optional< size_t > + GetActivePanel() const; + virtual void ActivatePanel( const ::boost::optional< size_t >& i_rPanel ); + virtual size_t InsertPanel( const PToolPanel& i_pPanel, const size_t i_nPosition ); + virtual PToolPanel RemovePanel( const size_t i_nPosition ); + virtual void AddListener( IToolPanelDeckListener& i_rListener ); + virtual void RemoveListener( IToolPanelDeckListener& i_rListener ); + + private: + ::std::auto_ptr< ToolPanelCollection_Data > m_pData; + }; + +//........................................................................ +} // namespace svt +//........................................................................ + +#endif // TOOLPANELCOLLECTION_HXX diff --git a/svtools/source/toolpanel/toolpaneldeck.cxx b/svtools/source/toolpanel/toolpaneldeck.cxx new file mode 100755 index 000000000000..fe4fa63ad997 --- /dev/null +++ b/svtools/source/toolpanel/toolpaneldeck.cxx @@ -0,0 +1,533 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + +#include "precompiled_svtools.hxx" + +#include "dummypanel.hxx" +#include "toolpanelcollection.hxx" +#include "paneldecklisteners.hxx" +#include "toolpaneldeckpeer.hxx" +#include "svtools/toolpanel/toolpaneldeck.hxx" +#include "svtools/toolpanel/tablayouter.hxx" + +/** === begin UNO includes === **/ +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/accessibility/AccessibleRole.hpp> +/** === end UNO includes === **/ + +#include <tools/diagnose_ex.h> + +#include <boost/optional.hpp> + +//........................................................................ +namespace svt +{ +//........................................................................ + + /** === begin UNO using === **/ + using ::com::sun::star::uno::Reference; + using ::com::sun::star::accessibility::XAccessible; + using ::com::sun::star::awt::XWindowPeer; + using ::com::sun::star::uno::UNO_SET_THROW; + /** === end UNO using === **/ + namespace AccessibleRole = ::com::sun::star::accessibility::AccessibleRole; + + enum DeckAction + { + /// activates the first panel + ACTION_ACTIVATE_FIRST, + // activates the panel after the currently active panel + ACTION_ACTIVATE_NEXT, + // activates the panel before the currently active panel + ACTION_ACTIVATE_PREV, + // activates the last panel + ACTION_ACTIVATE_LAST, + + // toggles the focus between the active panel and the panel selector + ACTION_TOGGLE_FOCUS, + }; + + //==================================================================== + //= ToolPanelDeck_Impl + //==================================================================== + class ToolPanelDeck_Impl : public IToolPanelDeckListener + { + public: + ToolPanelDeck_Impl( ToolPanelDeck& i_rDeck ) + :m_rDeck( i_rDeck ) + ,m_aPanelAnchor( &i_rDeck ) + ,m_aPanels() + ,m_pDummyPanel( new DummyPanel ) + ,m_pLayouter() + ,m_pAccessibleParent( NULL ) + { + m_aPanels.AddListener( *this ); + m_aPanelAnchor.Show(); + m_aPanelAnchor.SetAccessibleRole( AccessibleRole::PANEL ); + } + + ~ToolPanelDeck_Impl() + { + } + + PDeckLayouter GetLayouter() const { return m_pLayouter; } + void SetLayouter( const PDeckLayouter& i_pNewLayouter ); + + Window& GetPanelWindowAnchor() { return m_aPanelAnchor; } + + /// notifies our listeners that we're going to die. Only to be called from with our anti-impl's destructor + void NotifyDying() + { + m_aPanels.RemoveListener( *this ); + m_aListeners.Dying(); + } + + // IToolPanelDeck equivalents + size_t GetPanelCount() const; + PToolPanel GetPanel( const size_t i_nPos ) const; + ::boost::optional< size_t > + GetActivePanel() const; + void ActivatePanel( const ::boost::optional< size_t >& i_rPanel ); + size_t InsertPanel( const PToolPanel& i_pPanel, const size_t i_nPosition ); + PToolPanel RemovePanel( const size_t i_nPosition ); + void AddListener( IToolPanelDeckListener& i_rListener ); + void RemoveListener( IToolPanelDeckListener& i_rListener ); + + /// re-layouts everything + void LayoutAll() { ImplDoLayout(); } + + void DoAction( const DeckAction i_eAction ); + + void FocusActivePanel(); + + void SetAccessibleParentWindow( Window* i_pAccessibleParent ); + Window* GetAccessibleParentWindow() const { return m_pAccessibleParent ? m_pAccessibleParent : m_rDeck.GetAccessibleParentWindow(); } + + protected: + // IToolPanelDeckListener + virtual void PanelInserted( const PToolPanel& i_pPanel, const size_t i_nPosition ); + virtual void PanelRemoved( const size_t i_nPosition ); + virtual void ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive ); + virtual void LayouterChanged( const PDeckLayouter& i_rNewLayouter ); + virtual void Dying(); + + private: + void ImplDoLayout(); + PToolPanel GetActiveOrDummyPanel_Impl(); + + private: + ToolPanelDeck& m_rDeck; + Window m_aPanelAnchor; + ToolPanelCollection m_aPanels; + PToolPanel m_pDummyPanel; + PanelDeckListeners m_aListeners; + + PDeckLayouter m_pLayouter; + + Window* m_pAccessibleParent; + }; + + //-------------------------------------------------------------------- + PToolPanel ToolPanelDeck_Impl::GetActiveOrDummyPanel_Impl() + { + ::boost::optional< size_t > aActivePanel( m_aPanels.GetActivePanel() ); + if ( !aActivePanel ) + return m_pDummyPanel; + return m_aPanels.GetPanel( *aActivePanel ); + } + + //-------------------------------------------------------------------- + void ToolPanelDeck_Impl::SetLayouter( const PDeckLayouter& i_pNewLayouter ) + { + ENSURE_OR_RETURN_VOID( i_pNewLayouter.get(), "invalid layouter" ); + + if ( m_pLayouter.get() ) + m_pLayouter->Destroy(); + + m_pLayouter = i_pNewLayouter; + + ImplDoLayout(); + + m_aListeners.LayouterChanged( m_pLayouter ); + } + + //-------------------------------------------------------------------- + size_t ToolPanelDeck_Impl::GetPanelCount() const + { + return m_aPanels.GetPanelCount(); + } + + //-------------------------------------------------------------------- + PToolPanel ToolPanelDeck_Impl::GetPanel( const size_t i_nPos ) const + { + return m_aPanels.GetPanel( i_nPos ); + } + + //-------------------------------------------------------------------- + ::boost::optional< size_t > ToolPanelDeck_Impl::GetActivePanel() const + { + return m_aPanels.GetActivePanel(); + } + + //-------------------------------------------------------------------- + void ToolPanelDeck_Impl::ActivatePanel( const ::boost::optional< size_t >& i_rPanel ) + { + m_aPanels.ActivatePanel( i_rPanel ); + } + + //-------------------------------------------------------------------- + size_t ToolPanelDeck_Impl::InsertPanel( const PToolPanel& i_pPanel, const size_t i_nPosition ) + { + return m_aPanels.InsertPanel( i_pPanel, i_nPosition ); + } + + //-------------------------------------------------------------------- + PToolPanel ToolPanelDeck_Impl::RemovePanel( const size_t i_nPosition ) + { + return m_aPanels.RemovePanel( i_nPosition ); + } + + //-------------------------------------------------------------------- + void ToolPanelDeck_Impl::ImplDoLayout() + { + const Rectangle aDeckPlayground( Point(), m_rDeck.GetOutputSizePixel() ); + + // ask the layouter what is left for our panel, and position the panel container window appropriately + Rectangle aPlaygroundArea( aDeckPlayground ); + OSL_ENSURE( m_pLayouter.get(), "ToolPanelDeck_Impl::ImplDoLayout: no layouter!" ); + if ( m_pLayouter.get() ) + { + aPlaygroundArea = m_pLayouter->Layout( aDeckPlayground ); + } + m_aPanelAnchor.SetPosSizePixel( aPlaygroundArea.TopLeft(), aPlaygroundArea.GetSize() ); + + // position the active panel + const PToolPanel pActive( GetActiveOrDummyPanel_Impl() ); + pActive->SetSizePixel( m_aPanelAnchor.GetOutputSizePixel() ); + } + + //-------------------------------------------------------------------- + void ToolPanelDeck_Impl::AddListener( IToolPanelDeckListener& i_rListener ) + { + m_aListeners.AddListener( i_rListener ); + } + + //-------------------------------------------------------------------- + void ToolPanelDeck_Impl::RemoveListener( IToolPanelDeckListener& i_rListener ) + { + m_aListeners.RemoveListener( i_rListener ); + } + + //-------------------------------------------------------------------- + void ToolPanelDeck_Impl::DoAction( const DeckAction i_eAction ) + { + const size_t nPanelCount( m_aPanels.GetPanelCount() ); + ::boost::optional< size_t > aActivatePanel; + ::boost::optional< size_t > aCurrentPanel( GetActivePanel() ); + + switch ( i_eAction ) + { + case ACTION_ACTIVATE_FIRST: + if ( nPanelCount > 0 ) + aActivatePanel = 0; + break; + case ACTION_ACTIVATE_PREV: + if ( !aCurrentPanel && ( nPanelCount > 0 ) ) + aActivatePanel = nPanelCount - 1; + else + if ( !!aCurrentPanel && ( *aCurrentPanel > 0 ) ) + aActivatePanel = *aCurrentPanel - 1; + break; + case ACTION_ACTIVATE_NEXT: + if ( !aCurrentPanel && ( nPanelCount > 0 ) ) + aActivatePanel = 0; + else + if ( !!aCurrentPanel && ( *aCurrentPanel < nPanelCount - 1 ) ) + aActivatePanel = *aCurrentPanel + 1; + break; + case ACTION_ACTIVATE_LAST: + if ( nPanelCount > 0 ) + aActivatePanel = nPanelCount - 1; + break; + case ACTION_TOGGLE_FOCUS: + { + PToolPanel pActivePanel( GetActiveOrDummyPanel_Impl() ); + if ( !m_aPanelAnchor.HasChildPathFocus() ) + pActivePanel->GrabFocus(); + else + GetLayouter()->SetFocusToPanelSelector(); + } + break; + } + + if ( !!aActivatePanel ) + { + ActivatePanel( aActivatePanel ); + } + } + + //-------------------------------------------------------------------- + void ToolPanelDeck_Impl::FocusActivePanel() + { + PToolPanel pActivePanel( GetActiveOrDummyPanel_Impl() ); + pActivePanel->GrabFocus(); + } + + //-------------------------------------------------------------------- + void ToolPanelDeck_Impl::PanelInserted( const PToolPanel& i_pPanel, const size_t i_nPosition ) + { + // multiplex to our own listeners + m_aListeners.PanelInserted( i_pPanel, i_nPosition ); + } + + //-------------------------------------------------------------------- + void ToolPanelDeck_Impl::PanelRemoved( const size_t i_nPosition ) + { + // multiplex to our own listeners + m_aListeners.PanelRemoved( i_nPosition ); + } + + //-------------------------------------------------------------------- + void ToolPanelDeck_Impl::ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive ) + { + // hide the old panel + if ( !!i_rOldActive ) + { + const PToolPanel pOldActive( m_aPanels.GetPanel( *i_rOldActive ) ); + pOldActive->Deactivate(); + } + + // position and show the new panel + const PToolPanel pNewActive( !i_rNewActive ? m_pDummyPanel : m_aPanels.GetPanel( *i_rNewActive ) ); + pNewActive->Activate( m_aPanelAnchor ); + pNewActive->GrabFocus(); + + // resize the panel (cannot guarantee it has ever been resized before + pNewActive->SetSizePixel( m_aPanelAnchor.GetOutputSizePixel() ); + + // multiplex to our own listeners + m_aListeners.ActivePanelChanged( i_rOldActive, i_rNewActive ); + } + + //-------------------------------------------------------------------- + void ToolPanelDeck_Impl::LayouterChanged( const PDeckLayouter& i_rNewLayouter ) + { + // not interested in + (void)i_rNewLayouter; + } + + //-------------------------------------------------------------------- + void ToolPanelDeck_Impl::Dying() + { + // not interested in. Since the ToolPanelCollection is our member, this just means we ourself + // are dying, and we already sent this notification in our dtor. + } + + //-------------------------------------------------------------------- + void ToolPanelDeck_Impl::SetAccessibleParentWindow( Window* i_pAccessibleParent ) + { + m_pAccessibleParent = i_pAccessibleParent; + } + + //==================================================================== + //= ToolPanelDeck + //==================================================================== + //-------------------------------------------------------------------- + ToolPanelDeck::ToolPanelDeck( Window& i_rParent, const WinBits i_nStyle ) + :Control( &i_rParent, i_nStyle ) + ,m_pImpl( new ToolPanelDeck_Impl( *this ) ) + { + // use a default layouter + SetLayouter( PDeckLayouter( new TabDeckLayouter( *this, *this, TABS_RIGHT, TABITEM_IMAGE_AND_TEXT ) ) ); + } + + //-------------------------------------------------------------------- + ToolPanelDeck::~ToolPanelDeck() + { + m_pImpl->NotifyDying(); + GetLayouter()->Destroy(); + + Hide(); + for ( size_t i=0; i<GetPanelCount(); ++i ) + { + PToolPanel pPanel( GetPanel( i ) ); + pPanel->Dispose(); + } + } + + //-------------------------------------------------------------------- + size_t ToolPanelDeck::GetPanelCount() const + { + return m_pImpl->GetPanelCount(); + } + + //-------------------------------------------------------------------- + PToolPanel ToolPanelDeck::GetPanel( const size_t i_nPos ) const + { + return m_pImpl->GetPanel( i_nPos ); + } + + //-------------------------------------------------------------------- + ::boost::optional< size_t > ToolPanelDeck::GetActivePanel() const + { + return m_pImpl->GetActivePanel(); + } + + //-------------------------------------------------------------------- + void ToolPanelDeck::ActivatePanel( const ::boost::optional< size_t >& i_rPanel ) + { + m_pImpl->ActivatePanel( i_rPanel ); + } + + //-------------------------------------------------------------------- + size_t ToolPanelDeck::InsertPanel( const PToolPanel& i_pPanel, const size_t i_nPosition ) + { + return m_pImpl->InsertPanel( i_pPanel, i_nPosition ); + } + + //-------------------------------------------------------------------- + PToolPanel ToolPanelDeck::RemovePanel( const size_t i_nPosition ) + { + return m_pImpl->RemovePanel( i_nPosition ); + } + + //-------------------------------------------------------------------- + PDeckLayouter ToolPanelDeck::GetLayouter() const + { + return m_pImpl->GetLayouter(); + } + + //-------------------------------------------------------------------- + void ToolPanelDeck::SetLayouter( const PDeckLayouter& i_pNewLayouter ) + { + return m_pImpl->SetLayouter( i_pNewLayouter ); + } + + //-------------------------------------------------------------------- + void ToolPanelDeck::AddListener( IToolPanelDeckListener& i_rListener ) + { + m_pImpl->AddListener( i_rListener ); + } + + //-------------------------------------------------------------------- + void ToolPanelDeck::RemoveListener( IToolPanelDeckListener& i_rListener ) + { + m_pImpl->RemoveListener( i_rListener ); + } + + //-------------------------------------------------------------------- + Window& ToolPanelDeck::GetPanelWindowAnchor() + { + return m_pImpl->GetPanelWindowAnchor(); + } + + //-------------------------------------------------------------------- + void ToolPanelDeck::Resize() + { + Control::Resize(); + m_pImpl->LayoutAll(); + } + + //-------------------------------------------------------------------- + long ToolPanelDeck::Notify( NotifyEvent& i_rNotifyEvent ) + { + bool bHandled = false; + if ( i_rNotifyEvent.GetType() == EVENT_KEYINPUT ) + { + const KeyEvent* pEvent = i_rNotifyEvent.GetKeyEvent(); + const KeyCode& rKeyCode = pEvent->GetKeyCode(); + if ( rKeyCode.GetModifier() == KEY_MOD1 ) + { + bHandled = true; + switch ( rKeyCode.GetCode() ) + { + case KEY_HOME: + m_pImpl->DoAction( ACTION_ACTIVATE_FIRST ); + break; + case KEY_PAGEUP: + m_pImpl->DoAction( ACTION_ACTIVATE_PREV ); + break; + case KEY_PAGEDOWN: + m_pImpl->DoAction( ACTION_ACTIVATE_NEXT ); + break; + case KEY_END: + m_pImpl->DoAction( ACTION_ACTIVATE_LAST ); + break; + default: + bHandled = false; + break; + } + } + else if ( rKeyCode.GetModifier() == ( KEY_MOD1 | KEY_SHIFT ) ) + { + if ( rKeyCode.GetCode() == KEY_E ) + { + m_pImpl->DoAction( ACTION_TOGGLE_FOCUS ); + bHandled = true; + } + } + } + + if ( bHandled ) + return 1; + + return Control::Notify( i_rNotifyEvent ); + } + + //-------------------------------------------------------------------- + void ToolPanelDeck::GetFocus() + { + Control::GetFocus(); + m_pImpl->FocusActivePanel(); + } + + //-------------------------------------------------------------------- + void ToolPanelDeck::SetAccessibleParentWindow( Window* i_pAccessibleParent ) + { + m_pImpl->SetAccessibleParentWindow( i_pAccessibleParent ); + } + + //-------------------------------------------------------------------- + Window* ToolPanelDeck::GetAccessibleParentWindow() const + { + return m_pImpl->GetAccessibleParentWindow(); + } + + //-------------------------------------------------------------------- + Reference< XWindowPeer > ToolPanelDeck::GetComponentInterface( BOOL i_bCreate ) + { + Reference< XWindowPeer > xWindowPeer( Control::GetComponentInterface( FALSE ) ); + if ( !xWindowPeer.is() && i_bCreate ) + { + xWindowPeer.set( new ToolPanelDeckPeer( *this ) ); + SetComponentInterface( xWindowPeer ); + } + return xWindowPeer; + } + +//........................................................................ +} // namespace svt +//........................................................................ diff --git a/svtools/source/toolpanel/toolpaneldeckpeer.cxx b/svtools/source/toolpanel/toolpaneldeckpeer.cxx new file mode 100755 index 000000000000..0a84a90b4fb3 --- /dev/null +++ b/svtools/source/toolpanel/toolpaneldeckpeer.cxx @@ -0,0 +1,99 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "precompiled_svtools.hxx" + +#include "toolpaneldeckpeer.hxx" +#include "svtools/toolpanel/toolpaneldeck.hxx" + +/** === begin UNO includes === **/ +#include <com/sun/star/lang/DisposedException.hpp> +/** === end UNO includes === **/ + +#include <tools/diagnose_ex.h> + +//...................................................................................................................... +namespace svt +{ +//...................................................................................................................... + + /** === begin UNO using === **/ + using ::com::sun::star::uno::Reference; + using ::com::sun::star::uno::XInterface; + using ::com::sun::star::uno::UNO_QUERY; + using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::uno::UNO_SET_THROW; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::uno::RuntimeException; + using ::com::sun::star::uno::Any; + using ::com::sun::star::uno::makeAny; + using ::com::sun::star::uno::Sequence; + using ::com::sun::star::uno::Type; + using ::com::sun::star::accessibility::XAccessibleContext; + using ::com::sun::star::lang::DisposedException; + /** === end UNO using === **/ + + //================================================================================================================== + //= ToolPanelDeckPeer + //================================================================================================================== + //------------------------------------------------------------------------------------------------------------------ + ToolPanelDeckPeer::ToolPanelDeckPeer( ToolPanelDeck& i_rDeck ) + :VCLXWindow() + ,m_pDeck( &i_rDeck ) + { + } + + //------------------------------------------------------------------------------------------------------------------ + ToolPanelDeckPeer::~ToolPanelDeckPeer() + { + } + + //------------------------------------------------------------------------------------------------------------------ + Reference< XAccessibleContext > ToolPanelDeckPeer::CreateAccessibleContext() + { + ::vos::OGuard aSolarGuard( GetMutex() ); + if ( m_pDeck == NULL ) + throw DisposedException( ::rtl::OUString(), *this ); + + Window* pAccessibleParent( m_pDeck->GetAccessibleParentWindow() ); + ENSURE_OR_RETURN( pAccessibleParent != NULL, "no accessible parent => no accessible context", NULL ); + Reference< XAccessible > xAccessibleParent( pAccessibleParent->GetAccessible(), UNO_SET_THROW ); + return m_aAccessibleFactory.getFactory().createAccessibleToolPanelDeck( xAccessibleParent, *m_pDeck ); + } + + //------------------------------------------------------------------------------------------------------------------ + void SAL_CALL ToolPanelDeckPeer::dispose() throw(RuntimeException) + { + { + ::vos::OGuard aSolarGuard( GetMutex() ); + m_pDeck = NULL; + } + VCLXWindow::dispose(); + } + +//...................................................................................................................... +} // namespace svt +//...................................................................................................................... diff --git a/svtools/source/toolpanel/toolpaneldeckpeer.hxx b/svtools/source/toolpanel/toolpaneldeckpeer.hxx new file mode 100755 index 000000000000..4b6607ecbd05 --- /dev/null +++ b/svtools/source/toolpanel/toolpaneldeckpeer.hxx @@ -0,0 +1,69 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SVT_TOOLPANELDECKPEER_HXX +#define SVT_TOOLPANELDECKPEER_HXX + +#include "svtaccessiblefactory.hxx" + +/** === begin UNO includes === **/ +/** === end UNO includes === **/ + +#include <toolkit/awt/vclxwindow.hxx> + +//...................................................................................................................... +namespace svt +{ +//...................................................................................................................... + + class ToolPanelDeck; + //================================================================================================================== + //= ToolPanelDeckPeer + //================================================================================================================== + class ToolPanelDeckPeer : public VCLXWindow + { + public: + ToolPanelDeckPeer( ToolPanelDeck& i_rDeck ); + + protected: + ~ToolPanelDeckPeer(); + + // VCLXWindow overridables + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > CreateAccessibleContext(); + + // XComponent + void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException); + + private: + AccessibleFactoryAccess m_aAccessibleFactory; + ToolPanelDeck* m_pDeck; + }; + +//...................................................................................................................... +} // namespace svt +//...................................................................................................................... + +#endif // SVT_TOOLPANELDECKPEER_HXX diff --git a/svtools/source/uno/makefile.mk b/svtools/source/uno/makefile.mk index 7bfe37624947..4a52960f448c 100644 --- a/svtools/source/uno/makefile.mk +++ b/svtools/source/uno/makefile.mk @@ -38,9 +38,6 @@ ENABLE_EXCEPTIONS=TRUE # --- Files -------------------------------------------------------- -SRS1NAME= uno -SRC1FILES= unoifac2.src - SLOFILES= \ $(SLO)$/addrtempuno.obj \ $(SLO)$/contextmenuhelper.obj \ diff --git a/svtools/source/uno/unoifac2.src b/svtools/source/uno/unoifac2.src deleted file mode 100644 index 406701ca4fc1..000000000000 --- a/svtools/source/uno/unoifac2.src +++ /dev/null @@ -1,107 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - - - -#ifndef _SVT_UNO_UNOIFAC_HRC_ -#include <unoifac2.hrc> -#endif - - -Menu RID_CONTEXTMENU -{ - ItemList = - { - MenuItem - { - Identifier = RID_OPEN_LINK ; - HelpId = HID_TEXTCPNT_OPEN_LINK ; - Text [ en-US ] = "~Open"; - }; - MenuItem - { - Identifier = RID_OPEN_LINK_NEW ; - HelpId = HID_TEXTCPNT_OPEN_LINK_NEW ; - Text [ en-US ] = "Open in New ~Window"; - }; - MenuItem - { - Identifier = RID_DOWNLOAD ; - HelpId = HID_TEXTCPNT_DOWNLOAD ; - Text [ en-US ] = "~Download..."; - }; - MenuItem - { - Separator = TRUE; - }; - MenuItem - { - Identifier = RID_ADD_BOOKMARK ; - HelpId = HID_TEXTCPNT_ADD_BOOKMARK ; - Text [ en-US ] = "Add ~Link"; - }; - MenuItem - { - Separator = TRUE; - }; - MenuItem - { - Identifier = RID_COPY_LINK ; - HelpId = HID_TEXTCPNT_COPY_LINK ; - Text [ en-US ] = "Cop~y Link" ; - }; - }; -}; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/svtools/util/makefile.mk b/svtools/util/makefile.mk index ab05facdb065..0040b1d1ee65 100644 --- a/svtools/util/makefile.mk +++ b/svtools/util/makefile.mk @@ -48,30 +48,31 @@ LIB2TARGET= $(LB)$/svtool.lib LIB2FILES= $(LB)$/_svt.lib .ENDIF -LIB1TARGET= $(SLB)$/svt.lib +LIB1TARGET= $(SLB)/svt.lib LIB1FILES= \ - $(SLB)$/browse.lib \ - $(SLB)$/config.lib \ - $(SLB)$/svcontnr.lib \ - $(SLB)$/ctrl.lib \ - $(SLB)$/dialogs.lib \ - $(SLB)$/edit.lib \ - $(SLB)$/filter.lib \ - $(SLB)$/filter.uno.lib \ + $(SLB)/browse.lib \ + $(SLB)/config.lib \ + $(SLB)/svcontnr.lib \ + $(SLB)/ctrl.lib \ + $(SLB)/dialogs.lib \ + $(SLB)/edit.lib \ + $(SLB)/filter.lib \ + $(SLB)/filter.uno.lib \ $(SLB)$/graphic.lib \ - $(SLB)$/igif.lib \ - $(SLB)$/jpeg.lib \ - $(SLB)$/ixpm.lib \ - $(SLB)$/ixbm.lib \ - $(SLB)$/wmf.lib \ - $(SLB)$/java.lib \ - $(SLB)$/misc.lib \ - $(SLB)$/plugapp.lib \ - $(SLB)$/svhtml.lib \ - $(SLB)$/svrtf.lib \ - $(SLB)$/table.lib \ - $(SLB)$/unoiface.lib \ - $(SLB)$/urlobj.lib + $(SLB)/igif.lib \ + $(SLB)/jpeg.lib \ + $(SLB)/ixpm.lib \ + $(SLB)/ixbm.lib \ + $(SLB)/wmf.lib \ + $(SLB)/java.lib \ + $(SLB)/misc.lib \ + $(SLB)/plugapp.lib \ + $(SLB)/svhtml.lib \ + $(SLB)/svrtf.lib \ + $(SLB)/table.lib \ + $(SLB)/unoiface.lib \ + $(SLB)/urlobj.lib \ + $(SLB)/toolpanel.lib # generation of resourcen-lib ---------------------------------------- @@ -84,8 +85,8 @@ RESLIB1SRSFILES= \ $(SRS)$/dialogs.srs \ $(SRS)$/plugapp.srs \ $(SRS)$/svcontnr.srs \ - $(SRS)$/uno.srs \ $(SRS)$/browse.srs \ + $(SRS)$/toolpanel.srs \ $(SRS)$/javaerror.srs RESLIB3NAME= $(RESTARGETPATCH) diff --git a/svtools/workben/toolpanel/makefile.mk b/svtools/workben/toolpanel/makefile.mk new file mode 100644 index 000000000000..e64e3cd8eccd --- /dev/null +++ b/svtools/workben/toolpanel/makefile.mk @@ -0,0 +1,110 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.16 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=svtools +TARGET=toolpaneltest +TARGETTYPE=GUI +LIBTARGET=NO + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- + +CXXFILES= toolpaneltest.cxx + +OBJFILES= $(OBJ)$/toolpaneltest.obj + +APP1TARGET= $(TARGET) +APP1OBJS= $(OBJFILES) +APP1STDLIBS=\ + $(VCLLIB) \ + $(UCBHELPERLIB) \ + $(SALLIB) \ + $(TOOLSLIB) \ + $(COMPHELPERLIB) \ + $(CPPUHELPERLIB) \ + $(CPPULIB) \ + $(BASEGFXLIB) \ + $(SVTOOLLIB) \ + +APP1RAPTH=BRAND + +.IF "$(GUI)"!="UNX" +APP1DEF= $(MISC)$/$(TARGET).def +.ENDIF + +.IF "$(COM)"=="GCC" +ADDOPTFILES=$(OBJ)$/toolpaneltest.obj +add_cflagscxx="-frtti -fexceptions" +.ENDIF + + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + + +# ------------------------------------------------------------------ +# MAC +# ------------------------------------------------------------------ + +.IF "$(GUI)" == "MAC" + +$(MISC)$/$(TARGET).def: makefile + echo Kein Def-File fuer Applikationen auf Mac +.ENDIF + + +# ------------------------------------------------------------------ +# Windows +# ------------------------------------------------------------------ + +.IF "$(GUI)" == "WIN" + +$(MISC)$/$(TARGET).def: makefile + echo NAME $(TARGET) >$@ + echo DESCRIPTION 'ToolPanel - Testprogramm' >>$@ + echo EXETYPE WINDOWS >>$@ + echo STUB 'winSTUB.EXE' >>$@ + echo PROTMODE >>$@ + echo CODE PRELOAD MOVEABLE DISCARDABLE >>$@ + echo DATA PRELOAD MOVEABLE MULTIPLE >>$@ + echo HEAPSIZE 8192 >>$@ + echo STACKSIZE 32768 >>$@ + +.ENDIF + diff --git a/svtools/workben/toolpanel/toolpaneltest.cxx b/svtools/workben/toolpanel/toolpaneltest.cxx new file mode 100755 index 000000000000..148df941a254 --- /dev/null +++ b/svtools/workben/toolpanel/toolpaneltest.cxx @@ -0,0 +1,873 @@ +/************************************************************************* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2009 by Sun Microsystems, Inc. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General Public License +* version 3 along with OpenOffice.org. If not, see +* <http://www.openoffice.org/license.html> +* for a copy of the LGPLv3 License. +************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svtools.hxx" + +#include "svtools/ctrlbox.hxx" +#include "svtools/toolpanel/toolpaneldeck.hxx" +#include "svtools/toolpanel/tablayouter.hxx" + +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> + +#include <comphelper/processfactory.hxx> +#include <cppuhelper/bootstrap.hxx> +#include <cppuhelper/servicefactory.hxx> +#include <tools/diagnose_ex.h> +#include <ucbhelper/contentbroker.hxx> +#include <vcl/button.hxx> +#include <vcl/edit.hxx> +#include <vcl/fixed.hxx> +#include <vcl/help.hxx> +#include <vcl/lstbox.hxx> +#include <vcl/svapp.hxx> +#include <vcl/tabctrl.hxx> +#include <vcl/taskpanelist.hxx> +#include <vcl/wrkwin.hxx> + +namespace svt { namespace toolpanel +{ + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Any; +using ::com::sun::star::lang::XMultiServiceFactory; +using ::com::sun::star::uno::XComponentContext; +using ::com::sun::star::accessibility::XAccessible; + +//============================================================================= +//= PanelDemo +//============================================================================= +class PanelDemo : public Application +{ +public: + virtual void Main(); + +private: + static Reference< XMultiServiceFactory > createApplicationServiceManager(); +}; + +//============================================================================= +//= ColoredPanelWindow +//============================================================================= +class ColoredPanelWindow : public Window +{ +public: + ColoredPanelWindow( Window& i_rParent, const Color& i_rColor, const String& i_rTitle ) + :Window( &i_rParent ) + ,m_aEdit( this, WB_BORDER ) + ,m_aTabControl( this ) + ,m_sTitle( i_rTitle ) + { + SetLineColor(); + SetFillColor( i_rColor ); + + m_aEdit.Show(); + m_aTabControl.Show(); + + const sal_Char* pTabTitles[] = + { + "This", "is a", "Tab", "Control", "intended", "for", "comparison" + }; + for ( size_t i=0; i < sizeof( pTabTitles ) / sizeof( pTabTitles[0] ); ++i ) + { + String sText( String::CreateFromAscii( pTabTitles[i] ) ); + m_aTabControl.InsertPage( i + 1, sText ); + } + } + + virtual void Paint( const Rectangle& /*i_rRect*/ ) + { + const Size aOutputSize( GetOutputSizePixel() ); + const Rectangle aTitleRect( Point( 10, 10 ), Size( aOutputSize.Width() - 20, 20 ) ); + DrawRect( aTitleRect ); + SetTextColor( GetFillColor().IsDark() ? COL_WHITE : COL_BLACK ); + DrawText( aTitleRect, m_sTitle, TEXT_DRAW_CENTER | TEXT_DRAW_VCENTER ); + } + + virtual void GetFocus() + { + m_aEdit.GrabFocus(); + } + + virtual void Resize() + { + const Size aOutputSize( GetOutputSizePixel() ); + m_aEdit.SetPosSizePixel( + Point( 20, 40 ), + Size( aOutputSize.Width() - 40, 20 ) + ); + m_aTabControl.SetPosSizePixel( + Point( 20, 70 ), + Size( aOutputSize.Width() - 40, 150 ) + ); + } + +private: + Edit m_aEdit; + TabControl m_aTabControl; + String m_sTitle; +}; + +//============================================================================= +//= ColoredPanel +//============================================================================= +class ColoredPanel : public IToolPanel +{ +public: + ColoredPanel( Window& i_rParent, const Color& i_rColor, const sal_Char* i_pAsciiPanelName ); + ColoredPanel( Window& i_rParent, const Color& i_rColor, const String& i_rPanelName ); + ~ColoredPanel(); + + // IToolPanel + virtual ::rtl::OUString GetDisplayName() const; + virtual Image GetImage() const; + virtual void Activate( Window& i_rParentWindow ); + virtual void Deactivate(); + virtual void SetSizePixel( const Size& i_rPanelWindowSize ); + virtual void GrabFocus(); + virtual void Dispose(); + virtual Reference< XAccessible > CreatePanelAccessible( const Reference< XAccessible >& i_rParentAccessible ); + + // IReference + virtual oslInterlockedCount SAL_CALL acquire(); + virtual oslInterlockedCount SAL_CALL release(); + +private: + oslInterlockedCount m_refCount; + ::std::auto_ptr< ColoredPanelWindow > + m_pWindow; + ::rtl::OUString m_aPanelName; + BitmapEx m_aPanelIcon; +}; + +//============================================================================= +//= ColoredPanel +//============================================================================= +//----------------------------------------------------------------------------- +ColoredPanel::ColoredPanel( Window& i_rParent, const Color& i_rColor, const sal_Char* i_pAsciiPanelName ) + :m_refCount(0) + ,m_pWindow( new ColoredPanelWindow( i_rParent, i_rColor, ::rtl::OUString::createFromAscii( i_pAsciiPanelName ) ) ) + ,m_aPanelName( ::rtl::OUString::createFromAscii( i_pAsciiPanelName ) ) + ,m_aPanelIcon() +{ + Bitmap aBitmap( Size( 16, 16 ), 8 ); + m_aPanelIcon = BitmapEx( aBitmap ); + m_aPanelIcon.Erase( i_rColor ); +} + +//----------------------------------------------------------------------------- +ColoredPanel::ColoredPanel( Window& i_rParent, const Color& i_rColor, const String& i_rPanelName ) + :m_refCount(0) + ,m_pWindow( new ColoredPanelWindow( i_rParent, i_rColor, i_rPanelName ) ) + ,m_aPanelName( i_rPanelName ) + ,m_aPanelIcon() +{ + Bitmap aBitmap( Size( 16, 16 ), 8 ); + m_aPanelIcon = BitmapEx( aBitmap ); + m_aPanelIcon.Erase( i_rColor ); +} + +//----------------------------------------------------------------------------- +ColoredPanel::~ColoredPanel() +{ +} + +//----------------------------------------------------------------------------- +oslInterlockedCount SAL_CALL ColoredPanel::acquire() +{ + return osl_incrementInterlockedCount( &m_refCount ); +} + +//----------------------------------------------------------------------------- +oslInterlockedCount SAL_CALL ColoredPanel::release() +{ + oslInterlockedCount newCount = osl_decrementInterlockedCount( &m_refCount ); + if ( 0 == newCount ) + delete this; + return newCount; +} + +//----------------------------------------------------------------------------- +void ColoredPanel::Activate( Window& i_rParentWindow ) +{ + ENSURE_OR_RETURN_VOID( m_pWindow.get(), "disposed!" ); + OSL_ENSURE( &i_rParentWindow == m_pWindow->GetParent(), "ColoredPanel::Activate: unexpected new parent window!" ); + // the documentation of IToolPanel::Activate says it is guaranteed that the parent window is + // always the same ... + m_pWindow->SetPosSizePixel( Point(), i_rParentWindow.GetSizePixel() ); + m_pWindow->Show(); +} + +//----------------------------------------------------------------------------- +void ColoredPanel::Deactivate() +{ + ENSURE_OR_RETURN_VOID( m_pWindow.get(), "disposed!" ); + m_pWindow->Hide(); +} + +//----------------------------------------------------------------------------- +void ColoredPanel::SetSizePixel( const Size& i_rPanelWindowSize ) +{ + ENSURE_OR_RETURN_VOID( m_pWindow.get(), "disposed!" ); + m_pWindow->SetSizePixel( i_rPanelWindowSize ); +} + +//----------------------------------------------------------------------------- +void ColoredPanel::GrabFocus() +{ + ENSURE_OR_RETURN_VOID( m_pWindow.get(), "disposed!" ); + m_pWindow->GrabFocus(); +} + +//----------------------------------------------------------------------------- +void ColoredPanel::Dispose() +{ + ENSURE_OR_RETURN_VOID( m_pWindow.get(), "disposed!" ); + m_pWindow.reset(); +} + +//----------------------------------------------------------------------------- +Reference< XAccessible > ColoredPanel::CreatePanelAccessible( const Reference< XAccessible >& i_rParentAccessible ) +{ + ENSURE_OR_RETURN( m_pWindow.get(), "disposed!", NULL ); + (void)i_rParentAccessible; + return m_pWindow->GetAccessible(); +} + +//----------------------------------------------------------------------------- +::rtl::OUString ColoredPanel::GetDisplayName() const +{ + return m_aPanelName; +} + +//----------------------------------------------------------------------------- +Image ColoredPanel::GetImage() const +{ + return Image( m_aPanelIcon ); +} + +//============================================================================= +//= OptionsWindow +//============================================================================= +class PanelDemoMainWindow; +class OptionsWindow :public Window + ,public ::svt::IToolPanelDeckListener +{ +public: + OptionsWindow( PanelDemoMainWindow& i_rParent ); + ~OptionsWindow(); + + // Window overridables + virtual void Resize(); + virtual void GetFocus(); + virtual void StateChanged( StateChangedType i_nStateChange ); + + // IToolPanelDeckListener + virtual void PanelInserted( const PToolPanel& i_pPanel, const size_t i_nPosition ); + virtual void PanelRemoved( const size_t i_nPosition ); + virtual void ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive ); + virtual void LayouterChanged( const PDeckLayouter& i_rNewLayouter ); + virtual void Dying(); + +private: + DECL_LINK( OnRadioToggled, RadioButton* ); + DECL_LINK( OnListEntrySelected, ListBox* ); + DECL_LINK( OnListEntryDoubleClicked, ListBox* ); + DECL_LINK( OnButtonClicked, PushButton* ); + DECL_LINK( OnEditModified, Edit* ); + + void impl_initPanelList(); + void impl_updateRemoveButton(); + void impl_updateInsertButton(); + +private: + FixedLine m_aAlignmentHeader; + RadioButton m_aAlignLeft; + RadioButton m_aAlignRight; + RadioButton m_aAlignTop; + RadioButton m_aAlignBottom; + FixedLine m_aTabItemContent; + RadioButton m_aImagesAndText; + RadioButton m_aImagesOnly; + RadioButton m_aTextOnly; + RadioButton m_aAutomaticContent; + + FixedLine m_aPanelsHeader; + ListBox m_aPanelList; + PushButton m_aRemovePanel; + ColorListBox m_aColors; + Edit m_aNewPanelName; + PushButton m_aInsertPanel; +}; + +//============================================================================= +//= PanelDemoMainWindow +//============================================================================= +class PanelDemoMainWindow : public WorkWindow +{ +public: + PanelDemoMainWindow(); + ~PanelDemoMainWindow(); + + // window overridables + virtual void Resize(); + +public: + // operations + void AlignTabs( const ::svt::TabAlignment i_eAlignment ); + void SetTabItemContent( const TabItemContent i_eItemContent ); + + // member access + IToolPanelDeck& GetToolPanelDeck(); + PToolPanel CreateToolPanel( const Color& i_rColor, const String& i_rPanelName ); + +protected: + virtual void GetFocus(); + +private: + ToolPanelDeck m_aToolPanelDeck; + OptionsWindow m_aDemoOptions; +}; + +//============================================================================= +//= PanelDemoMainWindow - implementation +//============================================================================= +//----------------------------------------------------------------------------- +OptionsWindow::OptionsWindow( PanelDemoMainWindow& i_rParent ) + :Window( &i_rParent, WB_BORDER | WB_DIALOGCONTROL ) + ,m_aAlignmentHeader( this ) + ,m_aAlignLeft( this, WB_GROUP ) + ,m_aAlignRight( this, 0 ) + ,m_aAlignTop( this, 0 ) + ,m_aAlignBottom( this, 0 ) + ,m_aTabItemContent( this ) + ,m_aImagesAndText( this ) + ,m_aImagesOnly( this ) + ,m_aTextOnly( this ) + ,m_aAutomaticContent( this ) + ,m_aPanelsHeader( this ) + ,m_aPanelList( this ) + ,m_aRemovePanel( this ) + ,m_aColors( this, WB_DROPDOWN ) + ,m_aNewPanelName( this, WB_BORDER ) + ,m_aInsertPanel( this ) +{ + SetBorderStyle( WINDOW_BORDER_MONO ); + + m_aColors.InsertEntry( Color( COL_BLACK ), String( RTL_CONSTASCII_USTRINGPARAM( "Black" ) ) ); + m_aColors.InsertEntry( Color( COL_BLUE ), String( RTL_CONSTASCII_USTRINGPARAM( "Blue" ) ) ); + m_aColors.InsertEntry( Color( COL_GREEN ), String( RTL_CONSTASCII_USTRINGPARAM( "Green" ) ) ); + m_aColors.InsertEntry( Color( COL_CYAN ), String( RTL_CONSTASCII_USTRINGPARAM( "Cyan" ) ) ); + m_aColors.InsertEntry( Color( COL_RED ), String( RTL_CONSTASCII_USTRINGPARAM( "Red" ) ) ); + m_aColors.InsertEntry( Color( COL_MAGENTA ), String( RTL_CONSTASCII_USTRINGPARAM( "Magenta" ) ) ); + m_aColors.InsertEntry( Color( COL_BROWN ), String( RTL_CONSTASCII_USTRINGPARAM( "Brown" ) ) ); + m_aColors.InsertEntry( Color( COL_GRAY ), String( RTL_CONSTASCII_USTRINGPARAM( "Gray" ) ) ); + m_aColors.InsertEntry( Color( COL_LIGHTGRAY ), String( RTL_CONSTASCII_USTRINGPARAM( "Light Gray" ) ) ); + m_aColors.InsertEntry( Color( COL_LIGHTBLUE ), String( RTL_CONSTASCII_USTRINGPARAM( "Light Blue" ) ) ); + m_aColors.InsertEntry( Color( COL_LIGHTGREEN ), String( RTL_CONSTASCII_USTRINGPARAM( "Light Green" ) ) ); + m_aColors.InsertEntry( Color( COL_LIGHTCYAN ), String( RTL_CONSTASCII_USTRINGPARAM( "Light Cyan" ) ) ); + m_aColors.InsertEntry( Color( COL_LIGHTRED ), String( RTL_CONSTASCII_USTRINGPARAM( "Light Red" ) ) ); + m_aColors.InsertEntry( Color( COL_LIGHTMAGENTA ), String( RTL_CONSTASCII_USTRINGPARAM( "Light Magenta" ) ) ); + m_aColors.InsertEntry( Color( COL_YELLOW ), String( RTL_CONSTASCII_USTRINGPARAM( "Yellow" ) ) ); + m_aColors.InsertEntry( Color( COL_WHITE ), String( RTL_CONSTASCII_USTRINGPARAM( "White" ) ) ); + m_aColors.SetDropDownLineCount( 16 ); + + Window* pControls[] = + { + &m_aAlignmentHeader, &m_aAlignLeft, &m_aAlignRight, &m_aAlignTop, &m_aAlignBottom, &m_aTabItemContent, + &m_aImagesAndText, &m_aImagesOnly, &m_aTextOnly, &m_aAutomaticContent, &m_aPanelsHeader, &m_aPanelList, + &m_aRemovePanel, &m_aColors, &m_aNewPanelName, &m_aInsertPanel + }; + const sal_Char* pTexts[] = + { + "Tab Bar Alignment", "Left", "Right", "Top", "Bottom", "Tab Items", "Images and Text", "Images only", + "Text only", "Automatic", "Panels", "", "Remove Panel", "", "", "Insert Panel" + }; + for ( size_t i=0; i < sizeof( pControls ) / sizeof( pControls[0] ); ++i ) + { + const WindowType eWindowType = pControls[i]->GetType(); + + pControls[i]->SetText( String::CreateFromAscii( pTexts[i] ) ); + pControls[i]->Show(); + + if ( eWindowType == WINDOW_RADIOBUTTON ) + static_cast< RadioButton* >( pControls[i] )->SetToggleHdl( LINK( this, OptionsWindow, OnRadioToggled ) ); + + if ( eWindowType == WINDOW_LISTBOX ) + { + static_cast< ListBox* >( pControls[i] )->SetSelectHdl( LINK( this, OptionsWindow, OnListEntrySelected ) ); + static_cast< ListBox* >( pControls[i] )->SetDoubleClickHdl( LINK( this, OptionsWindow, OnListEntryDoubleClicked ) ); + } + + if ( eWindowType == WINDOW_PUSHBUTTON ) + { + static_cast< PushButton* >( pControls[i] )->SetClickHdl( LINK( this, OptionsWindow, OnButtonClicked ) ); + } + + if ( eWindowType == WINDOW_EDIT ) + { + static_cast< Edit* >( pControls[i] )->SetModifyHdl( LINK( this, OptionsWindow, OnEditModified ) ); + } + } + + m_aAlignRight.Check(); + m_aImagesAndText.Check(); + + Show(); +} + +//----------------------------------------------------------------------------- +OptionsWindow::~OptionsWindow() +{ +} + +//----------------------------------------------------------------------------- +void OptionsWindow::impl_updateInsertButton() +{ + m_aInsertPanel.Enable( ( m_aColors.GetSelectEntryPos() != LISTBOX_ENTRY_NOTFOUND ) && ( m_aNewPanelName.GetText().Len() > 0 ) ); +} + +//----------------------------------------------------------------------------- +void OptionsWindow::impl_updateRemoveButton() +{ + m_aRemovePanel.Enable( m_aPanelList.GetSelectEntryCount() > 0 ); +} + +//----------------------------------------------------------------------------- +void OptionsWindow::impl_initPanelList() +{ + m_aPanelList.Clear(); + + PanelDemoMainWindow& rController( dynamic_cast< PanelDemoMainWindow& >( *GetParent() ) ); + IToolPanelDeck& rPanelDeck( rController.GetToolPanelDeck() ); + + for ( size_t i=0; i<rPanelDeck.GetPanelCount(); ++i ) + { + PToolPanel pPanel = rPanelDeck.GetPanel( i ); + m_aPanelList.InsertEntry( pPanel->GetDisplayName(), pPanel->GetImage() ); + } + ActivePanelChanged( ::boost::optional< size_t >(), rPanelDeck.GetActivePanel() ); + + impl_updateRemoveButton(); + impl_updateInsertButton(); + + rPanelDeck.AddListener( *this ); +} + +//----------------------------------------------------------------------------- +void OptionsWindow::StateChanged( StateChangedType i_nStateChange ) +{ + Window::StateChanged( i_nStateChange ); + + if ( i_nStateChange == STATE_CHANGE_INITSHOW ) + { + impl_initPanelList(); + } +} + +//----------------------------------------------------------------------------- +void OptionsWindow::GetFocus() +{ + Window::GetFocus(); + RadioButton* pRadios[] = + { + &m_aAlignLeft, &m_aAlignRight, &m_aAlignTop, &m_aAlignBottom + }; + for ( size_t i=0; i < sizeof( pRadios ) / sizeof( pRadios[0] ); ++i ) + { + if ( pRadios[i]->IsChecked() ) + { + pRadios[i]->GrabFocus(); + break; + } + } +} + +//----------------------------------------------------------------------------- +void OptionsWindow::Resize() +{ + Window::Resize(); + + const Size aOutputSize( GetOutputSizePixel() ); + + const Size aSpacing( LogicToPixel( Size( 3, 3 ), MAP_APPFONT ) ); + const long nIndent( LogicToPixel( Size( 6, 9 ), MAP_APPFONT ).Width() ); + const long nFixedLineHeight( LogicToPixel( Size( 0, 8 ), MAP_APPFONT ).Height() ); + const long nEditLineHeight( LogicToPixel( Size( 0, 12 ), MAP_APPFONT ).Height() ); + const long nButtonLineHeight( LogicToPixel( Size( 0, 14 ), MAP_APPFONT ).Height() ); + + const long nSuperordinateWidth = aOutputSize.Width() - 2 * aSpacing.Width(); + const long nSuperordinateX = aSpacing.Width(); + + const long nSubordinateWidth = aOutputSize.Width() - 2 * aSpacing.Width() - nIndent; + const long nSubordinateX = aSpacing.Width() + nIndent; + + Point aItemPos( nSuperordinateX, aSpacing.Height() ); + + struct ControlRow + { + Window* pWindow; + bool bSubordinate; + size_t nRows; + + ControlRow( Window& i_rWindow, const bool i_bSubordinate, const size_t i_nRows = 1 ) + :pWindow( &i_rWindow ) + ,bSubordinate( i_bSubordinate ) + ,nRows( i_nRows ) + { + } + }; + ControlRow aControlRows[] = + { + ControlRow( m_aAlignmentHeader, false ), + ControlRow( m_aAlignLeft, true ), + ControlRow( m_aAlignRight, true ), + ControlRow( m_aAlignTop, true ), + ControlRow( m_aAlignBottom, true ), + ControlRow( m_aTabItemContent, false ), + ControlRow( m_aImagesAndText, true ), + ControlRow( m_aImagesOnly, true ), + ControlRow( m_aTextOnly, true ), + ControlRow( m_aAutomaticContent, true ), + ControlRow( m_aPanelsHeader, false ), + ControlRow( m_aPanelList, true, 6 ), + ControlRow( m_aRemovePanel, true ), + ControlRow( m_aColors, true ), + ControlRow( m_aNewPanelName, true ), + ControlRow( m_aInsertPanel, true ) + }; + bool bPreviousWasSubordinate = false; + for ( size_t i=0; i < sizeof( aControlRows ) / sizeof( aControlRows[0] ); ++i ) + { + aItemPos.X() = ( aControlRows[i].bSubordinate ) ? nSubordinateX : nSuperordinateX; + + if ( bPreviousWasSubordinate && !aControlRows[i].bSubordinate ) + aItemPos.Y() += aSpacing.Height(); + bPreviousWasSubordinate = aControlRows[i].bSubordinate; + + // height depends on the window type + const WindowType eWindowType = aControlRows[i].pWindow->GetType(); + long nControlHeight( nFixedLineHeight ); + if ( ( eWindowType == WINDOW_EDIT ) + || ( eWindowType == WINDOW_LISTBOX ) + ) + { + nControlHeight = nEditLineHeight; + } + else + if ( ( eWindowType == WINDOW_PUSHBUTTON ) + ) + { + nControlHeight = nButtonLineHeight; + } + + Size aControlSize( + aControlRows[i].bSubordinate ? nSubordinateWidth : nSuperordinateWidth, + nControlHeight * aControlRows[i].nRows + ); + aControlRows[i].pWindow->SetPosSizePixel( aItemPos, aControlSize ); + + aItemPos.Move( 0, aControlSize.Height() + aSpacing.Height() ); + } +} + +//----------------------------------------------------------------------------- +void OptionsWindow::PanelInserted( const PToolPanel& i_pPanel, const size_t i_nPosition ) +{ + m_aPanelList.InsertEntry( i_pPanel->GetDisplayName(), i_pPanel->GetImage(), USHORT( i_nPosition ) ); +} + +//----------------------------------------------------------------------------- +void OptionsWindow::PanelRemoved( const size_t i_nPosition ) +{ + m_aPanelList.RemoveEntry( USHORT( i_nPosition ) ); + impl_updateRemoveButton(); +} + +//----------------------------------------------------------------------------- +void OptionsWindow::ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive ) +{ + (void)i_rOldActive; + + if ( !i_rNewActive ) + m_aPanelList.SetNoSelection(); + else + m_aPanelList.SelectEntryPos( USHORT( *i_rNewActive ) ); +} + +//----------------------------------------------------------------------------- +void OptionsWindow::LayouterChanged( const PDeckLayouter& i_rNewLayouter ) +{ + (void)i_rNewLayouter; + // not interested in +} + +//----------------------------------------------------------------------------- +void OptionsWindow::Dying() +{ + // not interested in +} + +//----------------------------------------------------------------------------- +IMPL_LINK( OptionsWindow, OnListEntrySelected, ListBox*, i_pListBox ) +{ + if ( i_pListBox == &m_aColors ) + { + m_aNewPanelName.SetText( m_aColors.GetEntry( m_aColors.GetSelectEntryPos() ) ); + impl_updateInsertButton(); + } + else if ( i_pListBox == &m_aPanelList ) + { + impl_updateRemoveButton(); + } + return 0L; +} + +//----------------------------------------------------------------------------- +IMPL_LINK( OptionsWindow, OnListEntryDoubleClicked, ListBox*, i_pListBox ) +{ + PanelDemoMainWindow& rController( dynamic_cast< PanelDemoMainWindow& >( *GetParent() ) ); + + if ( i_pListBox == &m_aPanelList ) + { + size_t nActivatePanel = size_t( m_aPanelList.GetSelectEntryPos() ); + rController.GetToolPanelDeck().ActivatePanel( nActivatePanel ); + } + + return 0L; +} + +//----------------------------------------------------------------------------- +IMPL_LINK( OptionsWindow, OnEditModified, Edit*, i_pEdit ) +{ + if ( i_pEdit && &m_aNewPanelName ) + { + impl_updateInsertButton(); + } + + return 0L; +} + +//----------------------------------------------------------------------------- +IMPL_LINK( OptionsWindow, OnButtonClicked, PushButton*, i_pPushButton ) +{ + PanelDemoMainWindow& rController( dynamic_cast< PanelDemoMainWindow& >( *GetParent() ) ); + + if ( i_pPushButton == &m_aRemovePanel ) + { + rController.GetToolPanelDeck().RemovePanel( size_t( m_aPanelList.GetSelectEntryPos() ) ); + } + else if ( i_pPushButton == &m_aInsertPanel ) + { + PToolPanel pNewPanel( rController.CreateToolPanel( m_aColors.GetEntryColor( m_aColors.GetSelectEntryPos() ), m_aNewPanelName.GetText() ) ); + + ::boost::optional< size_t > aActivePanel( rController.GetToolPanelDeck().GetActivePanel() ); + size_t nNewPanelPos = !aActivePanel ? rController.GetToolPanelDeck().GetPanelCount() : *aActivePanel + 1; + + rController.GetToolPanelDeck().InsertPanel( pNewPanel, nNewPanelPos ); + } + return 0L; +} + +//----------------------------------------------------------------------------- +IMPL_LINK( OptionsWindow, OnRadioToggled, RadioButton*, i_pRadioButton ) +{ + PanelDemoMainWindow& rController( dynamic_cast< PanelDemoMainWindow& >( *GetParent() ) ); + + if ( i_pRadioButton->IsChecked() ) + { + if ( i_pRadioButton == &m_aAlignLeft ) + { + rController.AlignTabs( TABS_LEFT ); + } + else if ( i_pRadioButton == &m_aAlignRight ) + { + rController.AlignTabs( TABS_RIGHT ); + } + else if ( i_pRadioButton == &m_aAlignTop ) + { + rController.AlignTabs( TABS_TOP ); + } + else if ( i_pRadioButton == &m_aAlignBottom ) + { + rController.AlignTabs( TABS_BOTTOM ); + } + else if ( i_pRadioButton == &m_aImagesAndText ) + { + rController.SetTabItemContent( TABITEM_IMAGE_AND_TEXT ); + } + else if ( i_pRadioButton == &m_aImagesOnly ) + { + rController.SetTabItemContent( TABITEM_IMAGE_ONLY ); + } + else if ( i_pRadioButton == &m_aTextOnly ) + { + rController.SetTabItemContent( TABITEM_TEXT_ONLY ); + } + else if ( i_pRadioButton == &m_aAutomaticContent ) + { + rController.SetTabItemContent( TABITEM_AUTO ); + } + } + return 0L; +} +//============================================================================= +//= PanelDemoMainWindow - implementation +//============================================================================= +//----------------------------------------------------------------------------- +PanelDemoMainWindow::PanelDemoMainWindow() + :WorkWindow( NULL, WB_APP | WB_STDWORK | WB_CLIPCHILDREN ) + ,m_aToolPanelDeck( *this, WB_BORDER ) + ,m_aDemoOptions( *this ) +{ + m_aToolPanelDeck.SetPosSizePixel( Point( 20, 20 ), Size( 500, 300 ) ); + m_aToolPanelDeck.SetBorderStyle( WINDOW_BORDER_MONO ); + + m_aToolPanelDeck.InsertPanel( PToolPanel( new ColoredPanel( m_aToolPanelDeck.GetPanelWindowAnchor(), Color( COL_RED ), "Red" ) ), m_aToolPanelDeck.GetPanelCount() ); + m_aToolPanelDeck.InsertPanel( PToolPanel( new ColoredPanel( m_aToolPanelDeck.GetPanelWindowAnchor(), Color( COL_GREEN ), "Some flavor of Green" ) ), m_aToolPanelDeck.GetPanelCount() ); + m_aToolPanelDeck.InsertPanel( PToolPanel( new ColoredPanel( m_aToolPanelDeck.GetPanelWindowAnchor(), RGB_COLORDATA( 255, 255, 0 ), "Yellow is ugly" ) ), m_aToolPanelDeck.GetPanelCount() ); + m_aToolPanelDeck.InsertPanel( PToolPanel( new ColoredPanel( m_aToolPanelDeck.GetPanelWindowAnchor(), RGB_COLORDATA( 0, 0, 128 ), "Blue is the Color" ) ), m_aToolPanelDeck.GetPanelCount() ); + + m_aToolPanelDeck.ActivatePanel( size_t( 0 ) ); + m_aToolPanelDeck.Show(); + + SetText( String::CreateFromAscii( "ToolPanelDeck Demo Application" ) ); + Show(); + + Help::EnableQuickHelp(); + + GetSystemWindow()->GetTaskPaneList()->AddWindow( &m_aToolPanelDeck ); + GetSystemWindow()->GetTaskPaneList()->AddWindow( &m_aDemoOptions ); +} + +//----------------------------------------------------------------------------- +PanelDemoMainWindow::~PanelDemoMainWindow() +{ + GetSystemWindow()->GetTaskPaneList()->RemoveWindow( &m_aDemoOptions ); + GetSystemWindow()->GetTaskPaneList()->RemoveWindow( &m_aToolPanelDeck ); +} + +//----------------------------------------------------------------------------- +void PanelDemoMainWindow::GetFocus() +{ + WorkWindow::GetFocus(); + m_aToolPanelDeck.GrabFocus(); +} + +//----------------------------------------------------------------------------- +void PanelDemoMainWindow::Resize() +{ + WorkWindow::Resize(); + Size aSize( GetOutputSizePixel() ); + aSize.Width() -= 240; + aSize.Height() -= 40; + m_aToolPanelDeck.SetPosSizePixel( Point( 20, 20 ), aSize ); + + m_aDemoOptions.SetPosSizePixel( + Point( 20 + aSize.Width(), 20 ), + Size( 200, aSize.Height() ) + ); +} + +//----------------------------------------------------------------------------- +void PanelDemoMainWindow::AlignTabs( const ::svt::TabAlignment i_eAlignment ) +{ + TabItemContent eCurrentItemContent( TABITEM_IMAGE_AND_TEXT ); + TabDeckLayouter* pLayouter = dynamic_cast< TabDeckLayouter* >( m_aToolPanelDeck.GetLayouter().get() ); + OSL_ENSURE( pLayouter, "PanelDemoMainWindow::AlignTabs: wrong layouter!" ); + if ( pLayouter ) + eCurrentItemContent = pLayouter->GetTabItemContent(); + + m_aToolPanelDeck.SetLayouter( PDeckLayouter( new TabDeckLayouter( m_aToolPanelDeck, m_aToolPanelDeck, i_eAlignment, eCurrentItemContent ) ) ); +} + +//----------------------------------------------------------------------------- +void PanelDemoMainWindow::SetTabItemContent( const TabItemContent i_eItemContent ) +{ + TabDeckLayouter* pLayouter = dynamic_cast< TabDeckLayouter* >( m_aToolPanelDeck.GetLayouter().get() ); + OSL_ENSURE( pLayouter, "PanelDemoMainWindow::SetTabItemContent: wrong layouter!" ); + // we currently use tab layouters only ... + if ( !pLayouter ) + return; + + pLayouter->SetTabItemContent( i_eItemContent ); +} + +//----------------------------------------------------------------------------- +IToolPanelDeck& PanelDemoMainWindow::GetToolPanelDeck() +{ + return m_aToolPanelDeck; +} + +//----------------------------------------------------------------------------- +PToolPanel PanelDemoMainWindow::CreateToolPanel( const Color& i_rColor, const String& i_rPanelName ) +{ + return PToolPanel( new ColoredPanel( m_aToolPanelDeck.GetPanelWindowAnchor(), i_rColor, i_rPanelName ) ); +} + +//============================================================================= +//= PanelDemo +//============================================================================= +//----------------------------------------------------------------------------- +Reference< XMultiServiceFactory > PanelDemo::createApplicationServiceManager() +{ + Reference< XMultiServiceFactory > xMS; + try + { + Reference< XComponentContext > xComponentContext = ::cppu::defaultBootstrap_InitialComponentContext(); + if ( xComponentContext.is() ) + xMS = xMS.query( xComponentContext->getServiceManager() ); + } + catch( const ::com::sun::star::uno::Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + return xMS; +} + +//----------------------------------------------------------------------------- +void __EXPORT PanelDemo::Main() +{ + // create service factory + Reference< XMultiServiceFactory > xSMgr = createApplicationServiceManager(); + ::comphelper::setProcessServiceFactory( xSMgr ); + + // initialize the UCB + Sequence< Any > aArgs(2); + aArgs[0] <<= rtl::OUString::createFromAscii( "Local" ); + aArgs[1] <<= rtl::OUString::createFromAscii( "Office" ); + ::ucbhelper::ContentBroker::initialize( xSMgr, aArgs ); + + // run the application + PanelDemoMainWindow aWindow; + Execute(); +} + +PanelDemo aTheApplication; + +} } // namespace ::svt::toolpanel |