summaryrefslogtreecommitdiff
path: root/svtools/source
diff options
context:
space:
mode:
Diffstat (limited to 'svtools/source')
-rw-r--r--svtools/source/brwbox/brwbox1.cxx5
-rw-r--r--svtools/source/brwbox/brwbox2.cxx15
-rw-r--r--svtools/source/brwbox/brwbox3.cxx2
-rw-r--r--svtools/source/brwbox/datwin.hxx1
-rw-r--r--svtools/source/brwbox/editbrowsebox.cxx2
-rw-r--r--svtools/source/brwbox/editbrowsebox.src2
-rw-r--r--svtools/source/contnr/fileview.cxx2
-rw-r--r--svtools/source/contnr/fileview.src2
-rw-r--r--svtools/source/contnr/svcontnr.src2
-rw-r--r--svtools/source/contnr/svimpbox.cxx2
-rw-r--r--svtools/source/contnr/svtabbx.cxx4
-rw-r--r--svtools/source/contnr/svtreebx.cxx4
-rw-r--r--svtools/source/contnr/templwin.cxx2
-rw-r--r--svtools/source/contnr/templwin.src2
-rwxr-xr-x[-rw-r--r--]svtools/source/control/calendar.cxx2
-rwxr-xr-x[-rw-r--r--]svtools/source/control/calendar.src2
-rwxr-xr-x[-rw-r--r--]svtools/source/control/collatorres.cxx2
-rwxr-xr-x[-rw-r--r--]svtools/source/control/ctrlbox.cxx2
-rwxr-xr-x[-rw-r--r--]svtools/source/control/ctrlbox.src2
-rwxr-xr-x[-rw-r--r--]svtools/source/control/ctrltool.cxx2
-rwxr-xr-x[-rw-r--r--]svtools/source/control/ctrltool.src2
-rwxr-xr-x[-rw-r--r--]svtools/source/control/indexentryres.cxx2
-rwxr-xr-x[-rw-r--r--]svtools/source/control/makefile.mk4
-rw-r--r--svtools/source/control/toolbarmenu.cxx1805
-rw-r--r--svtools/source/control/toolbarmenuacc.cxx1003
-rw-r--r--svtools/source/control/toolbarmenuimp.hxx314
-rw-r--r--svtools/source/control/valueacc.cxx7
-rwxr-xr-x[-rw-r--r--]svtools/source/control/valueimp.hxx1
-rw-r--r--svtools/source/control/valueset.cxx51
-rw-r--r--svtools/source/dialogs/addresstemplate.cxx2
-rw-r--r--svtools/source/dialogs/addresstemplate.src2
-rw-r--r--svtools/source/dialogs/logindlg.cxx2
-rw-r--r--svtools/source/dialogs/logindlg.src2
-rw-r--r--svtools/source/dialogs/printdlg.hrc2
-rw-r--r--svtools/source/dialogs/prnsetup.hrc2
-rw-r--r--svtools/source/dialogs/roadmapwizard.cxx2
-rw-r--r--svtools/source/dialogs/wizardmachine.cxx2
-rw-r--r--svtools/source/dialogs/wizardmachine.src2
-rw-r--r--svtools/source/filter.vcl/filter/dlgejpg.hrc2
-rw-r--r--svtools/source/filter.vcl/filter/dlgepng.hrc2
-rw-r--r--svtools/source/filter.vcl/filter/dlgexpor.hrc2
-rw-r--r--svtools/source/filter.vcl/filter/strings.hrc2
-rw-r--r--svtools/source/inc/iodlg.hrc2
-rw-r--r--svtools/source/java/javaerror.src2
-rw-r--r--svtools/source/java/javainteractionhandler.cxx2
-rw-r--r--svtools/source/java/patchjavaerror.src2
-rw-r--r--svtools/source/misc/ehdl.cxx2
-rw-r--r--svtools/source/misc/ehdl.src2
-rw-r--r--svtools/source/misc/embedhlp.cxx2
-rw-r--r--svtools/source/misc/errtxt.src2
-rw-r--r--svtools/source/misc/helpagent.src2
-rw-r--r--svtools/source/misc/helpagentwindow.cxx2
-rw-r--r--svtools/source/misc/imagemgr.cxx2
-rw-r--r--svtools/source/misc/imagemgr.src2
-rw-r--r--[-rwxr-xr-x]svtools/source/misc/langtab.cxx2
-rw-r--r--svtools/source/misc/langtab.src2
-rwxr-xr-x[-rw-r--r--]svtools/source/misc/svtaccessiblefactory.cxx18
-rw-r--r--svtools/source/productregistration/productregistration.cxx2
-rw-r--r--svtools/source/productregistration/registrationdlg.cxx2
-rw-r--r--svtools/source/productregistration/registrationdlg.src2
-rw-r--r--svtools/source/table/tablecontrol.cxx2
-rw-r--r--svtools/source/toolpanel/drawerlayouter.cxx305
-rw-r--r--svtools/source/toolpanel/dummypanel.cxx107
-rw-r--r--svtools/source/toolpanel/dummypanel.hxx70
-rwxr-xr-xsvtools/source/toolpanel/makefile.mk68
-rwxr-xr-xsvtools/source/toolpanel/paneldecklisteners.cxx137
-rwxr-xr-xsvtools/source/toolpanel/paneldecklisteners.hxx72
-rwxr-xr-xsvtools/source/toolpanel/paneltabbar.cxx1356
-rw-r--r--svtools/source/toolpanel/paneltabbarpeer.cxx101
-rw-r--r--svtools/source/toolpanel/paneltabbarpeer.hxx69
-rw-r--r--svtools/source/toolpanel/refbase.cxx56
-rw-r--r--svtools/source/toolpanel/tabbargeometry.cxx328
-rw-r--r--svtools/source/toolpanel/tabbargeometry.hxx137
-rw-r--r--svtools/source/toolpanel/tabitemdescriptor.hxx90
-rwxr-xr-xsvtools/source/toolpanel/tablayouter.cxx262
-rw-r--r--svtools/source/toolpanel/toolpanel.cxx54
-rw-r--r--svtools/source/toolpanel/toolpanel.src (renamed from svtools/source/uno/unoifac2.hrc)57
-rw-r--r--svtools/source/toolpanel/toolpanelcollection.cxx193
-rw-r--r--svtools/source/toolpanel/toolpanelcollection.hxx69
-rwxr-xr-xsvtools/source/toolpanel/toolpaneldeck.cxx560
-rwxr-xr-xsvtools/source/toolpanel/toolpaneldeckpeer.cxx99
-rwxr-xr-xsvtools/source/toolpanel/toolpaneldeckpeer.hxx69
-rw-r--r--svtools/source/toolpanel/toolpaneldrawer.cxx373
-rw-r--r--svtools/source/toolpanel/toolpaneldrawer.hxx113
-rw-r--r--svtools/source/toolpanel/toolpaneldrawerpeer.cxx142
-rw-r--r--svtools/source/toolpanel/toolpaneldrawerpeer.hxx56
-rw-r--r--svtools/source/uno/makefile.mk7
-rw-r--r--svtools/source/uno/popupmenucontrollerbase.cxx420
-rw-r--r--svtools/source/uno/popupwindowcontroller.cxx258
-rw-r--r--svtools/source/uno/toolboxcontroller.cxx109
-rw-r--r--svtools/source/uno/treecontrolpeer.cxx13
-rw-r--r--svtools/source/uno/unoifac2.src107
92 files changed, 8940 insertions, 245 deletions
diff --git a/svtools/source/brwbox/brwbox1.cxx b/svtools/source/brwbox/brwbox1.cxx
index 9a4903b1e093..3a29c4ae63fa 100644
--- a/svtools/source/brwbox/brwbox1.cxx
+++ b/svtools/source/brwbox/brwbox1.cxx
@@ -2446,8 +2446,6 @@ void BrowseBox::SetMode( BrowserMode nMode )
BROWSER_AUTO_HSCROLL |
BROWSER_TRACKING_TIPS |
// BROWSER_HIGHLIGHT_NONE |
- BROWSER_HIGHLIGHT_AUTO |
-// BROWSER_HIGHLIGHT_MANU |
BROWSER_HEADERBAR_NEW |
// BROWSER_AUTOSIZE_LASTCOL |
0;
@@ -2517,9 +2515,6 @@ void BrowseBox::SetMode( BrowserMode nMode )
pVScroll->SetScrollHdl( LINK( this, BrowseBox, ScrollHdl ) );
pVScroll->SetEndScrollHdl( LINK( this, BrowseBox, EndScrollHdl ) );
- getDataWindow()->bHighlightAuto =
- BROWSER_HIGHLIGHT_AUTO == ( nMode & BROWSER_HIGHLIGHT_AUTO ) ||
- BROWSER_HIGHLIGHT_MANU != ( nMode & BROWSER_HIGHLIGHT_MANU );
getDataWindow()->bAutoSizeLastCol =
BROWSER_AUTOSIZE_LASTCOL == ( nMode & BROWSER_AUTOSIZE_LASTCOL );
getDataWindow()->bOwnDataChangedHdl =
diff --git a/svtools/source/brwbox/brwbox2.cxx b/svtools/source/brwbox/brwbox2.cxx
index da07415dfee8..68cf316e813b 100644
--- a/svtools/source/brwbox/brwbox2.cxx
+++ b/svtools/source/brwbox/brwbox2.cxx
@@ -340,10 +340,6 @@ void BrowseBox::ToggleSelection( BOOL bForce )
if ( !bForce &&
( bNotToggleSel || !IsUpdateMode() || !bSelectionIsVisible ) )
return;
-//MI, 28.01.98
-// if ( !getDataWindow()->bHighlightToggle &&
-// !getDataWindow()->bHighlightAuto )
-// return;
// only highlight painted areas!
bNotToggleSel = TRUE;
@@ -984,11 +980,10 @@ void BrowseBox::ImplPaintData(OutputDevice& _rOut, const Rectangle& _rRect, BOOL
Size( _rRect.GetSize().Width(), nDataRowHeigt ) );
PaintRow( _rOut, aRowRect );
- BOOL bRowAutoHighlight = _bDrawSelections
- && !bHideSelect
- && ((BrowserDataWin&)GetDataWindow()).bHighlightAuto
- && IsRowSelected( nRow );
- if ( bRowAutoHighlight )
+ BOOL bRowSelected = _bDrawSelections
+ && !bHideSelect
+ && IsRowSelected( nRow );
+ if ( bRowSelected )
{
_rOut.SetTextColor( rHighlightTextColor );
_rOut.SetFillColor( rHighlightFillColor );
@@ -1082,7 +1077,7 @@ void BrowseBox::ImplPaintData(OutputDevice& _rOut, const Rectangle& _rRect, BOOL
bRetouching = TRUE;
// reset auto-highlight
- if ( bRowAutoHighlight )
+ if ( bRowSelected )
{
_rOut.SetTextColor( aOldTextColor );
_rOut.SetFillColor( aOldFillColor );
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/brwbox/datwin.hxx b/svtools/source/brwbox/datwin.hxx
index e068f669e46e..1deb8aeb5b56 100644
--- a/svtools/source/brwbox/datwin.hxx
+++ b/svtools/source/brwbox/datwin.hxx
@@ -142,7 +142,6 @@ public:
FASTBOOL bAutoVScroll; // autohide horizontaler Scrollbar
FASTBOOL bUpdateMode; // nicht SV-UpdateMode wegen Invalidate()
FASTBOOL bAutoSizeLastCol;// last column always fills up window
- FASTBOOL bHighlightAuto; // new auto-highlight by SetFont() etc.
FASTBOOL bResizeOnPaint; // outstanding resize-event
FASTBOOL bUpdateOnUnlock; // Update() while locked
FASTBOOL bInUpdateScrollbars; // Rekursionsschutz
diff --git a/svtools/source/brwbox/editbrowsebox.cxx b/svtools/source/brwbox/editbrowsebox.cxx
index 817ab743140a..4f0afbaf5d2d 100644
--- a/svtools/source/brwbox/editbrowsebox.cxx
+++ b/svtools/source/brwbox/editbrowsebox.cxx
@@ -47,7 +47,7 @@
#include <svtools/svtdata.hxx>
#ifndef _SVTOOLS_HRC
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#endif
#include <algorithm>
diff --git a/svtools/source/brwbox/editbrowsebox.src b/svtools/source/brwbox/editbrowsebox.src
index 8c00c673c32b..6511d97ea86a 100644
--- a/svtools/source/brwbox/editbrowsebox.src
+++ b/svtools/source/brwbox/editbrowsebox.src
@@ -30,7 +30,7 @@
#endif
#ifndef _SVTOOLS_HRC
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#endif
ImageList RID_SVTOOLS_IMAGELIST_EDITBROWSEBOX
diff --git a/svtools/source/contnr/fileview.cxx b/svtools/source/contnr/fileview.cxx
index 8538e344bdc1..843de83f7710 100644
--- a/svtools/source/contnr/fileview.cxx
+++ b/svtools/source/contnr/fileview.cxx
@@ -34,7 +34,7 @@
#include <svtools/headbar.hxx>
#include <svtools/svtabbx.hxx>
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#include "fileview.hrc"
#include "contentenumeration.hxx"
#include <svtools/AccessibleBrowseBoxObjType.hxx>
diff --git a/svtools/source/contnr/fileview.src b/svtools/source/contnr/fileview.src
index e45f35fc1927..f40530c10347 100644
--- a/svtools/source/contnr/fileview.src
+++ b/svtools/source/contnr/fileview.src
@@ -27,7 +27,7 @@
// includes ------------------------------------------------------------------
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#include "fileview.hrc"
#include <svtools/helpid.hrc>
diff --git a/svtools/source/contnr/svcontnr.src b/svtools/source/contnr/svcontnr.src
index c296cc686c1d..bcd1e060664f 100644
--- a/svtools/source/contnr/svcontnr.src
+++ b/svtools/source/contnr/svcontnr.src
@@ -25,7 +25,7 @@
*
************************************************************************/
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
Image RID_IMG_TREENODE_COLLAPSED
{
diff --git a/svtools/source/contnr/svimpbox.cxx b/svtools/source/contnr/svimpbox.cxx
index 426f55be5b93..671b5a9f54e5 100644
--- a/svtools/source/contnr/svimpbox.cxx
+++ b/svtools/source/contnr/svimpbox.cxx
@@ -47,7 +47,7 @@
#include <svtools/svtdata.hxx>
#ifndef _SVTOOLS_HRC
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#endif
// #102891# --------------------
diff --git a/svtools/source/contnr/svtabbx.cxx b/svtools/source/contnr/svtabbx.cxx
index 9d4ad1ba15b5..53fbded59f11 100644
--- a/svtools/source/contnr/svtabbx.cxx
+++ b/svtools/source/contnr/svtabbx.cxx
@@ -31,7 +31,7 @@
#include <svtools/headbar.hxx>
#include <svtools/svtdata.hxx>
#ifndef _SVTOOLS_HRC
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#endif
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
#include <com/sun/star/accessibility/AccessibleEventId.hpp>
@@ -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/contnr/svtreebx.cxx b/svtools/source/contnr/svtreebx.cxx
index 143ac922eebc..736f27a1eafb 100644
--- a/svtools/source/contnr/svtreebx.cxx
+++ b/svtools/source/contnr/svtreebx.cxx
@@ -1041,7 +1041,7 @@ BOOL SvTreeListBox::Expand( SvLBoxEntry* pParent )
// --> OD 2009-04-01 #i92103#
if ( bExpanded )
{
- pImp->CallEventListeners( VCLEVENT_LISTBOX_ENTRY_EXPANDED, pParent );
+ pImp->CallEventListeners( VCLEVENT_ITEM_EXPANDED, pParent );
}
// <--
@@ -1068,7 +1068,7 @@ BOOL SvTreeListBox::Collapse( SvLBoxEntry* pParent )
// --> OD 2009-04-01 #i92103#
if ( bCollapsed )
{
- pImp->CallEventListeners( VCLEVENT_LISTBOX_ENTRY_COLLAPSED, pParent );
+ pImp->CallEventListeners( VCLEVENT_ITEM_COLLAPSED, pParent );
}
// <--
diff --git a/svtools/source/contnr/templwin.cxx b/svtools/source/contnr/templwin.cxx
index 47b5ab9aa4b9..61112f6669ca 100644
--- a/svtools/source/contnr/templwin.cxx
+++ b/svtools/source/contnr/templwin.cxx
@@ -41,7 +41,7 @@
#include "imgdef.hxx"
#include "txtattr.hxx"
#ifndef _SVTOOLS_HRC
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#endif
#ifndef _SVTOOLS_TEMPLWIN_HRC
#include "templwin.hrc"
diff --git a/svtools/source/contnr/templwin.src b/svtools/source/contnr/templwin.src
index 636c54ef6632..048d052c18d8 100644
--- a/svtools/source/contnr/templwin.src
+++ b/svtools/source/contnr/templwin.src
@@ -30,7 +30,7 @@
#include "templwin.hrc"
#include "controldims.hrc"
#include <svtools/helpid.hrc>
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
// Magenta and Grey as mask colors
#define MASK_COL_MAGENTA Color { Red = 0xFFFF ; Green = 0x0000 ; Blue = 0xFFFF ; };
diff --git a/svtools/source/control/calendar.cxx b/svtools/source/control/calendar.cxx
index c83ffa3ed70f..f7b49ac57eeb 100644..100755
--- a/svtools/source/control/calendar.cxx
+++ b/svtools/source/control/calendar.cxx
@@ -59,7 +59,7 @@
#include <com/sun/star/i18n/CalendarFieldIndex.hpp>
#define _SV_CALENDAR_CXX
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#include <svtools/svtdata.hxx>
#include <calendar.hxx>
diff --git a/svtools/source/control/calendar.src b/svtools/source/control/calendar.src
index 15c82cfdd184..4dd31765a5c1 100644..100755
--- a/svtools/source/control/calendar.src
+++ b/svtools/source/control/calendar.src
@@ -25,7 +25,7 @@
*
************************************************************************/
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
String STR_SVT_CALENDAR_DAY
{
Text [ en-US ] = "Day" ;
diff --git a/svtools/source/control/collatorres.cxx b/svtools/source/control/collatorres.cxx
index 23a84e757ebe..9988bfdadbb9 100644..100755
--- a/svtools/source/control/collatorres.cxx
+++ b/svtools/source/control/collatorres.cxx
@@ -29,7 +29,7 @@
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svtools.hxx"
#include <svtools/svtdata.hxx>
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#include <collatorres.hxx>
diff --git a/svtools/source/control/ctrlbox.cxx b/svtools/source/control/ctrlbox.cxx
index 2f692944d3c7..d44b18a29ae1 100644..100755
--- a/svtools/source/control/ctrlbox.cxx
+++ b/svtools/source/control/ctrlbox.cxx
@@ -40,7 +40,7 @@
#include <unotools/charclass.hxx>
#include <svtools/svtdata.hxx>
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#include <ctrlbox.hxx>
#include <ctrltool.hxx>
diff --git a/svtools/source/control/ctrlbox.src b/svtools/source/control/ctrlbox.src
index 0c63aef259b3..95440c905d89 100644..100755
--- a/svtools/source/control/ctrlbox.src
+++ b/svtools/source/control/ctrlbox.src
@@ -24,7 +24,7 @@
* for a copy of the LGPLv3 License.
*
************************************************************************/
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#ifndef IMAGE_STDBTN_COLOR
#define IMAGE_STDBTN_COLOR Color { Red = 0xFFFF; Green = 0x0000; Blue = 0xFFFF; }
diff --git a/svtools/source/control/ctrltool.cxx b/svtools/source/control/ctrltool.cxx
index 9abd14331fe4..bd965aca66a6 100644..100755
--- a/svtools/source/control/ctrltool.cxx
+++ b/svtools/source/control/ctrltool.cxx
@@ -42,7 +42,7 @@
#include <vcl/svapp.hxx>
#include <vcl/wrkwin.hxx>
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#include <svtools/svtdata.hxx>
#include <ctrltool.hxx>
diff --git a/svtools/source/control/ctrltool.src b/svtools/source/control/ctrltool.src
index 3e1c1ba884f8..72420af4908e 100644..100755
--- a/svtools/source/control/ctrltool.src
+++ b/svtools/source/control/ctrltool.src
@@ -24,7 +24,7 @@
* for a copy of the LGPLv3 License.
*
************************************************************************/
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
String STR_SVT_STYLE_LIGHT
{
diff --git a/svtools/source/control/indexentryres.cxx b/svtools/source/control/indexentryres.cxx
index 32e3aa14c0dc..5a79edab5b77 100644..100755
--- a/svtools/source/control/indexentryres.cxx
+++ b/svtools/source/control/indexentryres.cxx
@@ -29,7 +29,7 @@
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svtools.hxx"
#include <svtools/svtdata.hxx>
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#include <indexentryres.hxx>
diff --git a/svtools/source/control/makefile.mk b/svtools/source/control/makefile.mk
index a40a81163eb3..a2e622730635 100644..100755
--- a/svtools/source/control/makefile.mk
+++ b/svtools/source/control/makefile.mk
@@ -51,7 +51,9 @@ EXCEPTIONSFILES=\
$(SLO)$/scriptedtext.obj\
$(SLO)$/fmtfield.obj \
$(SLO)$/inettbc.obj \
- $(SLO)$/valueacc.obj
+ $(SLO)$/valueacc.obj \
+ $(SLO)$/toolbarmenu.obj \
+ $(SLO)$/toolbarmenuacc.obj
SLOFILES=\
$(EXCEPTIONSFILES) \
diff --git a/svtools/source/control/toolbarmenu.cxx b/svtools/source/control/toolbarmenu.cxx
new file mode 100644
index 000000000000..f07ebd7fe8cd
--- /dev/null
+++ b/svtools/source/control/toolbarmenu.cxx
@@ -0,0 +1,1805 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <comphelper/processfactory.hxx>
+
+#include <vcl/dockwin.hxx>
+#include <vcl/decoview.hxx>
+#include <vcl/image.hxx>
+#include <vcl/taskpanelist.hxx>
+#include <vcl/toolbox.hxx>
+
+#include "svtools/valueset.hxx"
+#include "svtools/toolbarmenu.hxx"
+#include "toolbarmenuimp.hxx"
+
+using ::rtl::OUString;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::accessibility;
+
+namespace svtools {
+
+// --------------------------------------------------------------------
+
+static Window* GetTopMostParentSystemWindow( Window* pWindow )
+{
+ OSL_ASSERT( pWindow );
+ if ( pWindow )
+ {
+ // ->manually search topmost system window
+ // required because their might be another system window between this and the top window
+ pWindow = pWindow->GetParent();
+ SystemWindow* pTopMostSysWin = NULL;
+ while ( pWindow )
+ {
+ if ( pWindow->IsSystemWindow() )
+ pTopMostSysWin = (SystemWindow*)pWindow;
+ pWindow = pWindow->GetParent();
+ }
+ pWindow = pTopMostSysWin;
+ OSL_ASSERT( pWindow );
+ return pWindow;
+ }
+
+ return NULL;
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenuEntry::init( int nEntryId, MenuItemBits nBits )
+{
+ mnEntryId = nEntryId;
+ mnBits = nBits;
+
+ mbHasText = false;
+ mbHasImage = false;
+ mbChecked = false;
+ mbEnabled = true;
+
+ mpControl = NULL;
+}
+
+// --------------------------------------------------------------------
+
+ToolbarMenuEntry::ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, const String& rText, MenuItemBits nBits )
+: mrMenu( rMenu )
+{
+ init( nEntryId, nBits );
+
+ maText = rText;
+ mbHasText = true;
+}
+
+// --------------------------------------------------------------------
+
+ToolbarMenuEntry::ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, const Image& rImage, MenuItemBits nBits )
+: mrMenu( rMenu )
+{
+ init( nEntryId, nBits );
+
+ maImage = rImage;
+ mbHasImage = true;
+}
+
+// --------------------------------------------------------------------
+
+ToolbarMenuEntry::ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, const Image& rImage, const String& rText, MenuItemBits nBits )
+: mrMenu( rMenu )
+{
+ init( nEntryId, nBits );
+
+ maText = rText;
+ mbHasText = true;
+
+ maImage = rImage;
+ mbHasImage = true;
+}
+
+// --------------------------------------------------------------------
+
+ToolbarMenuEntry::ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, Control* pControl, MenuItemBits nBits )
+: mrMenu( rMenu )
+{
+ init( nEntryId, nBits );
+
+ if( pControl )
+ {
+ mpControl = pControl;
+ mpControl->Show();
+ }
+}
+
+// --------------------------------------------------------------------
+
+ToolbarMenuEntry::~ToolbarMenuEntry()
+{
+ if( mxAccContext.is() )
+ {
+ Reference< XComponent > xComponent( mxAccContext, UNO_QUERY );
+ if( xComponent.is() )
+ xComponent->dispose();
+ mxAccContext.clear();
+ }
+ delete mpControl;
+}
+
+// --------------------------------------------------------------------
+
+const Reference< XAccessibleContext >& ToolbarMenuEntry::GetAccessible( bool bCreate /* = false */ )
+{
+ if( !mxAccContext.is() && bCreate )
+ {
+ if( mpControl )
+ {
+ mxAccContext = Reference< XAccessibleContext >( mpControl->GetAccessible( TRUE ), UNO_QUERY );
+ }
+ else
+ {
+ mxAccContext = Reference< XAccessibleContext >( new ToolbarMenuEntryAcc( this ) );
+ }
+ }
+
+ return mxAccContext;
+}
+
+// --------------------------------------------------------------------
+
+sal_Int32 ToolbarMenuEntry::getAccessibleChildCount() throw (RuntimeException)
+{
+ if( mpControl )
+ {
+ const Reference< XAccessibleContext >& xContext = GetAccessible( true );
+ if( xContext.is() )
+ {
+ return xContext->getAccessibleChildCount();
+ }
+ }
+ return 1;
+}
+
+// --------------------------------------------------------------------
+
+Reference< XAccessible > ToolbarMenuEntry::getAccessibleChild( sal_Int32 index ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ const Reference< XAccessibleContext >& xContext = GetAccessible( true );
+ if( mpControl )
+ {
+ if( xContext.is() )
+ {
+ return xContext->getAccessibleChild(index);
+ }
+ }
+ else if( index == 0 )
+ {
+ Reference< XAccessible > xRet( xContext, UNO_QUERY );
+ if( xRet.is() )
+ return xRet;
+ }
+
+ throw IndexOutOfBoundsException();
+}
+
+// --------------------------------------------------------------------
+
+ToolbarMenu_Impl::ToolbarMenu_Impl( ToolbarMenu& rMenu, const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame )
+: mrMenu( rMenu )
+, mxFrame( xFrame )
+, mxServiceManager( ::comphelper::getProcessServiceFactory() )
+, mnCheckPos(0)
+, mnImagePos(0)
+, mnTextPos(0)
+, mnHighlightedEntry(-1)
+, mnSelectedEntry(-1)
+, mnLastColumn(0)
+{
+}
+
+// --------------------------------------------------------------------
+
+ToolbarMenu_Impl::~ToolbarMenu_Impl()
+{
+ setAccessible( 0 );
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu_Impl::setAccessible( ToolbarMenuAcc* pAccessible )
+{
+ if( mxAccessible.get() != pAccessible )
+ {
+ if( mxAccessible.is() )
+ mxAccessible->dispose();
+
+ mxAccessible.set( pAccessible );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ToolbarMenu_Impl::fireAccessibleEvent( short nEventId, const ::com::sun::star::uno::Any& rOldValue, const ::com::sun::star::uno::Any& rNewValue )
+{
+ if( mxAccessible.is() )
+ mxAccessible->FireAccessibleEvent( nEventId, rOldValue, rNewValue );
+}
+
+// -----------------------------------------------------------------------
+
+bool ToolbarMenu_Impl::hasAccessibleListeners()
+{
+ return( mxAccessible.is() && mxAccessible->HasAccessibleListeners() );
+}
+
+// --------------------------------------------------------------------
+
+sal_Int32 ToolbarMenu_Impl::getAccessibleChildCount() throw (RuntimeException)
+{
+ sal_Int32 nCount = 0;
+ const int nEntryCount = maEntryVector.size();
+ for( int nEntry = 0; nEntry < nEntryCount; nEntry++ )
+ {
+ ToolbarMenuEntry* pEntry = maEntryVector[nEntry];
+ if( pEntry )
+ {
+ if( pEntry->mpControl )
+ {
+ nCount += pEntry->getAccessibleChildCount();
+ }
+ else
+ {
+ nCount += 1;
+ }
+ }
+ }
+
+ return nCount;
+}
+
+// --------------------------------------------------------------------
+
+Reference< XAccessible > ToolbarMenu_Impl::getAccessibleChild( sal_Int32 index ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ const int nEntryCount = maEntryVector.size();
+ for( int nEntry = 0; nEntry < nEntryCount; nEntry++ )
+ {
+ ToolbarMenuEntry* pEntry = maEntryVector[nEntry];
+ if( pEntry )
+ {
+ const sal_Int32 nCount = pEntry->getAccessibleChildCount();
+ if( index < nCount )
+ {
+ return pEntry->getAccessibleChild( index );
+ }
+ index -= nCount;
+ }
+ }
+
+ throw IndexOutOfBoundsException();
+}
+
+// --------------------------------------------------------------------
+
+Reference< XAccessible > ToolbarMenu_Impl::getAccessibleChild( Control* pControl, sal_Int32 childIndex ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ const int nEntryCount = maEntryVector.size();
+ for( int nEntry = 0; nEntry < nEntryCount; nEntry++ )
+ {
+ ToolbarMenuEntry* pEntry = maEntryVector[nEntry];
+ if( pEntry && (pEntry->mpControl == pControl) )
+ {
+ return pEntry->getAccessibleChild( childIndex );
+ }
+ }
+
+ throw IndexOutOfBoundsException();
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu_Impl::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ const int nEntryCount = maEntryVector.size();
+ for( int nEntry = 0; nEntry < nEntryCount; nEntry++ )
+ {
+ ToolbarMenuEntry* pEntry = maEntryVector[nEntry];
+ if( pEntry )
+ {
+ const sal_Int32 nCount = pEntry->getAccessibleChildCount();
+ if( nChildIndex < nCount )
+ {
+ if( pEntry->mpControl )
+ {
+ Reference< XAccessibleSelection > xSel( pEntry->GetAccessible(true), UNO_QUERY_THROW );
+ xSel->selectAccessibleChild(nChildIndex);
+ }
+ else if( pEntry->mnEntryId != TITLE_ID )
+ {
+ mrMenu.implSelectEntry( nEntry );
+ }
+ return;
+ }
+ nChildIndex -= nCount;
+ }
+ }
+
+ throw IndexOutOfBoundsException();
+}
+
+// --------------------------------------------------------------------
+
+sal_Bool ToolbarMenu_Impl::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ const int nEntryCount = maEntryVector.size();
+ for( int nEntry = 0; nEntry < nEntryCount; nEntry++ )
+ {
+ ToolbarMenuEntry* pEntry = maEntryVector[nEntry];
+ if( pEntry )
+ {
+ const sal_Int32 nCount = pEntry->getAccessibleChildCount();
+ if( nChildIndex < nCount )
+ {
+ if( mnHighlightedEntry == nEntry )
+ {
+ if( pEntry->mpControl )
+ {
+ Reference< XAccessibleSelection > xSel( pEntry->GetAccessible(true), UNO_QUERY_THROW );
+ xSel->isAccessibleChildSelected(nChildIndex);
+ }
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ nChildIndex -= nCount;
+ }
+ }
+
+ throw IndexOutOfBoundsException();
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu_Impl::clearAccessibleSelection()
+{
+ if( mnHighlightedEntry != -1 )
+ {
+ mrMenu.implHighlightEntry( mnHighlightedEntry, false );
+ mnHighlightedEntry = -1;
+ }
+}
+
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu_Impl::notifyHighlightedEntry()
+{
+ if( hasAccessibleListeners() )
+ {
+ ToolbarMenuEntry* pEntry = implGetEntry( mnHighlightedEntry );
+ if( pEntry && pEntry->mbEnabled && (pEntry->mnEntryId != TITLE_ID) )
+ {
+ Any aNew;
+ Any aOld( mxOldSelection );
+ if( pEntry->mpControl )
+ {
+ sal_Int32 nChildIndex = 0;
+ // todo: if other controls than ValueSet are allowed, addapt this code
+ ValueSet* pValueSet = dynamic_cast< ValueSet* >( pEntry->mpControl );
+ if( pValueSet )
+ nChildIndex = static_cast< sal_Int32 >( pValueSet->GetItemPos( pValueSet->GetSelectItemId() ) );
+
+ if( nChildIndex >= pEntry->getAccessibleChildCount() )
+ return;
+
+ aNew <<= getAccessibleChild( pEntry->mpControl, nChildIndex );
+ }
+ else
+ {
+ aNew <<= pEntry->GetAccessible(true);
+ }
+
+ fireAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOld, aNew );
+ fireAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, aOld, aNew );
+ fireAccessibleEvent( AccessibleEventId::STATE_CHANGED, Any(), Any( AccessibleStateType::FOCUSED ) );
+ aNew >>= mxOldSelection;
+ }
+ }
+}
+
+// --------------------------------------------------------------------
+
+ToolbarMenuEntry* ToolbarMenu_Impl::implGetEntry( int nEntry ) const
+{
+ if( (nEntry < 0) || (nEntry >= (int)maEntryVector.size() ) )
+ return NULL;
+
+ return maEntryVector[nEntry];
+}
+
+
+// --------------------------------------------------------------------
+
+IMPL_LINK( ToolbarMenu, HighlightHdl, Control *, pControl )
+{
+ (void)pControl;
+ mpImpl->notifyHighlightedEntry();
+ return 0;
+}
+
+// ====================================================================
+
+ToolbarMenu::ToolbarMenu( const Reference< XFrame >& rFrame, Window* pParentWindow, WinBits nBits )
+: DockingWindow(pParentWindow, nBits)
+{
+ implInit(rFrame);
+}
+
+// --------------------------------------------------------------------
+
+ToolbarMenu::ToolbarMenu( const Reference< XFrame >& rFrame, Window* pParentWindow, const ResId& rResId )
+: DockingWindow(pParentWindow, rResId)
+{
+ implInit(rFrame);
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::implInit(const Reference< XFrame >& rFrame)
+{
+ mpImpl = new ToolbarMenu_Impl( *this, rFrame );
+
+ initWindow();
+
+ Window* pWindow = GetTopMostParentSystemWindow( this );
+ if ( pWindow )
+ ((SystemWindow *)pWindow)->GetTaskPaneList()->AddWindow( this );
+}
+
+// --------------------------------------------------------------------
+
+ToolbarMenu::~ToolbarMenu()
+{
+ Window* pWindow = GetTopMostParentSystemWindow( this );
+ if ( pWindow )
+ ((SystemWindow *)pWindow)->GetTaskPaneList()->RemoveWindow( this );
+
+ if ( mpImpl->mxStatusListener.is() )
+ {
+ mpImpl->mxStatusListener->dispose();
+ mpImpl->mxStatusListener.clear();
+ }
+
+ // delete all menu entries
+ const int nEntryCount = mpImpl->maEntryVector.size();
+ int nEntry;
+ for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
+ {
+ delete mpImpl->maEntryVector[nEntry];
+ }
+
+ delete mpImpl;
+}
+
+// --------------------------------------------------------------------
+
+int ToolbarMenu::getSelectedEntryId() const
+{
+ ToolbarMenuEntry* pEntry = implGetEntry( mpImpl->mnSelectedEntry );
+ return pEntry ? pEntry->mnEntryId : -1;
+}
+
+// --------------------------------------------------------------------
+
+int ToolbarMenu::getHighlightedEntryId() const
+{
+ ToolbarMenuEntry* pEntry = implGetEntry( mpImpl->mnHighlightedEntry );
+ return pEntry ? pEntry->mnEntryId : -1;
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::checkEntry( int nEntryId, bool bChecked )
+{
+ ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId );
+ if( pEntry && pEntry->mbChecked != bChecked )
+ {
+ pEntry->mbChecked = bChecked;
+ Invalidate();
+ }
+}
+
+// --------------------------------------------------------------------
+
+bool ToolbarMenu::isEntryChecked( int nEntryId ) const
+{
+ ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId );
+ return pEntry && pEntry->mbChecked;
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::enableEntry( int nEntryId, bool bEnable )
+{
+ ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId );
+ if( pEntry && pEntry->mbEnabled != bEnable )
+ {
+ pEntry->mbEnabled = bEnable;
+ if( pEntry->mpControl )
+ {
+ pEntry->mpControl->Enable( bEnable );
+
+ // hack for the valueset to make it paint itself anew
+ pEntry->mpControl->Resize();
+ }
+ Invalidate();
+ }
+}
+
+// --------------------------------------------------------------------
+
+bool ToolbarMenu::isEntryEnabled( int nEntryId ) const
+{
+ ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId );
+ return pEntry && pEntry->mbEnabled;
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::setEntryText( int nEntryId, const String& rStr )
+{
+ ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId );
+ if( pEntry && pEntry->maText != rStr )
+ {
+ pEntry->maText = rStr;
+ mpImpl->maSize = implCalcSize();
+ if( IsVisible() )
+ Invalidate();
+ }
+}
+
+// --------------------------------------------------------------------
+
+const String& ToolbarMenu::getEntryText( int nEntryId ) const
+{
+ ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId );
+ if( pEntry )
+ return pEntry->maText;
+ else
+ {
+ static String aEmptyStr;
+ return aEmptyStr;
+ }
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::setEntryImage( int nEntryId, const Image& rImage )
+{
+ ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId );
+ if( pEntry && pEntry->maImage != rImage )
+ {
+ pEntry->maImage = rImage;
+ mpImpl->maSize = implCalcSize();
+ if( IsVisible() )
+ Invalidate();
+ }
+}
+
+// --------------------------------------------------------------------
+
+const Image& ToolbarMenu::getEntryImage( int nEntryId ) const
+{
+ ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId );
+ if( pEntry )
+ return pEntry->maImage;
+ else
+ {
+ static Image aEmptyImage;
+ return aEmptyImage;
+ }
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::initWindow()
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ SetControlBackground( GetSettings().GetStyleSettings().GetFaceGradientColor() );
+
+ SetPointFont( rStyleSettings.GetMenuFont() );
+ SetBackground( Wallpaper( GetControlBackground() ) );
+ SetTextColor( rStyleSettings.GetMenuTextColor() );
+ SetTextFillColor();
+ SetLineColor();
+
+ mpImpl->maSize = implCalcSize();
+}
+
+// --------------------------------------------------------------------
+
+Size ToolbarMenu::implCalcSize()
+{
+ const long nFontHeight = GetTextHeight();
+ long nExtra = nFontHeight/4;
+
+ Size aSz;
+ Size aMaxImgSz;
+ long nMaxTextWidth = 0;
+ long nMinMenuItemHeight = nFontHeight+2;
+ sal_Bool bCheckable = sal_False;
+
+ const int nEntryCount = mpImpl->maEntryVector.size();
+ int nEntry;
+
+ const StyleSettings& rSettings = GetSettings().GetStyleSettings();
+ const bool bUseImages = rSettings.GetUseImagesInMenus();
+
+ // get maximum image size
+ if( bUseImages )
+ {
+ for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
+ {
+ ToolbarMenuEntry* pEntry = mpImpl->maEntryVector[nEntry];
+ if( pEntry && pEntry->mbHasImage )
+ {
+ Size aImgSz( pEntry->maImage.GetSizePixel() );
+ nMinMenuItemHeight = std::max( nMinMenuItemHeight, aImgSz.Height() + 6 );
+ aMaxImgSz.Width() = std::max( aMaxImgSz.Width(), aImgSz.Width() );
+ }
+ }
+ }
+
+ mpImpl->mnCheckPos = nExtra;
+ mpImpl->mnImagePos = nExtra;
+ mpImpl->mnTextPos = mpImpl->mnImagePos + aMaxImgSz.Width();
+
+ if ( aMaxImgSz.Width() )
+ mpImpl->mnTextPos += std::max( nExtra, 7L );
+ if ( bCheckable )
+ mpImpl->mnTextPos += 16;
+
+ // set heights, calc maximum width
+ for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
+ {
+ ToolbarMenuEntry* pEntry = mpImpl->maEntryVector[nEntry];
+
+ if( pEntry )
+ {
+ if ( ( pEntry->mnBits ) & ( MIB_RADIOCHECK | MIB_CHECKABLE ) )
+ bCheckable = sal_True;
+
+ // Text:
+ if( pEntry->mbHasText || pEntry->mbHasImage )
+ {
+ pEntry->maSize.Height() = nMinMenuItemHeight;
+
+ if( pEntry->mbHasText )
+ {
+ long nTextWidth = GetCtrlTextWidth( pEntry->maText ) + mpImpl->mnTextPos + nExtra;
+ nMaxTextWidth = std::max( nTextWidth, nMaxTextWidth );
+ }
+ }
+ // Control:
+ else if( pEntry->mpControl )
+ {
+ Size aControlSize( pEntry->mpControl->GetOutputSizePixel() );
+
+ nMaxTextWidth = std::max( aControlSize.Width(), nMaxTextWidth );
+ pEntry->maSize.Height() = aControlSize.Height() + 1;
+ }
+
+ }
+ }
+
+ aSz.Width() = nMaxTextWidth + (BORDER_X<<1);
+
+ // positionate controls
+ int nY = BORDER_Y;
+ for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
+ {
+ ToolbarMenuEntry* pEntry = mpImpl->maEntryVector[nEntry];
+
+ if( pEntry )
+ {
+ pEntry->maSize.Width() = nMaxTextWidth;
+
+ if( pEntry->mpControl )
+ {
+ Size aControlSize( pEntry->mpControl->GetOutputSizePixel() );
+ Point aControlPos( (aSz.Width() - aControlSize.Width())>>1, nY);
+
+ pEntry->mpControl->SetPosPixel( aControlPos );
+
+ pEntry->maRect = Rectangle( aControlPos, aControlSize );
+ }
+ else
+ {
+ pEntry->maRect = Rectangle( Point( 0, nY ), pEntry->maSize );
+ }
+
+ nY += pEntry->maSize.Height();
+ }
+ else
+ {
+ nY += SEPARATOR_HEIGHT;
+ }
+ }
+
+ aSz.Height() += nY + BORDER_Y;
+
+ return aSz;
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::highlightFirstEntry()
+{
+ implChangeHighlightEntry( 0 );
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::GetFocus()
+{
+ if( mpImpl->mnHighlightedEntry == -1 )
+ implChangeHighlightEntry( 0 );
+
+ DockingWindow::GetFocus();
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::LoseFocus()
+{
+ if( mpImpl->mnHighlightedEntry != -1 )
+ implChangeHighlightEntry( -1 );
+
+ DockingWindow::LoseFocus();
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::appendEntry( int nEntryId, const String& rStr, MenuItemBits nItemBits )
+{
+ appendEntry( new ToolbarMenuEntry( *this, nEntryId, rStr, nItemBits ) );
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::appendEntry( int nEntryId, const Image& rImage, MenuItemBits nItemBits )
+{
+ appendEntry( new ToolbarMenuEntry( *this, nEntryId, rImage, nItemBits ) );
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::appendEntry( int nEntryId, const String& rStr, const Image& rImage, MenuItemBits nItemBits )
+{
+ appendEntry( new ToolbarMenuEntry( *this, nEntryId, rImage, rStr, nItemBits ) );
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::appendEntry( int nEntryId, Control* pControl, MenuItemBits nItemBits )
+{
+ appendEntry( new ToolbarMenuEntry( *this, nEntryId, pControl, nItemBits ) );
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::appendEntry( ToolbarMenuEntry* pEntry )
+{
+ mpImpl->maEntryVector.push_back( pEntry );
+ mpImpl->maSize = implCalcSize();
+ if( IsVisible() )
+ Invalidate();
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::appendSeparator()
+{
+ appendEntry( 0 );
+}
+
+// --------------------------------------------------------------------
+
+/** creates an empty ValueSet that is initialized and can be inserted with appendEntry. */
+ValueSet* ToolbarMenu::createEmptyValueSetControl()
+{
+ ValueSet* pSet = new ValueSet( this, WB_TABSTOP | WB_MENUSTYLEVALUESET | WB_FLATVALUESET | WB_NOBORDER | WB_NO_DIRECTSELECT );
+ pSet->EnableFullItemMode( FALSE );
+ pSet->SetColor( GetControlBackground() );
+ pSet->SetHighlightHdl( LINK( this, ToolbarMenu, HighlightHdl ) );
+ return pSet;
+}
+
+// --------------------------------------------------------------------
+
+ToolbarMenuEntry* ToolbarMenu::implGetEntry( int nEntry ) const
+{
+ return mpImpl->implGetEntry( nEntry );
+}
+
+// --------------------------------------------------------------------
+
+ToolbarMenuEntry* ToolbarMenu::implSearchEntry( int nEntryId ) const
+{
+ const int nEntryCount = mpImpl->maEntryVector.size();
+ int nEntry;
+ for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
+ {
+ ToolbarMenuEntry* p = mpImpl->maEntryVector[nEntry];
+ if( p && p->mnEntryId == nEntryId )
+ {
+ return p;
+ }
+ }
+
+ return NULL;
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::implHighlightEntry( int nHighlightEntry, bool bHighlight )
+{
+ Size aSz( GetOutputSizePixel() );
+ long nX = 0, nY = 0;
+
+ const int nEntryCount = mpImpl->maEntryVector.size();
+ int nEntry;
+ for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
+ {
+ ToolbarMenuEntry* pEntry = mpImpl->maEntryVector[nEntry];
+ if( pEntry && (nEntry == nHighlightEntry) )
+ {
+ // no highlights for controls only items
+ if( pEntry->mpControl )
+ {
+ if( !bHighlight )
+ {
+ ValueSet* pValueSet = dynamic_cast< ValueSet* >( pEntry->mpControl );
+ if( pValueSet )
+ {
+ pValueSet->SetNoSelection();
+ }
+ }
+ break;
+ }
+
+ bool bRestoreLineColor = false;
+ Color oldLineColor;
+ bool bDrawItemRect = true;
+
+ Rectangle aItemRect( Point( nX, nY ), Size( aSz.Width(), pEntry->maSize.Height() ) );
+ if ( pEntry->mnBits & MIB_POPUPSELECT )
+ {
+ long nFontHeight = GetTextHeight();
+ aItemRect.Right() -= nFontHeight + nFontHeight/4;
+ }
+
+ if( IsNativeControlSupported( CTRL_MENU_POPUP, PART_ENTIRE_CONTROL ) )
+ {
+ Size aPxSize( GetOutputSizePixel() );
+ Push( PUSH_CLIPREGION );
+ IntersectClipRegion( Rectangle( Point( nX, nY ), Size( aSz.Width(), pEntry->maSize.Height() ) ) );
+ Rectangle aCtrlRect( Point( nX, 0 ), Size( aPxSize.Width()-nX, aPxSize.Height() ) );
+ DrawNativeControl( CTRL_MENU_POPUP, PART_ENTIRE_CONTROL,
+ Region( aCtrlRect ),
+ CTRL_STATE_ENABLED,
+ ImplControlValue(),
+ OUString() );
+ if( bHighlight && IsNativeControlSupported( CTRL_MENU_POPUP, PART_MENU_ITEM ) )
+ {
+ bDrawItemRect = false;
+ if( FALSE == DrawNativeControl( CTRL_MENU_POPUP, PART_MENU_ITEM,
+ Region( aItemRect ),
+ CTRL_STATE_SELECTED | ( pEntry->mbEnabled? CTRL_STATE_ENABLED: 0 ),
+ ImplControlValue(),
+ OUString() ) )
+ {
+ bDrawItemRect = bHighlight;
+ }
+ }
+ else
+ bDrawItemRect = bHighlight;
+ Pop();
+ }
+ if( bDrawItemRect )
+ {
+ if ( bHighlight )
+ {
+ if( pEntry->mbEnabled )
+ SetFillColor( GetSettings().GetStyleSettings().GetMenuHighlightColor() );
+ else
+ {
+ SetFillColor();
+ oldLineColor = GetLineColor();
+ SetLineColor( GetSettings().GetStyleSettings().GetMenuHighlightColor() );
+ bRestoreLineColor = true;
+ }
+ }
+ else
+ SetFillColor( GetSettings().GetStyleSettings().GetMenuColor() );
+
+ DrawRect( aItemRect );
+ }
+ implPaint( pEntry, bHighlight );
+ if( bRestoreLineColor )
+ SetLineColor( oldLineColor );
+ break;
+ }
+
+ nY += pEntry ? pEntry->maSize.Height() : SEPARATOR_HEIGHT;
+ }
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::implSelectEntry( int nSelectedEntry )
+{
+ mpImpl->mnSelectedEntry = nSelectedEntry;
+
+ ToolbarMenuEntry* pEntry = NULL;
+ if( nSelectedEntry != -1 )
+ pEntry = mpImpl->maEntryVector[ nSelectedEntry ];
+
+ if( pEntry )
+ mpImpl->maSelectHdl.Call( this );
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ implHighlightEntry( rMEvt, true );
+
+ implSelectEntry( mpImpl->mnHighlightedEntry );
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::MouseButtonUp( const MouseEvent& )
+{
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::MouseMove( const MouseEvent& rMEvt )
+{
+ if ( !IsVisible() )
+ return;
+
+ implHighlightEntry( rMEvt, false );
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::implHighlightEntry( const MouseEvent& rMEvt, bool bMBDown )
+{
+ long nY = 0;
+ long nMouseY = rMEvt.GetPosPixel().Y();
+ Size aOutSz = GetOutputSizePixel();
+ if ( ( nMouseY >= 0 ) && ( nMouseY < aOutSz.Height() ) )
+ {
+ bool bHighlighted = FALSE;
+
+ const int nEntryCount = mpImpl->maEntryVector.size();
+ int nEntry;
+ for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
+ {
+ ToolbarMenuEntry* pEntry = mpImpl->maEntryVector[nEntry];
+ if( pEntry )
+ {
+ long nOldY = nY;
+ nY += pEntry->maSize.Height();
+
+ if( pEntry->mnEntryId != TITLE_ID )
+ {
+ if ( ( nOldY <= nMouseY ) && ( nY > nMouseY ) )
+ {
+ if( bMBDown )
+ {
+ if( nEntry != mpImpl->mnHighlightedEntry )
+ {
+ implChangeHighlightEntry( nEntry );
+ }
+ }
+ else
+ {
+ if ( nEntry != mpImpl->mnHighlightedEntry )
+ {
+ implChangeHighlightEntry( nEntry );
+ }
+ }
+ bHighlighted = true;
+ }
+ }
+ }
+ else
+ {
+ nY += SEPARATOR_HEIGHT;
+ }
+ }
+ if ( !bHighlighted )
+ implChangeHighlightEntry( -1 );
+ }
+ else
+ {
+ implChangeHighlightEntry( -1 );
+ }
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::implChangeHighlightEntry( int nEntry )
+{
+ if( mpImpl->mnHighlightedEntry != -1 )
+ {
+ implHighlightEntry( mpImpl->mnHighlightedEntry, false );
+ }
+
+ mpImpl->mnHighlightedEntry = nEntry;
+ Invalidate();
+
+ if( mpImpl->mnHighlightedEntry != -1 )
+ {
+ implHighlightEntry( mpImpl->mnHighlightedEntry, true );
+ }
+
+ mpImpl->notifyHighlightedEntry();
+}
+
+// --------------------------------------------------------------------
+
+static bool implCheckSubControlCursorMove( Control* pControl, bool bUp, int& nLastColumn )
+{
+ ValueSet* pValueSet = dynamic_cast< ValueSet* >( pControl );
+ if( pValueSet )
+ {
+ USHORT nItemPos = pValueSet->GetItemPos( pValueSet->GetSelectItemId() );
+ if( nItemPos != VALUESET_ITEM_NOTFOUND )
+ {
+ const USHORT nColCount = pValueSet->GetColCount();
+ const USHORT nLine = nItemPos / nColCount;
+
+ nLastColumn = nItemPos - (nLine * nColCount);
+
+ if( bUp )
+ {
+ return nLine > 0;
+ }
+ else
+ {
+ const USHORT nLineCount = (pValueSet->GetItemCount() + nColCount - 1) / nColCount;
+ return (nLine+1) < nLineCount;
+ }
+ }
+ }
+
+ return false;
+}
+
+// --------------------------------------------------------------------
+
+ToolbarMenuEntry* ToolbarMenu::implCursorUpDown( bool bUp, bool bHomeEnd )
+{
+ int n = 0, nLoop = 0;
+ if( !bHomeEnd )
+ {
+ n = mpImpl->mnHighlightedEntry;
+ if( n == -1 )
+ {
+ if( bUp )
+ n = 0;
+ else
+ n = mpImpl->maEntryVector.size()-1;
+ }
+ else
+ {
+ // if we have a currently selected entry and
+ // cursor keys are used than check if this entry
+ // has a control that can use those cursor keys
+ ToolbarMenuEntry* pData = mpImpl->maEntryVector[n];
+ if( pData && pData->mpControl && !pData->mbHasText )
+ {
+ if( implCheckSubControlCursorMove( pData->mpControl, bUp, mpImpl->mnLastColumn ) )
+ return pData;
+ }
+ }
+ nLoop = n;
+ }
+ else
+ {
+ // absolute positioning
+ if( bUp )
+ {
+ n = mpImpl->maEntryVector.size();
+ nLoop = n-1;
+ }
+ else
+ {
+ n = -1;
+ nLoop = mpImpl->maEntryVector.size()-1;
+ }
+ }
+
+ do
+ {
+ if( bUp )
+ {
+ if ( n )
+ n--;
+ else
+ if( mpImpl->mnHighlightedEntry == -1 )
+ n = mpImpl->maEntryVector.size()-1;
+ else
+ break;
+ }
+ else
+ {
+ if( n < ((int)mpImpl->maEntryVector.size()-1) )
+ n++;
+ else
+ if( mpImpl->mnHighlightedEntry == -1 )
+ n = 0;
+ else
+ break;
+ }
+
+ ToolbarMenuEntry* pData = mpImpl->maEntryVector[n];
+ if( pData && (pData->mnEntryId != TITLE_ID) )
+ {
+ implChangeHighlightEntry( n );
+ return pData;
+ }
+ } while ( n != nLoop );
+
+ return 0;
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu_Impl::implHighlightControl( USHORT nCode, Control* pControl )
+{
+ ValueSet* pValueSet = dynamic_cast< ValueSet* >( pControl );
+ if( pValueSet )
+ {
+ const USHORT nItemCount = pValueSet->GetItemCount();
+ USHORT nItemPos = VALUESET_ITEM_NOTFOUND;
+ switch( nCode )
+ {
+ case KEY_UP:
+ {
+ const USHORT nColCount = pValueSet->GetColCount();
+ const USHORT nLastLine = nItemCount / nColCount;
+ nItemPos = std::min( ((nLastLine-1) * nColCount) + mnLastColumn, nItemCount-1 );
+ break;
+ }
+ case KEY_DOWN:
+ nItemPos = std::min( mnLastColumn, nItemCount-1 );
+ break;
+ case KEY_END:
+ nItemPos = nItemCount -1;
+ break;
+ case KEY_HOME:
+ nItemPos = 0;
+ break;
+ }
+ pValueSet->SelectItem( pValueSet->GetItemId( nItemPos ) );
+ notifyHighlightedEntry();
+ }
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::KeyInput( const KeyEvent& rKEvent )
+{
+ Control* pForwardControl = 0;
+ USHORT nCode = rKEvent.GetKeyCode().GetCode();
+ switch ( nCode )
+ {
+ case KEY_UP:
+ case KEY_DOWN:
+ {
+ int nOldEntry = mpImpl->mnHighlightedEntry;
+ ToolbarMenuEntry*p = implCursorUpDown( nCode == KEY_UP, false );
+ if( p && p->mpControl )
+ {
+ if( nOldEntry != mpImpl->mnHighlightedEntry )
+ {
+ mpImpl->implHighlightControl( nCode, p->mpControl );
+ }
+ else
+ {
+ // in case we are in a system floating window, GrabFocus does not work :-/
+ pForwardControl = p->mpControl;
+ }
+ }
+ }
+ break;
+ case KEY_END:
+ case KEY_HOME:
+ {
+ ToolbarMenuEntry* p = implCursorUpDown( nCode == KEY_END, true );
+ if( p && p->mpControl )
+ {
+ mpImpl->implHighlightControl( nCode, p->mpControl );
+ }
+ }
+ break;
+ case KEY_F6:
+ case KEY_ESCAPE:
+ {
+ // Ctrl-F6 acts like ESC here, the menu bar however will then put the focus in the document
+ if( nCode == KEY_F6 && !rKEvent.GetKeyCode().IsMod1() )
+ break;
+
+ implSelectEntry( -1 );
+ }
+ break;
+
+ case KEY_RETURN:
+ {
+ ToolbarMenuEntry* pEntry = implGetEntry( mpImpl->mnHighlightedEntry );
+ if ( pEntry && pEntry->mbEnabled && (pEntry->mnEntryId != TITLE_ID) )
+ {
+ if( pEntry->mpControl )
+ {
+ pForwardControl = pEntry->mpControl;
+ }
+ else
+ {
+ implSelectEntry( mpImpl->mnHighlightedEntry );
+ }
+ }
+ }
+ break;
+ default:
+ {
+ ToolbarMenuEntry* pEntry = implGetEntry( mpImpl->mnHighlightedEntry );
+ if ( pEntry && pEntry->mbEnabled && pEntry->mpControl && !pEntry->mbHasText )
+ {
+ pForwardControl = pEntry->mpControl;
+ }
+ }
+
+ }
+ if( pForwardControl )
+ pForwardControl->KeyInput( rKEvent );
+
+}
+
+// --------------------------------------------------------------------
+static void ImplPaintCheckBackground( Window* i_pWindow, const Rectangle& i_rRect, bool i_bHighlight )
+{
+ BOOL bNativeOk = FALSE;
+ if( i_pWindow->IsNativeControlSupported( CTRL_TOOLBAR, PART_BUTTON ) )
+ {
+ ImplControlValue aControlValue;
+ Region aCtrlRegion( i_rRect );
+ ControlState nState = CTRL_STATE_PRESSED | CTRL_STATE_ENABLED;
+
+ aControlValue.setTristateVal( BUTTONVALUE_ON );
+
+ bNativeOk = i_pWindow->DrawNativeControl( CTRL_TOOLBAR, PART_BUTTON,
+ aCtrlRegion, nState, aControlValue,
+ rtl::OUString() );
+ }
+
+ if( ! bNativeOk )
+ {
+ const StyleSettings& rSettings = i_pWindow->GetSettings().GetStyleSettings();
+ Color aColor( i_bHighlight ? rSettings.GetMenuHighlightTextColor() : rSettings.GetHighlightColor() );
+ i_pWindow->DrawSelectionBackground( i_rRect, 0, i_bHighlight, TRUE, FALSE, 2, NULL, &aColor );
+ }
+}
+
+static long ImplGetNativeCheckAndRadioSize( Window* pWin, long& rCheckHeight, long& rRadioHeight, long &rMaxWidth )
+{
+ rMaxWidth = rCheckHeight = rRadioHeight = 0;
+
+ ImplControlValue aVal;
+ Region aNativeBounds;
+ Region aNativeContent;
+ Point tmp( 0, 0 );
+ Region aCtrlRegion( Rectangle( tmp, Size( 100, 15 ) ) );
+ if( pWin->IsNativeControlSupported( CTRL_MENU_POPUP, PART_MENU_ITEM_CHECK_MARK ) )
+ {
+ if( pWin->GetNativeControlRegion( ControlType(CTRL_MENU_POPUP),
+ ControlPart(PART_MENU_ITEM_CHECK_MARK),
+ aCtrlRegion,
+ ControlState(CTRL_STATE_ENABLED),
+ aVal,
+ OUString(),
+ aNativeBounds,
+ aNativeContent )
+ )
+ {
+ rCheckHeight = aNativeBounds.GetBoundRect().GetHeight();
+ rMaxWidth = aNativeContent.GetBoundRect().GetWidth();
+ }
+ }
+ if( pWin->IsNativeControlSupported( CTRL_MENU_POPUP, PART_MENU_ITEM_RADIO_MARK ) )
+ {
+ if( pWin->GetNativeControlRegion( ControlType(CTRL_MENU_POPUP),
+ ControlPart(PART_MENU_ITEM_RADIO_MARK),
+ aCtrlRegion,
+ ControlState(CTRL_STATE_ENABLED),
+ aVal,
+ OUString(),
+ aNativeBounds,
+ aNativeContent )
+ )
+ {
+ rRadioHeight = aNativeBounds.GetBoundRect().GetHeight();
+ rMaxWidth = Max (rMaxWidth, aNativeContent.GetBoundRect().GetWidth());
+ }
+ }
+ return (rCheckHeight > rRadioHeight) ? rCheckHeight : rRadioHeight;
+}
+
+void ToolbarMenu::implPaint( ToolbarMenuEntry* pThisOnly, bool bHighlighted )
+{
+ USHORT nBorder = 0; long nStartY = 0; // from Menu implementations, needed when we support native menu background & scrollable menu
+
+ long nFontHeight = GetTextHeight();
+// long nExtra = nFontHeight/4;
+
+ long nCheckHeight = 0, nRadioHeight = 0, nMaxCheckWidth = 0;
+ ImplGetNativeCheckAndRadioSize( this, nCheckHeight, nRadioHeight, nMaxCheckWidth );
+
+ DecorationView aDecoView( this );
+ const StyleSettings& rSettings = GetSettings().GetStyleSettings();
+ const bool bUseImages = rSettings.GetUseImagesInMenus();
+
+ int nOuterSpace = 0; // ImplGetSVData()->maNWFData.mnMenuFormatExtraBorder;
+ Point aTopLeft( nOuterSpace, nOuterSpace ), aTmpPos;
+
+ Size aOutSz( GetOutputSizePixel() );
+ const int nEntryCount = mpImpl->maEntryVector.size();
+ int nEntry;
+ for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
+ {
+ ToolbarMenuEntry* pEntry = mpImpl->maEntryVector[nEntry];
+
+ Point aPos( aTopLeft );
+ aPos.Y() += nBorder;
+ aPos.Y() += nStartY;
+
+
+ if( (pEntry == 0) && !pThisOnly )
+ {
+ // Separator
+ aTmpPos.Y() = aPos.Y() + ((SEPARATOR_HEIGHT-2)/2);
+ aTmpPos.X() = aPos.X() + 2 + nOuterSpace;
+ SetLineColor( rSettings.GetShadowColor() );
+ DrawLine( aTmpPos, Point( aOutSz.Width() - 3 - 2*nOuterSpace, aTmpPos.Y() ) );
+ aTmpPos.Y()++;
+ SetLineColor( rSettings.GetLightColor() );
+ DrawLine( aTmpPos, Point( aOutSz.Width() - 3 - 2*nOuterSpace, aTmpPos.Y() ) );
+ SetLineColor();
+ }
+ else if( !pThisOnly || ( pEntry == pThisOnly ) )
+ {
+ const bool bTitle = pEntry->mnEntryId == TITLE_ID;
+
+ if ( pThisOnly && bHighlighted )
+ SetTextColor( rSettings.GetMenuHighlightTextColor() );
+
+ if( aPos.Y() >= 0 )
+ {
+ long nTextOffsetY = ((pEntry->maSize.Height()-nFontHeight)/2);
+
+ USHORT nTextStyle = 0;
+ USHORT nSymbolStyle = 0;
+ USHORT nImageStyle = 0;
+
+ if( !pEntry->mbEnabled )
+ {
+ nTextStyle |= TEXT_DRAW_DISABLE;
+ nSymbolStyle |= SYMBOL_DRAW_DISABLE;
+ nImageStyle |= IMAGE_DRAW_DISABLE;
+ }
+
+ Rectangle aOuterCheckRect( Point( aPos.X()+mpImpl->mnCheckPos, aPos.Y() ), Size( pEntry->maSize.Height(), pEntry->maSize.Height() ) );
+ aOuterCheckRect.Left() += 1;
+ aOuterCheckRect.Right() -= 1;
+ aOuterCheckRect.Top() += 1;
+ aOuterCheckRect.Bottom() -= 1;
+
+ if( bTitle )
+ {
+ // fill the background
+ Rectangle aRect( aTopLeft, Size( aOutSz.Width(), pEntry->maSize.Height() ) );
+ SetFillColor(rSettings.GetDialogColor());
+ SetLineColor();
+ DrawRect(aRect);
+ SetLineColor( rSettings.GetLightColor() );
+ DrawLine( aRect.TopLeft(), aRect.TopRight() );
+ SetLineColor( rSettings.GetShadowColor() );
+ DrawLine( aRect.BottomLeft(), aRect.BottomRight() );
+ }
+
+ // CheckMark
+ if ( pEntry->HasCheck() )
+ {
+ // draw selection transparent marker if checked
+ // onto that either a checkmark or the item image
+ // will be painted
+ // however do not do this if native checks will be painted since
+ // the selection color too often does not fit the theme's check and/or radio
+
+ if( !pEntry->mbHasImage )
+ {
+ if( this->IsNativeControlSupported( CTRL_MENU_POPUP,
+ (pEntry->mnBits & MIB_RADIOCHECK)
+ ? PART_MENU_ITEM_CHECK_MARK
+ : PART_MENU_ITEM_RADIO_MARK ) )
+ {
+ ControlPart nPart = ((pEntry->mnBits & MIB_RADIOCHECK)
+ ? PART_MENU_ITEM_RADIO_MARK
+ : PART_MENU_ITEM_CHECK_MARK);
+
+ ControlState nState = 0;
+
+ if ( pEntry->mbChecked )
+ nState |= CTRL_STATE_PRESSED;
+
+ if ( pEntry->mbEnabled )
+ nState |= CTRL_STATE_ENABLED;
+
+ if ( bHighlighted )
+ nState |= CTRL_STATE_SELECTED;
+
+ long nCtrlHeight = (pEntry->mnBits & MIB_RADIOCHECK) ? nCheckHeight : nRadioHeight;
+ aTmpPos.X() = aOuterCheckRect.Left() + (aOuterCheckRect.GetWidth() - nCtrlHeight)/2;
+ aTmpPos.Y() = aOuterCheckRect.Top() + (aOuterCheckRect.GetHeight() - nCtrlHeight)/2;
+
+ Rectangle aCheckRect( aTmpPos, Size( nCtrlHeight, nCtrlHeight ) );
+ DrawNativeControl( CTRL_MENU_POPUP, nPart, Region( aCheckRect ), nState, ImplControlValue(), OUString() );
+ }
+ else if ( pEntry->mbChecked ) // by default do nothing for unchecked items
+ {
+ ImplPaintCheckBackground( this, aOuterCheckRect, pThisOnly && bHighlighted );
+
+ SymbolType eSymbol;
+ Size aSymbolSize;
+ if ( pEntry->mnBits & MIB_RADIOCHECK )
+ {
+ eSymbol = SYMBOL_RADIOCHECKMARK;
+ aSymbolSize = Size( nFontHeight/2, nFontHeight/2 );
+ }
+ else
+ {
+ eSymbol = SYMBOL_CHECKMARK;
+ aSymbolSize = Size( (nFontHeight*25)/40, nFontHeight/2 );
+ }
+ aTmpPos.X() = aOuterCheckRect.Left() + (aOuterCheckRect.GetWidth() - aSymbolSize.Width())/2;
+ aTmpPos.Y() = aOuterCheckRect.Top() + (aOuterCheckRect.GetHeight() - aSymbolSize.Height())/2;
+ Rectangle aRect( aTmpPos, aSymbolSize );
+ aDecoView.DrawSymbol( aRect, eSymbol, GetTextColor(), nSymbolStyle );
+ }
+ }
+ }
+
+ // Image:
+ if( pEntry->mbHasImage && bUseImages )
+ {
+ // Don't render an image for a check thing
+ /* if((nMenuFlags & MENU_FLAG_SHOWCHECKIMAGES) || !pEntry->HasCheck() )*/
+ {
+ if( pEntry->mbChecked )
+ ImplPaintCheckBackground( this, aOuterCheckRect, pThisOnly && bHighlighted );
+ aTmpPos = aOuterCheckRect.TopLeft();
+ aTmpPos.X() += (aOuterCheckRect.GetWidth()-pEntry->maImage.GetSizePixel().Width())/2;
+ aTmpPos.Y() += (aOuterCheckRect.GetHeight()-pEntry->maImage.GetSizePixel().Height())/2;
+ DrawImage( aTmpPos, pEntry->maImage, nImageStyle );
+ }
+ }
+
+ // Text:
+ if( pEntry->mbHasText )
+ {
+ aTmpPos.X() = aPos.X() + (bTitle ? 4 : mpImpl->mnTextPos);
+ aTmpPos.Y() = aPos.Y();
+ aTmpPos.Y() += nTextOffsetY;
+ USHORT nStyle = nTextStyle|TEXT_DRAW_MNEMONIC;
+
+ DrawCtrlText( aTmpPos, pEntry->maText, 0, pEntry->maText.Len(), nStyle, NULL, NULL ); // pVector, pDisplayText );
+ }
+
+/*
+ // Accel
+ if ( !bLayout && !bIsMenuBar && pData->aAccelKey.GetCode() && !ImplAccelDisabled() )
+ {
+ XubString aAccText = pData->aAccelKey.GetName();
+ aTmpPos.X() = aOutSz.Width() - this->GetTextWidth( aAccText );
+ aTmpPos.X() -= 4*nExtra;
+
+ aTmpPos.X() -= nOuterSpace;
+ aTmpPos.Y() = aPos.Y();
+ aTmpPos.Y() += nTextOffsetY;
+ this->DrawCtrlText( aTmpPos, aAccText, 0, aAccText.Len(), nTextStyle );
+ }
+*/
+
+/*
+ // SubMenu?
+ if ( !bLayout && !bIsMenuBar && pData->pSubMenu )
+ {
+ aTmpPos.X() = aOutSz.Width() - nFontHeight + nExtra - nOuterSpace;
+ aTmpPos.Y() = aPos.Y();
+ aTmpPos.Y() += nExtra/2;
+ aTmpPos.Y() += ( pEntry->maSize.Height() / 2 ) - ( nFontHeight/4 );
+ if ( pEntry->mnBits & MIB_POPUPSELECT )
+ {
+ this->SetTextColor( rSettings.GetMenuTextColor() );
+ Point aTmpPos2( aPos );
+ aTmpPos2.X() = aOutSz.Width() - nFontHeight - nFontHeight/4;
+ aDecoView.DrawFrame(
+ Rectangle( aTmpPos2, Size( nFontHeight+nFontHeight/4, pEntry->maSize.Height() ) ), FRAME_DRAW_GROUP );
+ }
+ aDecoView.DrawSymbol(
+ Rectangle( aTmpPos, Size( nFontHeight/2, nFontHeight/2 ) ),
+ SYMBOL_SPIN_RIGHT, this->GetTextColor(), nSymbolStyle );
+// if ( pEntry->mnBits & MIB_POPUPSELECT )
+// {
+// aTmpPos.Y() += nFontHeight/2 ;
+// this->SetLineColor( rSettings.GetShadowColor() );
+// this->DrawLine( aTmpPos, Point( aTmpPos.X() + nFontHeight/3, aTmpPos.Y() ) );
+// this->SetLineColor( rSettings.GetLightColor() );
+// aTmpPos.Y()++;
+// this->DrawLine( aTmpPos, Point( aTmpPos.X() + nFontHeight/3, aTmpPos.Y() ) );
+// this->SetLineColor();
+// }
+ }
+*/
+
+ if ( pThisOnly && bHighlighted )
+ {
+ // This restores the normal menu or menu bar text
+ // color for when it is no longer highlighted.
+ SetTextColor( rSettings.GetMenuTextColor() );
+ }
+ }
+ }
+
+ aTopLeft.Y() += pEntry ? pEntry->maSize.Height() : SEPARATOR_HEIGHT;
+ }
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::Paint( const Rectangle& )
+{
+ SetFillColor( GetSettings().GetStyleSettings().GetMenuColor() );
+
+ implPaint();
+
+ if( mpImpl->mnHighlightedEntry != -1 )
+ implHighlightEntry( mpImpl->mnHighlightedEntry, true );
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::RequestHelp( const HelpEvent& rHEvt )
+{
+ DockingWindow::RequestHelp( rHEvt );
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::StateChanged( StateChangedType nType )
+{
+ DockingWindow::StateChanged( nType );
+
+ if ( ( nType == STATE_CHANGE_CONTROLFOREGROUND ) || ( nType == STATE_CHANGE_CONTROLBACKGROUND ) )
+ {
+ initWindow();
+ Invalidate();
+ }
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ DockingWindow::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
+ {
+ initWindow();
+ Invalidate();
+ }
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::Command( const CommandEvent& rCEvt )
+{
+ if ( rCEvt.GetCommand() == COMMAND_WHEEL )
+ {
+ const CommandWheelData* pData = rCEvt.GetWheelData();
+ if( !pData->GetModifier() && ( pData->GetMode() == COMMAND_WHEEL_SCROLL ) )
+ {
+ implCursorUpDown( pData->GetDelta() > 0L, false );
+ }
+ }
+}
+
+// --------------------------------------------------------------------
+
+Reference< ::com::sun::star::accessibility::XAccessible > ToolbarMenu::CreateAccessible()
+{
+ mpImpl->setAccessible( new ToolbarMenuAcc( *mpImpl ) );
+ return Reference< XAccessible >( mpImpl->mxAccessible.get() );
+}
+
+// --------------------------------------------------------------------
+
+// todo: move to new base class that will replace SfxPopupWindo
+void ToolbarMenu::AddStatusListener( const rtl::OUString& rCommandURL )
+{
+ initStatusListener();
+ mpImpl->mxStatusListener->addStatusListener( rCommandURL );
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::RemoveStatusListener( const rtl::OUString& rCommandURL )
+{
+ mpImpl->mxStatusListener->removeStatusListener( rCommandURL );
+}
+// --------------------------------------------------------------------
+
+
+void ToolbarMenu::UpdateStatus( const rtl::OUString& rCommandURL )
+{
+ mpImpl->mxStatusListener->updateStatus( rCommandURL );
+}
+
+// --------------------------------------------------------------------
+
+// XStatusListener (subclasses must override this one to get the status updates
+void SAL_CALL ToolbarMenu::statusChanged( const ::com::sun::star::frame::FeatureStateEvent& /*Event*/ ) throw ( ::com::sun::star::uno::RuntimeException )
+{
+}
+
+// --------------------------------------------------------------------
+
+class ToolbarMenuStatusListener : public svt::FrameStatusListener
+{
+public:
+ ToolbarMenuStatusListener( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& xServiceManager,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame,
+ ToolbarMenu& rToolbarMenu );
+
+ virtual void SAL_CALL dispose() throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL statusChanged( const ::com::sun::star::frame::FeatureStateEvent& Event ) throw ( ::com::sun::star::uno::RuntimeException );
+
+ ToolbarMenu* mpMenu;
+};
+
+// --------------------------------------------------------------------
+
+ToolbarMenuStatusListener::ToolbarMenuStatusListener(
+ const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& xServiceManager,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame,
+ ToolbarMenu& rToolbarMenu )
+: svt::FrameStatusListener( xServiceManager, xFrame )
+, mpMenu( &rToolbarMenu )
+{
+}
+
+// --------------------------------------------------------------------
+
+void SAL_CALL ToolbarMenuStatusListener::dispose() throw (::com::sun::star::uno::RuntimeException)
+{
+ mpMenu = 0;
+ svt::FrameStatusListener::dispose();
+}
+
+// --------------------------------------------------------------------
+
+void SAL_CALL ToolbarMenuStatusListener::statusChanged( const ::com::sun::star::frame::FeatureStateEvent& Event ) throw ( ::com::sun::star::uno::RuntimeException )
+{
+ if( mpMenu )
+ mpMenu->statusChanged( Event );
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::initStatusListener()
+{
+ if( !mpImpl->mxStatusListener.is() )
+ mpImpl->mxStatusListener.set( new ToolbarMenuStatusListener( mpImpl->mxServiceManager, mpImpl->mxFrame, *this ) );
+}
+
+// --------------------------------------------------------------------
+
+bool ToolbarMenu::IsInPopupMode()
+{
+ return GetDockingManager()->IsInPopupMode(this);
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::EndPopupMode()
+{
+ GetDockingManager()->EndPopupMode(this);
+}
+
+// --------------------------------------------------------------------
+
+const Size& ToolbarMenu::getMenuSize() const
+{
+ return mpImpl->maSize;
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::SetSelectHdl( const Link& rLink )
+{
+ mpImpl->maSelectHdl = rLink;
+}
+
+// --------------------------------------------------------------------
+
+const Link& ToolbarMenu::GetSelectHdl() const
+{
+ return mpImpl->maSelectHdl;
+}
+
+// --------------------------------------------------------------------
+
+Reference< XFrame > ToolbarMenu::GetFrame() const
+{
+ return mpImpl->mxFrame;
+}
+
+// --------------------------------------------------------------------
+
+
+// --------------------------------------------------------------------
+
+}
+
+
diff --git a/svtools/source/control/toolbarmenuacc.cxx b/svtools/source/control/toolbarmenuacc.cxx
new file mode 100644
index 000000000000..020467084748
--- /dev/null
+++ b/svtools/source/control/toolbarmenuacc.cxx
@@ -0,0 +1,1003 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+
+#include <unotools/accessiblestatesethelper.hxx>
+
+#include <vcl/svapp.hxx>
+
+#include "svtools/toolbarmenu.hxx"
+
+#include "toolbarmenuimp.hxx"
+
+using ::rtl::OUString;
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::accessibility;
+
+namespace svtools {
+
+// ------------------
+// - ToolbarMenuAcc -
+// ------------------
+
+ToolbarMenuAcc::ToolbarMenuAcc( ToolbarMenu_Impl& rParent )
+: ToolbarMenuAccComponentBase(m_aMutex)
+, mpParent( &rParent )
+, mbIsFocused(false)
+{
+ mpParent->mrMenu.AddEventListener( LINK( this, ToolbarMenuAcc, WindowEventListener ) );
+}
+
+// -----------------------------------------------------------------------------
+
+ToolbarMenuAcc::~ToolbarMenuAcc()
+{
+ if( mpParent )
+ mpParent->mrMenu.RemoveEventListener( LINK( this, ToolbarMenuAcc, WindowEventListener ) );
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ToolbarMenuAcc, WindowEventListener, VclSimpleEvent*, pEvent )
+{
+ DBG_ASSERT( pEvent && pEvent->ISA( VclWindowEvent ), "Unknown WindowEvent!" );
+
+ /* Ignore VCLEVENT_WINDOW_ENDPOPUPMODE, because the UNO accessibility wrapper
+ * might have been destroyed by the previous VCLEventListener (if no AT tool
+ * is running), e.g. sub-toolbars in impress.
+ */
+ if ( mpParent && pEvent && pEvent->ISA( VclWindowEvent ) && (pEvent->GetId() != VCLEVENT_WINDOW_ENDPOPUPMODE) )
+ {
+ DBG_ASSERT( ((VclWindowEvent*)pEvent)->GetWindow(), "Window???" );
+ if( !((VclWindowEvent*)pEvent)->GetWindow()->IsAccessibilityEventsSuppressed() || ( pEvent->GetId() == VCLEVENT_OBJECT_DYING ) )
+ {
+ ProcessWindowEvent( *(VclWindowEvent*)pEvent );
+ }
+ }
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void ToolbarMenuAcc::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
+{
+ Any aOldValue, aNewValue;
+
+ switch ( rVclWindowEvent.GetId() )
+ {
+ case VCLEVENT_OBJECT_DYING:
+ {
+ mpParent->mrMenu.RemoveEventListener( LINK( this, ToolbarMenuAcc, WindowEventListener ) );
+ mpParent = 0;
+ }
+ break;
+
+ case VCLEVENT_WINDOW_GETFOCUS:
+ {
+ if( !mbIsFocused )
+ {
+ mpParent->notifyHighlightedEntry();
+ mbIsFocused = true;
+ }
+ }
+ break;
+ case VCLEVENT_WINDOW_LOSEFOCUS:
+ {
+ if( mbIsFocused )
+ {
+ mbIsFocused = false;
+ }
+ }
+ break;
+ default:
+ {
+ }
+ break;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ToolbarMenuAcc::FireAccessibleEvent( short nEventId, const Any& rOldValue, const Any& rNewValue )
+{
+ if( nEventId )
+ {
+ EventListenerVector aTmpListeners( mxEventListeners );
+ EventListenerVector::const_iterator aIter( aTmpListeners.begin() );
+ AccessibleEventObject aEvtObject;
+
+ aEvtObject.EventId = nEventId;
+ aEvtObject.Source = static_cast<XWeak*>(this);
+ aEvtObject.NewValue = rNewValue;
+ aEvtObject.OldValue = rOldValue;
+
+ while( aIter != aTmpListeners.end() )
+ {
+ try
+ {
+ (*aIter)->notifyEvent( aEvtObject );
+ }
+ catch( Exception& )
+ {
+ }
+
+ aIter++;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XAccessibleContext > SAL_CALL ToolbarMenuAcc::getAccessibleContext() throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ return this;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL ToolbarMenuAcc::getAccessibleChildCount() throw (RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ThrowIfDisposed();
+
+ return mpParent->getAccessibleChildCount();
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XAccessible > SAL_CALL ToolbarMenuAcc::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ThrowIfDisposed();
+
+ return mpParent->getAccessibleChild(i);
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XAccessible > SAL_CALL ToolbarMenuAcc::getAccessibleParent() throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+
+ Reference< XAccessible > xRet;
+
+ Window* pParent = mpParent->mrMenu.GetParent();
+ if( pParent )
+ xRet = pParent->GetAccessible();
+
+ return xRet;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL ToolbarMenuAcc::getAccessibleIndexInParent() throw (RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ThrowIfDisposed();
+
+ Window* pParent = mpParent->mrMenu.GetParent();
+ if( pParent )
+ {
+ for( USHORT i = 0, nCount = pParent->GetChildCount(); i < nCount ; i++ )
+ {
+ if( pParent->GetChild( i ) == &mpParent->mrMenu )
+ return i;
+ }
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int16 SAL_CALL ToolbarMenuAcc::getAccessibleRole() throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ return AccessibleRole::LIST;
+}
+
+// -----------------------------------------------------------------------------
+
+OUString SAL_CALL ToolbarMenuAcc::getAccessibleDescription() throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ return OUString( RTL_CONSTASCII_USTRINGPARAM( "ToolbarMenu" ) );
+}
+
+// -----------------------------------------------------------------------------
+
+OUString SAL_CALL ToolbarMenuAcc::getAccessibleName() throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ OUString aRet;
+
+ if( mpParent )
+ aRet = mpParent->mrMenu.GetAccessibleName();
+
+ if( !aRet.getLength() )
+ {
+ Window* pLabel = mpParent->mrMenu.GetLabeledBy();
+ if( pLabel && pLabel != &mpParent->mrMenu )
+ aRet = OutputDevice::GetNonMnemonicString( pLabel->GetText() );
+ }
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XAccessibleRelationSet > SAL_CALL ToolbarMenuAcc::getAccessibleRelationSet() throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ return Reference< XAccessibleRelationSet >();
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XAccessibleStateSet > SAL_CALL ToolbarMenuAcc::getAccessibleStateSet() throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ ::utl::AccessibleStateSetHelper* pStateSet = new ::utl::AccessibleStateSetHelper();
+
+ // Set some states.
+ pStateSet->AddState (AccessibleStateType::ENABLED);
+ pStateSet->AddState (AccessibleStateType::SENSITIVE);
+ pStateSet->AddState (AccessibleStateType::SHOWING);
+ pStateSet->AddState (AccessibleStateType::VISIBLE);
+ pStateSet->AddState (AccessibleStateType::MANAGES_DESCENDANTS);
+ pStateSet->AddState (AccessibleStateType::FOCUSABLE);
+ if (mbIsFocused)
+ pStateSet->AddState (AccessibleStateType::FOCUSED);
+
+ return pStateSet;
+}
+
+// -----------------------------------------------------------------------------
+
+Locale SAL_CALL ToolbarMenuAcc::getLocale() throw (IllegalAccessibleComponentStateException, RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ const ::rtl::OUString aEmptyStr;
+ Reference< XAccessible > xParent( getAccessibleParent() );
+ Locale aRet( aEmptyStr, aEmptyStr, aEmptyStr );
+
+ if( xParent.is() )
+ {
+ Reference< XAccessibleContext > xParentContext( xParent->getAccessibleContext() );
+
+ if( xParentContext.is() )
+ aRet = xParentContext->getLocale ();
+ }
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ToolbarMenuAcc::addEventListener( const Reference< XAccessibleEventListener >& rxListener ) throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ ::osl::MutexGuard aGuard(m_aMutex);
+
+ if( rxListener.is() )
+ {
+ EventListenerVector::const_iterator aIter = mxEventListeners.begin();
+ bool bFound = false;
+
+ while( !bFound && ( aIter != mxEventListeners.end() ) )
+ {
+ if( *aIter == rxListener )
+ bFound = true;
+ else
+ aIter++;
+ }
+
+ if (!bFound)
+ mxEventListeners.push_back( rxListener );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ToolbarMenuAcc::removeEventListener( const Reference< XAccessibleEventListener >& rxListener ) throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ ::osl::MutexGuard aGuard(m_aMutex);
+
+ if( rxListener.is() )
+ {
+ EventListenerVector::iterator aIter = mxEventListeners.begin();
+ bool bFound = false;
+
+ while( !bFound && ( aIter != mxEventListeners.end() ) )
+ {
+ if( *aIter == rxListener )
+ {
+ mxEventListeners.erase( aIter );
+ bFound = true;
+ }
+ else
+ aIter++;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool SAL_CALL ToolbarMenuAcc::containsPoint( const awt::Point& aPoint ) throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ const awt::Rectangle aRect( getBounds() );
+ const Point aSize( aRect.Width, aRect.Height );
+ const Point aNullPoint, aTestPoint( aPoint.X, aPoint.Y );
+
+ return Rectangle( aNullPoint, aSize ).IsInside( aTestPoint );
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XAccessible > SAL_CALL ToolbarMenuAcc::getAccessibleAtPoint( const awt::Point& aPoint ) throw (RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ThrowIfDisposed();
+
+ Reference< XAccessible > xRet;
+
+ const Point aVclPoint( aPoint.X, aPoint.Y );
+
+ const int nEntryCount = mpParent->maEntryVector.size();
+ for( int nEntry = 0; (nEntry < nEntryCount) && !xRet.is(); nEntry++ )
+ {
+ ToolbarMenuEntry* pEntry = mpParent->maEntryVector[nEntry];
+ if( pEntry && pEntry->maRect.IsInside( aVclPoint ) )
+ {
+ if( pEntry->mpControl )
+ {
+ awt::Point aChildPoint( aPoint.X - pEntry->maRect.Left(), aPoint.Y - pEntry->maRect.Top() );
+ Reference< XAccessibleComponent > xComp( pEntry->GetAccessible(true), UNO_QUERY_THROW );
+ xRet = xComp->getAccessibleAtPoint(aChildPoint);
+ }
+ else
+ {
+ xRet = Reference< XAccessible >( pEntry->GetAccessible(true), UNO_QUERY );
+ }
+ }
+ }
+ return xRet;
+}
+
+// -----------------------------------------------------------------------------
+
+awt::Rectangle SAL_CALL ToolbarMenuAcc::getBounds() throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ const Point aOutPos( mpParent->mrMenu.GetPosPixel() );
+ const Size aOutSize( mpParent->mrMenu.GetOutputSizePixel() );
+ awt::Rectangle aRet;
+
+ aRet.X = aOutPos.X();
+ aRet.Y = aOutPos.Y();
+ aRet.Width = aOutSize.Width();
+ aRet.Height = aOutSize.Height();
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+awt::Point SAL_CALL ToolbarMenuAcc::getLocation() throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ const Point aOutPos( mpParent->mrMenu.GetPosPixel() );
+ return awt::Point( aOutPos.X(), aOutPos.Y() );
+}
+
+// -----------------------------------------------------------------------------
+
+awt::Point SAL_CALL ToolbarMenuAcc::getLocationOnScreen() throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ const Point aScreenPos( mpParent->mrMenu.OutputToAbsoluteScreenPixel( Point() ) );
+ return awt::Point( aScreenPos.X(), aScreenPos.Y() );
+}
+
+// -----------------------------------------------------------------------------
+
+awt::Size SAL_CALL ToolbarMenuAcc::getSize() throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ const Size aOutSize( mpParent->mrMenu.GetOutputSizePixel() );
+ return awt::Size( aOutSize.Width(), aOutSize.Height() );
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ToolbarMenuAcc::grabFocus() throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ mpParent->mrMenu.GrabFocus();
+}
+
+// -----------------------------------------------------------------------------
+
+Any SAL_CALL ToolbarMenuAcc::getAccessibleKeyBinding() throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ return Any();
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL ToolbarMenuAcc::getForeground() throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ UINT32 nColor = Application::GetSettings().GetStyleSettings().GetMenuTextColor().GetColor();
+ return static_cast<sal_Int32>(nColor);
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL ToolbarMenuAcc::getBackground() throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ UINT32 nColor = Application::GetSettings().GetStyleSettings().GetMenuColor().GetColor();
+ return static_cast<sal_Int32>(nColor);
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ToolbarMenuAcc::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ThrowIfDisposed();
+
+ mpParent->selectAccessibleChild( nChildIndex );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool SAL_CALL ToolbarMenuAcc::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ThrowIfDisposed();
+ return mpParent->isAccessibleChildSelected( nChildIndex );
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ToolbarMenuAcc::clearAccessibleSelection() throw (RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ThrowIfDisposed();
+ mpParent->clearAccessibleSelection();
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ToolbarMenuAcc::selectAllAccessibleChildren() throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ // unsupported due to single selection only
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL ToolbarMenuAcc::getSelectedAccessibleChildCount() throw (RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ThrowIfDisposed();
+
+ return mpParent->mnHighlightedEntry != -1 ? 1 : 0;
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XAccessible > SAL_CALL ToolbarMenuAcc::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+
+ if( (mpParent->mnHighlightedEntry != -1) && (nSelectedChildIndex == 0) )
+ {
+ ToolbarMenuEntry* pEntry = mpParent->maEntryVector[ mpParent->mnHighlightedEntry ];
+ if( pEntry )
+ {
+ if( pEntry->mpControl )
+ {
+ Reference< XAccessibleSelection > xSel( pEntry->GetAccessible(true), UNO_QUERY_THROW );
+ return xSel->getSelectedAccessibleChild(0);
+ }
+ else
+ return Reference< XAccessible >( pEntry->GetAccessible(true), UNO_QUERY );
+ }
+ }
+
+ throw IndexOutOfBoundsException();
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ToolbarMenuAcc::deselectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ ThrowIfDisposed();
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ // Because of the single selection we can reset the whole selection when
+ // the specified child is currently selected.
+ if (isAccessibleChildSelected(nChildIndex))
+ mpParent->clearAccessibleSelection();
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ToolbarMenuAcc::disposing (void)
+{
+ EventListenerVector aListenerListCopy;
+
+ {
+ // Make a copy of the list and clear the original.
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ::osl::MutexGuard aGuard (m_aMutex);
+ aListenerListCopy = mxEventListeners;
+ mxEventListeners.clear();
+
+ // Reset the pointer to the parent. It has to be the one who has
+ // disposed us because he is dying.
+ mpParent = NULL;
+ }
+
+ // Inform all listeners that this objects is disposing.
+ EventListenerVector::const_iterator aListenerIterator (aListenerListCopy.begin());
+ EventObject aEvent (static_cast<XAccessible*>(this));
+ while(aListenerIterator != aListenerListCopy.end())
+ {
+ try
+ {
+ (*aListenerIterator)->disposing (aEvent);
+ }
+ catch( Exception& )
+ {
+ // Ignore exceptions.
+ }
+
+ ++aListenerIterator;
+ }
+}
+
+void ToolbarMenuAcc::ThrowIfDisposed (void) throw (DisposedException)
+{
+ if(rBHelper.bDisposed || rBHelper.bInDispose || !mpParent)
+ {
+ throw DisposedException ( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("object has been already disposed")), static_cast<XWeak*>(this));
+ }
+}
+
+// -----------------------
+// - ToolbarMenuEntryAcc -
+// -----------------------
+
+ToolbarMenuEntryAcc::ToolbarMenuEntryAcc( ToolbarMenuEntry* pParent )
+: ToolbarMenuEntryAccBase( m_aMutex )
+, mpParent( pParent )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+ToolbarMenuEntryAcc::~ToolbarMenuEntryAcc()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void ToolbarMenuEntryAcc::FireAccessibleEvent( short nEventId, const Any& rOldValue, const Any& rNewValue )
+{
+ if( nEventId )
+ {
+ EventListenerVector aTmpListeners( mxEventListeners );
+ ::std::vector< Reference< XAccessibleEventListener > >::const_iterator aIter( aTmpListeners.begin() );
+ AccessibleEventObject aEvtObject;
+
+ aEvtObject.EventId = nEventId;
+ aEvtObject.Source = static_cast<XWeak*>(this);
+ aEvtObject.NewValue = rNewValue;
+ aEvtObject.OldValue = rOldValue;
+
+ while( aIter != aTmpListeners.end() )
+ {
+ (*aIter)->notifyEvent( aEvtObject );
+ aIter++;
+ }
+ }
+}
+
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ToolbarMenuEntryAcc::disposing (void)
+{
+ EventListenerVector aListenerListCopy;
+
+ {
+ // Make a copy of the list and clear the original.
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ::osl::MutexGuard aGuard (m_aMutex);
+ aListenerListCopy = mxEventListeners;
+ mxEventListeners.clear();
+
+ // Reset the pointer to the parent. It has to be the one who has
+ // disposed us because he is dying.
+ mpParent = NULL;
+ }
+
+ // Inform all listeners that this objects is disposing.
+ EventListenerVector::const_iterator aListenerIterator (aListenerListCopy.begin());
+ EventObject aEvent (static_cast<XAccessible*>(this));
+ while(aListenerIterator != aListenerListCopy.end())
+ {
+ try
+ {
+ (*aListenerIterator)->disposing (aEvent);
+ }
+ catch( Exception& )
+ {
+ // Ignore exceptions.
+ }
+
+ ++aListenerIterator;
+ }
+}
+// -----------------------------------------------------------------------------
+
+Reference< XAccessibleContext > SAL_CALL ToolbarMenuEntryAcc::getAccessibleContext() throw (RuntimeException)
+{
+ return this;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL ToolbarMenuEntryAcc::getAccessibleChildCount() throw (RuntimeException)
+{
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XAccessible > SAL_CALL ToolbarMenuEntryAcc::getAccessibleChild( sal_Int32 ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ throw IndexOutOfBoundsException();
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XAccessible > SAL_CALL ToolbarMenuEntryAcc::getAccessibleParent() throw (RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ Reference< XAccessible > xRet;
+
+ if( mpParent )
+ xRet = mpParent->mrMenu.GetAccessible();
+
+ return xRet;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL ToolbarMenuEntryAcc::getAccessibleIndexInParent() throw (RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ // The index defaults to -1 to indicate the child does not belong to its
+ // parent.
+ sal_Int32 nIndexInParent = -1;
+
+ if( mpParent )
+ {
+ Reference< XAccessibleContext > xParent( mpParent->mrMenu.GetAccessible(), UNO_QUERY );
+
+ if( xParent.is() )
+ {
+ Reference< XAccessible > xThis( this );
+
+ const sal_Int32 nCount = xParent->getAccessibleChildCount();
+ for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
+ {
+ if( xParent->getAccessibleChild(nIndex) == xThis )
+ {
+ nIndexInParent = nIndex;
+ break;
+ }
+ }
+ }
+ }
+
+ return nIndexInParent;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int16 SAL_CALL ToolbarMenuEntryAcc::getAccessibleRole() throw (RuntimeException)
+{
+ return AccessibleRole::LIST_ITEM;
+}
+
+// -----------------------------------------------------------------------------
+
+::rtl::OUString SAL_CALL ToolbarMenuEntryAcc::getAccessibleDescription() throw (RuntimeException)
+{
+ return ::rtl::OUString();
+}
+
+// -----------------------------------------------------------------------------
+
+::rtl::OUString SAL_CALL ToolbarMenuEntryAcc::getAccessibleName() throw (RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ String aRet;
+
+ if( mpParent )
+ {
+ aRet = mpParent->maText;
+
+ if( !aRet.Len() )
+ {
+ aRet = String( RTL_CONSTASCII_USTRINGPARAM( "Item " ) );
+ aRet += String::CreateFromInt32( mpParent->mnEntryId );
+ }
+ }
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XAccessibleRelationSet > SAL_CALL ToolbarMenuEntryAcc::getAccessibleRelationSet() throw (RuntimeException)
+{
+ return Reference< XAccessibleRelationSet >();
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XAccessibleStateSet > SAL_CALL ToolbarMenuEntryAcc::getAccessibleStateSet() throw (RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ::utl::AccessibleStateSetHelper* pStateSet = new ::utl::AccessibleStateSetHelper;
+
+ if( mpParent )
+ {
+ pStateSet->AddState (AccessibleStateType::ENABLED);
+ pStateSet->AddState (AccessibleStateType::SENSITIVE);
+ pStateSet->AddState (AccessibleStateType::SHOWING);
+ pStateSet->AddState (AccessibleStateType::VISIBLE);
+ pStateSet->AddState (AccessibleStateType::TRANSIENT);
+ if( mpParent->mnEntryId != TITLE_ID )
+ {
+ pStateSet->AddState( AccessibleStateType::SELECTABLE );
+
+ // SELECTED
+ if( mpParent->mrMenu.getHighlightedEntryId() == mpParent->mnEntryId )
+ pStateSet->AddState( AccessibleStateType::SELECTED );
+ }
+ }
+
+ return pStateSet;
+}
+
+// -----------------------------------------------------------------------------
+
+Locale SAL_CALL ToolbarMenuEntryAcc::getLocale() throw (IllegalAccessibleComponentStateException, RuntimeException)
+{
+ const ::rtl::OUString aEmptyStr;
+ Locale aRet( aEmptyStr, aEmptyStr, aEmptyStr );
+
+ Reference< XAccessible > xParent( getAccessibleParent() );
+ if( xParent.is() )
+ {
+ Reference< XAccessibleContext > xParentContext( xParent->getAccessibleContext() );
+
+ if( xParentContext.is() )
+ aRet = xParentContext->getLocale();
+ }
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ToolbarMenuEntryAcc::addEventListener( const Reference< XAccessibleEventListener >& rxListener ) throw (RuntimeException)
+{
+ const ::vos::OGuard aGuard( maMutex );
+
+ if( rxListener.is() )
+ {
+ EventListenerVector::const_iterator aIter( mxEventListeners.begin() );
+ bool bFound = false;
+
+ while( !bFound && ( aIter != mxEventListeners.end() ) )
+ {
+ if( *aIter == rxListener )
+ bFound = true;
+ else
+ aIter++;
+ }
+
+ if (!bFound)
+ mxEventListeners.push_back( rxListener );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ToolbarMenuEntryAcc::removeEventListener( const Reference< XAccessibleEventListener >& rxListener ) throw (RuntimeException)
+{
+ const ::vos::OGuard aGuard( maMutex );
+
+ if( rxListener.is() )
+ {
+ EventListenerVector::iterator aIter = mxEventListeners.begin();
+ bool bFound = false;
+
+ while( !bFound && ( aIter != mxEventListeners.end() ) )
+ {
+ if( *aIter == rxListener )
+ {
+ mxEventListeners.erase( aIter );
+ bFound = true;
+ }
+ else
+ aIter++;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool SAL_CALL ToolbarMenuEntryAcc::containsPoint( const awt::Point& aPoint ) throw (RuntimeException)
+{
+ const awt::Rectangle aRect( getBounds() );
+ const Point aSize( aRect.Width, aRect.Height );
+ const Point aNullPoint, aTestPoint( aPoint.X, aPoint.Y );
+
+ return Rectangle( aNullPoint, aSize ).IsInside( aTestPoint );
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XAccessible > SAL_CALL ToolbarMenuEntryAcc::getAccessibleAtPoint( const awt::Point& ) throw (RuntimeException)
+{
+ Reference< XAccessible > xRet;
+ return xRet;
+}
+
+// -----------------------------------------------------------------------------
+
+awt::Rectangle SAL_CALL ToolbarMenuEntryAcc::getBounds() throw (RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ awt::Rectangle aRet;
+
+ if( mpParent )
+ {
+ Rectangle aRect( mpParent->maRect );
+ Point aOrigin;
+ Rectangle aParentRect( aOrigin, mpParent->mrMenu.GetOutputSizePixel() );
+
+ aRect.Intersection( aParentRect );
+
+ aRet.X = aRect.Left();
+ aRet.Y = aRect.Top();
+ aRet.Width = aRect.GetWidth();
+ aRet.Height = aRect.GetHeight();
+ }
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+awt::Point SAL_CALL ToolbarMenuEntryAcc::getLocation() throw (RuntimeException)
+{
+ const awt::Rectangle aRect( getBounds() );
+ return awt::Point( aRect.X, aRect.Y );
+}
+
+// -----------------------------------------------------------------------------
+
+awt::Point SAL_CALL ToolbarMenuEntryAcc::getLocationOnScreen() throw (RuntimeException)
+{
+ const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ awt::Point aRet;
+
+ if( mpParent )
+ {
+ const Point aScreenPos( mpParent->mrMenu.OutputToAbsoluteScreenPixel( mpParent->maRect.TopLeft() ) );
+
+ aRet.X = aScreenPos.X();
+ aRet.Y = aScreenPos.Y();
+ }
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+awt::Size SAL_CALL ToolbarMenuEntryAcc::getSize() throw (RuntimeException)
+{
+ const awt::Rectangle aRect( getBounds() );
+ awt::Size aRet;
+
+ aRet.Width = aRect.Width;
+ aRet.Height = aRect.Height;
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ToolbarMenuEntryAcc::grabFocus() throw (RuntimeException)
+{
+ // nothing to do
+}
+
+// -----------------------------------------------------------------------------
+
+Any SAL_CALL ToolbarMenuEntryAcc::getAccessibleKeyBinding() throw (RuntimeException)
+{
+ return Any();
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL ToolbarMenuEntryAcc::getForeground( ) throw (RuntimeException)
+{
+ return static_cast<sal_Int32>(Application::GetSettings().GetStyleSettings().GetMenuTextColor().GetColor());
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL ToolbarMenuEntryAcc::getBackground( ) throw (RuntimeException)
+{
+ return static_cast<sal_Int32>(Application::GetSettings().GetStyleSettings().GetMenuColor().GetColor());
+}
+
+}
diff --git a/svtools/source/control/toolbarmenuimp.hxx b/svtools/source/control/toolbarmenuimp.hxx
new file mode 100644
index 000000000000..d1de4f704b76
--- /dev/null
+++ b/svtools/source/control/toolbarmenuimp.hxx
@@ -0,0 +1,314 @@
+/*************************************************************************
+ *
+ * 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 <vos/mutex.hxx>
+#include <vcl/image.hxx>
+#include <vcl/menu.hxx>
+
+#include <cppuhelper/compbase4.hxx>
+#include <cppuhelper/compbase5.hxx>
+#include <comphelper/broadcasthelper.hxx>
+
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/XAccessibleContext.hpp>
+#include <com/sun/star/accessibility/XAccessibleComponent.hpp>
+#include <com/sun/star/accessibility/XAccessibleSelection.hpp>
+#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+
+#include <rtl/ref.hxx>
+
+#include <vector>
+
+#include "framestatuslistener.hxx"
+
+#include "svtools/valueset.hxx"
+
+namespace svtools {
+
+struct ToolbarMenu_Impl;
+class ToolbarMenu;
+class ToolbarMenuEntry;
+
+typedef ::std::vector< ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener > > EventListenerVector;
+typedef std::vector< ToolbarMenuEntry * > ToolbarMenuEntryVector;
+
+const int EXTRAITEMHEIGHT = 0; // 4;
+const int SEPARATOR_HEIGHT = 4;
+const int TITLE_ID = -1;
+const int BORDER_X = 0;
+const int BORDER_Y = 0;
+
+// --------------------
+// - ToolbarMenuEntry -
+// --------------------
+
+class ToolbarMenuEntry
+{
+public:
+ ToolbarMenu& mrMenu;
+
+ int mnEntryId;
+ MenuItemBits mnBits;
+ Size maSize;
+
+ bool mbHasText;
+ bool mbHasImage;
+ bool mbChecked;
+ bool mbEnabled;
+
+ String maText;
+ Image maImage;
+ Control* mpControl;
+ Rectangle maRect;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > mxAccContext;
+
+public:
+ ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, const String& rText, MenuItemBits nBits );
+ ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, const Image& rImage, MenuItemBits nBits );
+ ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, const Image& rImage, const String& rText, MenuItemBits nBits );
+ ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, Control* pControl, MenuItemBits nBits );
+ ~ToolbarMenuEntry();
+
+ void init( int nEntryId, MenuItemBits nBits );
+
+ const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >& GetAccessible( bool bCreate = false );
+
+ sal_Int32 getAccessibleChildCount() throw (::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > getAccessibleChild( sal_Int32 index ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ void selectAccessibleChild( sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+
+ bool HasCheck() const
+ {
+ return mbChecked || ( mnBits & ( MIB_RADIOCHECK | MIB_CHECKABLE | MIB_AUTOCHECK ) );
+ }
+};
+
+// ---------------
+// - ToolbarMenuAcc -
+// ---------------
+
+typedef ::cppu::WeakComponentImplHelper5<
+ ::com::sun::star::accessibility::XAccessible,
+ ::com::sun::star::accessibility::XAccessibleEventBroadcaster,
+ ::com::sun::star::accessibility::XAccessibleContext,
+ ::com::sun::star::accessibility::XAccessibleComponent,
+ ::com::sun::star::accessibility::XAccessibleSelection >
+ ToolbarMenuAccComponentBase;
+
+class ToolbarMenuAcc :
+ public ::comphelper::OBaseMutex,
+ public ToolbarMenuAccComponentBase
+{
+public:
+
+ ToolbarMenuAcc( ToolbarMenu_Impl& rParent );
+ ~ToolbarMenuAcc();
+
+ void FireAccessibleEvent( short nEventId, const ::com::sun::star::uno::Any& rOldValue, const ::com::sun::star::uno::Any& rNewValue );
+ bool HasAccessibleListeners() const { return( mxEventListeners.size() > 0 ); }
+
+public:
+ // XAccessible
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleEventBroadcaster
+ using cppu::WeakComponentImplHelper5<com::sun::star::accessibility::XAccessible, com::sun::star::accessibility::XAccessibleEventBroadcaster, com::sun::star::accessibility::XAccessibleContext, com::sun::star::accessibility::XAccessibleComponent, com::sun::star::accessibility::XAccessibleSelection>::addEventListener;
+ virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+ using cppu::WeakComponentImplHelper5<com::sun::star::accessibility::XAccessible, com::sun::star::accessibility::XAccessibleEventBroadcaster, com::sun::star::accessibility::XAccessibleContext, com::sun::star::accessibility::XAccessibleComponent, com::sun::star::accessibility::XAccessibleSelection>::removeEventListener;
+ virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleContext
+ virtual sal_Int32 SAL_CALL getAccessibleChildCount( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getAccessibleIndexInParent( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int16 SAL_CALL getAccessibleRole( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getAccessibleDescription( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getAccessibleName( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleStateSet > SAL_CALL getAccessibleStateSet( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::lang::Locale SAL_CALL getLocale( ) throw (::com::sun::star::accessibility::IllegalAccessibleComponentStateException, ::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleComponent
+ virtual sal_Bool SAL_CALL containsPoint( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::Rectangle SAL_CALL getBounds( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::Point SAL_CALL getLocation( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::Point SAL_CALL getLocationOnScreen( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::Size SAL_CALL getSize( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL grabFocus( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Any SAL_CALL getAccessibleKeyBinding( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getForeground( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getBackground( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleSelection
+ virtual void SAL_CALL selectAccessibleChild( sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL clearAccessibleSelection( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL selectAllAccessibleChildren( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getSelectedAccessibleChildCount( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL deselectAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+
+ DECL_LINK( WindowEventListener, VclSimpleEvent* );
+
+private:
+ EventListenerVector mxEventListeners;
+ ToolbarMenu_Impl* mpParent;
+ /// The current FOCUSED state.
+ bool mbIsFocused;
+
+ void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent );
+
+ /** Tell all listeners that the object is dying. This callback is
+ usually called from the WeakComponentImplHelper class.
+ */
+ virtual void SAL_CALL disposing (void);
+
+ /** Check whether or not the object has been disposed (or is in the
+ state of beeing disposed). If that is the case then
+ DisposedException is thrown to inform the (indirect) caller of the
+ foul deed.
+ */
+ void ThrowIfDisposed (void) throw (::com::sun::star::lang::DisposedException);
+};
+
+// -----------------------
+// - ToolbarMenuEntryAcc -
+// -----------------------
+
+typedef ::cppu::WeakComponentImplHelper4< ::com::sun::star::accessibility::XAccessible,
+ ::com::sun::star::accessibility::XAccessibleEventBroadcaster,
+ ::com::sun::star::accessibility::XAccessibleContext,
+ ::com::sun::star::accessibility::XAccessibleComponent > ToolbarMenuEntryAccBase;
+
+class ToolbarMenuEntryAcc : public ::comphelper::OBaseMutex,
+ public ToolbarMenuEntryAccBase
+{
+public:
+ ToolbarMenuEntryAcc( ToolbarMenuEntry* pParent );
+ ~ToolbarMenuEntryAcc();
+
+ void FireAccessibleEvent( short nEventId, const ::com::sun::star::uno::Any& rOldValue, const ::com::sun::star::uno::Any& rNewValue );
+ bool HasAccessibleListeners() const { return( mxEventListeners.size() > 0 ); }
+
+ // XAccessible
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleEventBroadcaster
+ using ToolbarMenuEntryAccBase::addEventListener;
+ virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+ using ToolbarMenuEntryAccBase::removeEventListener;
+ virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleContext
+ virtual sal_Int32 SAL_CALL getAccessibleChildCount( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getAccessibleIndexInParent( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int16 SAL_CALL getAccessibleRole( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getAccessibleDescription( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getAccessibleName( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleStateSet > SAL_CALL getAccessibleStateSet( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::lang::Locale SAL_CALL getLocale( ) throw (::com::sun::star::accessibility::IllegalAccessibleComponentStateException, ::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleComponent
+ virtual sal_Bool SAL_CALL containsPoint( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::Rectangle SAL_CALL getBounds( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::Point SAL_CALL getLocation( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::Point SAL_CALL getLocationOnScreen( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::Size SAL_CALL getSize( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL grabFocus( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Any SAL_CALL getAccessibleKeyBinding( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getForeground( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getBackground( ) throw (::com::sun::star::uno::RuntimeException);
+
+private:
+ EventListenerVector mxEventListeners;
+ ::vos::OMutex maMutex;
+ ToolbarMenuEntry* mpParent;
+
+ /** Tell all listeners that the object is dying. This callback is
+ usually called from the WeakComponentImplHelper class.
+ */
+ virtual void SAL_CALL disposing (void);
+};
+
+// -----------------------------------------------------------------------------
+
+struct ToolbarMenu_Impl
+{
+ ToolbarMenu& mrMenu;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > mxFrame;
+ rtl::Reference< svt::FrameStatusListener > mxStatusListener;
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > mxServiceManager;
+ rtl::Reference< ToolbarMenuAcc > mxAccessible;
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > mxOldSelection;
+
+ ToolbarMenuEntryVector maEntryVector;
+
+ int mnCheckPos;
+ int mnImagePos;
+ int mnTextPos;
+
+ int mnHighlightedEntry;
+ int mnSelectedEntry;
+ int mnLastColumn;
+
+ Size maSize;
+
+ Link maSelectHdl;
+
+ ToolbarMenu_Impl( ToolbarMenu& rMenu, const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame );
+ ~ToolbarMenu_Impl();
+
+ void setAccessible( ToolbarMenuAcc* pAccessible );
+
+ void fireAccessibleEvent( short nEventId, const ::com::sun::star::uno::Any& rOldValue, const ::com::sun::star::uno::Any& rNewValue );
+ bool hasAccessibleListeners();
+
+ sal_Int32 getAccessibleChildCount() throw (::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > getAccessibleChild( sal_Int32 index ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > getAccessibleChild( Control* pControl, sal_Int32 childIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+
+ void selectAccessibleChild( sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ sal_Bool isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ void clearAccessibleSelection();
+
+ ToolbarMenuEntry* implGetEntry( int nEntry ) const;
+ void notifyHighlightedEntry();
+
+ void implHighlightControl( USHORT nCode, Control* pControl );
+};
+
+}
diff --git a/svtools/source/control/valueacc.cxx b/svtools/source/control/valueacc.cxx
index 6712e75aa9b4..66da5636d89c 100644
--- a/svtools/source/control/valueacc.cxx
+++ b/svtools/source/control/valueacc.cxx
@@ -976,10 +976,7 @@ sal_Int16 SAL_CALL ValueItemAcc::getAccessibleRole()
::rtl::OUString SAL_CALL ValueItemAcc::getAccessibleDescription()
throw (uno::RuntimeException)
{
- const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
- String aRet( RTL_CONSTASCII_USTRINGPARAM( "ValueSet item" ) );
-
- return aRet;
+ return ::rtl::OUString();
}
// -----------------------------------------------------------------------------
@@ -1239,7 +1236,7 @@ sal_Int32 SAL_CALL ValueItemAcc::getBackground( )
throw (uno::RuntimeException)
{
UINT32 nColor;
- if (mpParent->meType == VALUESETITEM_COLOR)
+ if (mpParent && mpParent->meType == VALUESETITEM_COLOR)
nColor = mpParent->maColor.GetColor();
else
nColor = Application::GetSettings().GetStyleSettings().GetWindowColor().GetColor();
diff --git a/svtools/source/control/valueimp.hxx b/svtools/source/control/valueimp.hxx
index f74cdf00a4db..abde4a015ab8 100644..100755
--- a/svtools/source/control/valueimp.hxx
+++ b/svtools/source/control/valueimp.hxx
@@ -111,6 +111,7 @@ struct ValueSet_Impl
{
::std::auto_ptr< ValueItemList > mpItemList;
bool mbIsTransientChildrenDisabled;
+ Link maHighlightHdl;
ValueSet_Impl() : mpItemList( ::std::auto_ptr< ValueItemList >( new ValueItemList() ) ),
mbIsTransientChildrenDisabled( false )
diff --git a/svtools/source/control/valueset.cxx b/svtools/source/control/valueset.cxx
index bb48c11c7c0b..62193eadf735 100644
--- a/svtools/source/control/valueset.cxx
+++ b/svtools/source/control/valueset.cxx
@@ -1418,7 +1418,7 @@ void ValueSet::KeyInput( const KeyEvent& rKEvt )
{
USHORT nLastItem = (USHORT)mpImpl->mpItemList->Count();
USHORT nItemPos = VALUESET_ITEM_NOTFOUND;
- USHORT nCurPos;
+ USHORT nCurPos = VALUESET_ITEM_NONEITEM;
USHORT nCalcPos;
if ( !nLastItem || !ImplGetFirstItem() )
@@ -1431,8 +1431,6 @@ void ValueSet::KeyInput( const KeyEvent& rKEvt )
if ( mnSelItemId )
nCurPos = GetItemPos( mnSelItemId );
- else
- nCurPos = VALUESET_ITEM_NONEITEM;
nCalcPos = nCurPos;
//switch off selection mode if key travelling is used
@@ -1528,30 +1526,20 @@ void ValueSet::KeyInput( const KeyEvent& rKEvt )
nCalcPos - ( nLineCount * mnCols ));
else
{
- if( (KEY_UP == rKEvt.GetKeyCode().GetCode() ) && (GetStyle() & WB_MENUSTYLEVALUESET) )
+ if ( mpNoneItem )
{
- Window* pParent = GetParent();
- pParent->GrabFocus();
- pParent->KeyInput( rKEvt );
- break;
+ mnCurCol = nCalcPos%mnCols;
+ nItemPos = VALUESET_ITEM_NONEITEM;
}
else
{
- if ( mpNoneItem )
- {
- mnCurCol = nCalcPos%mnCols;
- nItemPos = VALUESET_ITEM_NONEITEM;
- }
+ if ( nLastItem+1 <= mnCols )
+ nItemPos = nCalcPos;
else
{
- if ( nLastItem+1 <= mnCols )
- nItemPos = nCalcPos;
- else
- {
- nItemPos = ((((nLastItem+1)/mnCols)-1)*mnCols)+(nCalcPos%mnCols);
- if ( nItemPos+mnCols <= nLastItem )
- nItemPos = nItemPos + mnCols;
- }
+ nItemPos = ((((nLastItem+1)/mnCols)-1)*mnCols)+(nCalcPos%mnCols);
+ if ( nItemPos+mnCols <= nLastItem )
+ nItemPos = nItemPos + mnCols;
}
}
}
@@ -1580,6 +1568,7 @@ void ValueSet::KeyInput( const KeyEvent& rKEvt )
nCalcPos + ( nLineCount * mnCols ));
else
{
+#if 0
if( (KEY_DOWN == rKEvt.GetKeyCode().GetCode() ) && (GetStyle() & WB_MENUSTYLEVALUESET) )
{
Window* pParent = GetParent();
@@ -1588,6 +1577,7 @@ void ValueSet::KeyInput( const KeyEvent& rKEvt )
break;
}
else
+#endif
{
if ( mpNoneItem )
{
@@ -1620,7 +1610,6 @@ void ValueSet::KeyInput( const KeyEvent& rKEvt )
bDefault = TRUE;
break;
}
-
if(!bDefault)
EndSelection();
if ( nItemPos != VALUESET_ITEM_NOTFOUND )
@@ -1630,6 +1619,7 @@ void ValueSet::KeyInput( const KeyEvent& rKEvt )
nItemId = GetItemId( nItemPos );
else
nItemId = 0;
+
if ( nItemId != mnSelItemId )
{
SelectItem( nItemId );
@@ -2278,6 +2268,7 @@ void ValueSet::SelectItem( USHORT nItemId )
::com::sun::star::uno::Any aOldAny, aNewAny;
ImplFireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::SELECTION_CHANGED, aOldAny, aNewAny );
}
+ mpImpl->maHighlightHdl.Call(this);
}
}
@@ -2749,3 +2740,19 @@ bool ValueSet::IsRTLActive (void)
return Application::GetSettings().GetLayoutRTL() && IsRTLEnabled();
}
+// -----------------------------------------------------------------------
+
+void ValueSet::SetHighlightHdl( const Link& rLink )
+{
+ mpImpl->maHighlightHdl = rLink;
+}
+
+// -----------------------------------------------------------------------
+
+const Link& ValueSet::GetHighlightHdl() const
+{
+ return mpImpl->maHighlightHdl;
+}
+
+// -----------------------------------------------------------------------
+
diff --git a/svtools/source/dialogs/addresstemplate.cxx b/svtools/source/dialogs/addresstemplate.cxx
index 2849ddb71d10..9a66230f012c 100644
--- a/svtools/source/dialogs/addresstemplate.cxx
+++ b/svtools/source/dialogs/addresstemplate.cxx
@@ -36,7 +36,7 @@
#include "addresstemplate.hrc"
#endif
#ifndef _SVTOOLS_HRC
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#endif
#ifndef _SVT_HELPID_HRC
#include <svtools/helpid.hrc>
diff --git a/svtools/source/dialogs/addresstemplate.src b/svtools/source/dialogs/addresstemplate.src
index f4812f8b7566..0652dfb9d0f5 100644
--- a/svtools/source/dialogs/addresstemplate.src
+++ b/svtools/source/dialogs/addresstemplate.src
@@ -26,7 +26,7 @@
************************************************************************/
#ifndef _SVTOOLS_HRC
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#endif
#ifndef _SVT_ADDRESSTEMPLATE_HRC_
#include "addresstemplate.hrc"
diff --git a/svtools/source/dialogs/logindlg.cxx b/svtools/source/dialogs/logindlg.cxx
index c9edf632d2ec..036d5d71a4cf 100644
--- a/svtools/source/dialogs/logindlg.cxx
+++ b/svtools/source/dialogs/logindlg.cxx
@@ -35,7 +35,7 @@
#include "logindlg.hrc"
#endif
#ifndef _SVTOOLS_HRC
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#endif
#include <svtools/svtdata.hxx>
diff --git a/svtools/source/dialogs/logindlg.src b/svtools/source/dialogs/logindlg.src
index 338b608ab0e4..f6e3565d8cd9 100644
--- a/svtools/source/dialogs/logindlg.src
+++ b/svtools/source/dialogs/logindlg.src
@@ -26,7 +26,7 @@
************************************************************************/
#ifndef _SVTOOLS_HRC
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#endif
#ifndef _SVTOOLS_LOGINDLG_HRC_
diff --git a/svtools/source/dialogs/printdlg.hrc b/svtools/source/dialogs/printdlg.hrc
index ef780acbb47c..83b7b0b28c82 100644
--- a/svtools/source/dialogs/printdlg.hrc
+++ b/svtools/source/dialogs/printdlg.hrc
@@ -25,7 +25,7 @@
*
************************************************************************/
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#define FL_PRINTER 1
#define LB_NAMES 2
diff --git a/svtools/source/dialogs/prnsetup.hrc b/svtools/source/dialogs/prnsetup.hrc
index 7d10c4652d45..4a06c3cf0e63 100644
--- a/svtools/source/dialogs/prnsetup.hrc
+++ b/svtools/source/dialogs/prnsetup.hrc
@@ -24,7 +24,7 @@
* for a copy of the LGPLv3 License.
*
************************************************************************/
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#define FL_PRINTER 1
#define LB_NAMES 2
diff --git a/svtools/source/dialogs/roadmapwizard.cxx b/svtools/source/dialogs/roadmapwizard.cxx
index 2c71e60e8101..9a03a9b16c2d 100644
--- a/svtools/source/dialogs/roadmapwizard.cxx
+++ b/svtools/source/dialogs/roadmapwizard.cxx
@@ -29,7 +29,7 @@
#include "precompiled_svtools.hxx"
#include <svtools/roadmapwizard.hxx>
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#include <svtools/svtdata.hxx>
#include "roadmap.hxx"
#include <tools/debug.hxx>
diff --git a/svtools/source/dialogs/wizardmachine.cxx b/svtools/source/dialogs/wizardmachine.cxx
index 6a09f85036fd..3aaf279889d8 100644
--- a/svtools/source/dialogs/wizardmachine.cxx
+++ b/svtools/source/dialogs/wizardmachine.cxx
@@ -33,7 +33,7 @@
#include <vcl/msgbox.hxx>
#include <svtools/svtdata.hxx>
#ifndef _SVTOOLS_HRC
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#endif
//.........................................................................
diff --git a/svtools/source/dialogs/wizardmachine.src b/svtools/source/dialogs/wizardmachine.src
index c3570335773f..9c82ea30071f 100644
--- a/svtools/source/dialogs/wizardmachine.src
+++ b/svtools/source/dialogs/wizardmachine.src
@@ -26,7 +26,7 @@
************************************************************************/
#ifndef _SVTOOLS_HRC
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#endif
String STR_WIZDLG_FINISH
diff --git a/svtools/source/filter.vcl/filter/dlgejpg.hrc b/svtools/source/filter.vcl/filter/dlgejpg.hrc
index 523a1d9553f1..90a3c1d162be 100644
--- a/svtools/source/filter.vcl/filter/dlgejpg.hrc
+++ b/svtools/source/filter.vcl/filter/dlgejpg.hrc
@@ -24,7 +24,7 @@
* for a copy of the LGPLv3 License.
*
************************************************************************/
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#define BTN_OK 1
#define BTN_CANCEL 1
diff --git a/svtools/source/filter.vcl/filter/dlgepng.hrc b/svtools/source/filter.vcl/filter/dlgepng.hrc
index 4a05771534ab..b3ffaab3ab1e 100644
--- a/svtools/source/filter.vcl/filter/dlgepng.hrc
+++ b/svtools/source/filter.vcl/filter/dlgepng.hrc
@@ -24,7 +24,7 @@
* for a copy of the LGPLv3 License.
*
************************************************************************/
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#define BTN_OK 1
#define BTN_CANCEL 1
diff --git a/svtools/source/filter.vcl/filter/dlgexpor.hrc b/svtools/source/filter.vcl/filter/dlgexpor.hrc
index 2e5377ce4fcb..69870c9b00b0 100644
--- a/svtools/source/filter.vcl/filter/dlgexpor.hrc
+++ b/svtools/source/filter.vcl/filter/dlgexpor.hrc
@@ -24,7 +24,7 @@
* for a copy of the LGPLv3 License.
*
************************************************************************/
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#define BTN_OK_PIX 1
#define BTN_CANCEL_PIX 1
diff --git a/svtools/source/filter.vcl/filter/strings.hrc b/svtools/source/filter.vcl/filter/strings.hrc
index ac162bff09f4..0eea67fb2338 100644
--- a/svtools/source/filter.vcl/filter/strings.hrc
+++ b/svtools/source/filter.vcl/filter/strings.hrc
@@ -24,4 +24,4 @@
* for a copy of the LGPLv3 License.
*
************************************************************************/
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
diff --git a/svtools/source/inc/iodlg.hrc b/svtools/source/inc/iodlg.hrc
index 918e47f849b4..e78e3fb687fe 100644
--- a/svtools/source/inc/iodlg.hrc
+++ b/svtools/source/inc/iodlg.hrc
@@ -29,7 +29,7 @@
#define _SVTOOLS_IODLGIMPL_HRC
#ifndef _SVTOOLS_HRC
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#endif
// ModalDialog DLG_SVT_EXPLORERFILE
diff --git a/svtools/source/java/javaerror.src b/svtools/source/java/javaerror.src
index e16992a3473d..d5990c05a663 100644
--- a/svtools/source/java/javaerror.src
+++ b/svtools/source/java/javaerror.src
@@ -25,7 +25,7 @@
*
************************************************************************/
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
WarningBox WARNINGBOX_JAVANOTFOUND
{
diff --git a/svtools/source/java/javainteractionhandler.cxx b/svtools/source/java/javainteractionhandler.cxx
index 3dde9c33cd48..ec34ed07f25d 100644
--- a/svtools/source/java/javainteractionhandler.cxx
+++ b/svtools/source/java/javainteractionhandler.cxx
@@ -30,7 +30,7 @@
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#include <tools/resid.hxx>
#include <com/sun/star/task/XInteractionContinuation.hpp>
#include <com/sun/star/task/XInteractionAbort.hpp>
diff --git a/svtools/source/java/patchjavaerror.src b/svtools/source/java/patchjavaerror.src
index e16992a3473d..d5990c05a663 100644
--- a/svtools/source/java/patchjavaerror.src
+++ b/svtools/source/java/patchjavaerror.src
@@ -25,7 +25,7 @@
*
************************************************************************/
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
WarningBox WARNINGBOX_JAVANOTFOUND
{
diff --git a/svtools/source/misc/ehdl.cxx b/svtools/source/misc/ehdl.cxx
index cf476098056b..bf9e87d33a74 100644
--- a/svtools/source/misc/ehdl.cxx
+++ b/svtools/source/misc/ehdl.cxx
@@ -42,7 +42,7 @@
#include <svtools/ehdl.hxx>
#include <svtools/svtdata.hxx>
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#include "sfxecode.hxx"
//=========================================================================
diff --git a/svtools/source/misc/ehdl.src b/svtools/source/misc/ehdl.src
index 55ab99b93bdf..436e06b7f3c5 100644
--- a/svtools/source/misc/ehdl.src
+++ b/svtools/source/misc/ehdl.src
@@ -26,7 +26,7 @@
************************************************************************/
#define __RSC
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#include "sfxecode.hxx"
// pragma ----------------------------------------------------------------
diff --git a/svtools/source/misc/embedhlp.cxx b/svtools/source/misc/embedhlp.cxx
index f606e1e2e4b1..3aa0016c225e 100644
--- a/svtools/source/misc/embedhlp.cxx
+++ b/svtools/source/misc/embedhlp.cxx
@@ -30,7 +30,7 @@
#include <svtools/embedhlp.hxx>
#include <svtools/filter.hxx>
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#include <svtools/svtdata.hxx>
#include <comphelper/embeddedobjectcontainer.hxx>
diff --git a/svtools/source/misc/errtxt.src b/svtools/source/misc/errtxt.src
index 4e9a316308e0..6c1a90ae6412 100644
--- a/svtools/source/misc/errtxt.src
+++ b/svtools/source/misc/errtxt.src
@@ -26,7 +26,7 @@
************************************************************************/
#define __RSC
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#include "sfxecode.hxx"
// pragma ----------------------------------------------------------------
Resource RID_ERRCTX
diff --git a/svtools/source/misc/helpagent.src b/svtools/source/misc/helpagent.src
index c649c1f17a40..1f2eaaa291a3 100644
--- a/svtools/source/misc/helpagent.src
+++ b/svtools/source/misc/helpagent.src
@@ -26,7 +26,7 @@
************************************************************************/
#ifndef _SVTOOLS_HRC
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#endif
Bitmap BMP_HELP_AGENT_IMAGE
diff --git a/svtools/source/misc/helpagentwindow.cxx b/svtools/source/misc/helpagentwindow.cxx
index 55800a213a2e..1d407bbdb611 100644
--- a/svtools/source/misc/helpagentwindow.cxx
+++ b/svtools/source/misc/helpagentwindow.cxx
@@ -36,7 +36,7 @@
#include <svtools/svtdata.hxx>
#ifndef _SVTOOLS_HRC
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#endif
#ifndef _SVT_HELPID_HRC
#include <svtools/helpid.hrc>
diff --git a/svtools/source/misc/imagemgr.cxx b/svtools/source/misc/imagemgr.cxx
index 391ad02e6aa1..c02ebc4477c6 100644
--- a/svtools/source/misc/imagemgr.cxx
+++ b/svtools/source/misc/imagemgr.cxx
@@ -52,7 +52,7 @@
#include <rtl/logfile.hxx>
#include <unotools/configmgr.hxx>
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#include "imagemgr.hrc"
#include <svtools/svtdata.hxx>
#include <vos/mutex.hxx>
diff --git a/svtools/source/misc/imagemgr.src b/svtools/source/misc/imagemgr.src
index 0664cdc6bc87..cdc9f8da1c87 100644
--- a/svtools/source/misc/imagemgr.src
+++ b/svtools/source/misc/imagemgr.src
@@ -26,7 +26,7 @@
************************************************************************/
// includes ******************************************************************
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#include "imagemgr.hrc"
// images ********************************************************************
diff --git a/svtools/source/misc/langtab.cxx b/svtools/source/misc/langtab.cxx
index b656dbf501c4..d1ff94572a99 100755..100644
--- a/svtools/source/misc/langtab.cxx
+++ b/svtools/source/misc/langtab.cxx
@@ -39,7 +39,7 @@
#include <i18npool/lang.h>
#include <i18npool/mslangid.hxx>
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#include <svtools/svtdata.hxx>
#include <svtools/langtab.hxx>
#include <unotools/syslocale.hxx>
diff --git a/svtools/source/misc/langtab.src b/svtools/source/misc/langtab.src
index 39f9362e3940..0b83cb535ec4 100644
--- a/svtools/source/misc/langtab.src
+++ b/svtools/source/misc/langtab.src
@@ -26,7 +26,7 @@
************************************************************************/
// include ---------------------------------------------------------------
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#define RSC_RESOURCE_USAGE 1
#include <i18npool/lang.h>
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/productregistration/productregistration.cxx b/svtools/source/productregistration/productregistration.cxx
index 4a5db9cf47c4..39629f5c3f77 100644
--- a/svtools/source/productregistration/productregistration.cxx
+++ b/svtools/source/productregistration/productregistration.cxx
@@ -32,7 +32,7 @@
#include "unotools/regoptions.hxx"
#include "registrationdlg.hxx"
#ifndef _SVTOOLS_HRC
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#endif
#include "cppuhelper/factory.hxx"
#include <cppuhelper/implbase1.hxx>
diff --git a/svtools/source/productregistration/registrationdlg.cxx b/svtools/source/productregistration/registrationdlg.cxx
index 93b7e5c88462..460cedb060d1 100644
--- a/svtools/source/productregistration/registrationdlg.cxx
+++ b/svtools/source/productregistration/registrationdlg.cxx
@@ -32,7 +32,7 @@
#if 0 /* @@@ */
#include <svtools/svtdata.hxx>
#ifndef _SVTOOLS_HRC
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#endif
#endif /* @@@ */
diff --git a/svtools/source/productregistration/registrationdlg.src b/svtools/source/productregistration/registrationdlg.src
index e0598ab05e60..c4cdcbcbe3ec 100644
--- a/svtools/source/productregistration/registrationdlg.src
+++ b/svtools/source/productregistration/registrationdlg.src
@@ -29,7 +29,7 @@
#include "registrationdlg.hrc"
#endif
#ifndef _SVTOOLS_HRC
-#include <svl/svtools.hrc>
+#include <svtools/svtools.hrc>
#endif
#ifndef _SVT_HELPID_HRC
#include <svtools/helpid.hrc>
diff --git a/svtools/source/table/tablecontrol.cxx b/svtools/source/table/tablecontrol.cxx
index 418348c81b7d..8c95fab6120b 100644
--- a/svtools/source/table/tablecontrol.cxx
+++ b/svtools/source/table/tablecontrol.cxx
@@ -401,7 +401,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/drawerlayouter.cxx b/svtools/source/toolpanel/drawerlayouter.cxx
new file mode 100644
index 000000000000..040f33045fff
--- /dev/null
+++ b/svtools/source/toolpanel/drawerlayouter.cxx
@@ -0,0 +1,305 @@
+/*************************************************************************
+ * 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/drawerlayouter.hxx"
+#include "toolpaneldrawer.hxx"
+
+#include <com/sun/star/accessibility/XAccessible.hpp>
+
+#include <comphelper/accimplaccess.hxx>
+#include <tools/diagnose_ex.h>
+
+//......................................................................................................................
+namespace svt
+{
+//......................................................................................................................
+
+ /** === begin UNO using === **/
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::accessibility::XAccessible;
+ /** === end UNO using === **/
+
+ //==================================================================================================================
+ //= DrawerDeckLayouter
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ DrawerDeckLayouter::DrawerDeckLayouter( ::Window& i_rParentWindow, IToolPanelDeck& i_rPanels )
+ :m_rParentWindow( i_rParentWindow )
+ ,m_rPanelDeck( i_rPanels )
+ ,m_aDrawers()
+ ,m_aLastKnownActivePanel()
+ {
+ m_rPanelDeck.AddListener( *this );
+
+ // simulate PanelInserted events for the panels which are already there
+ for ( size_t i=0; i<m_rPanelDeck.GetPanelCount(); ++i )
+ PanelInserted( m_rPanelDeck.GetPanel( i ), i );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ DrawerDeckLayouter::~DrawerDeckLayouter()
+ {
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ IMPLEMENT_IREFERENCE( DrawerDeckLayouter )
+
+ //------------------------------------------------------------------------------------------------------------------
+ Rectangle DrawerDeckLayouter::Layout( const Rectangle& i_rDeckPlayground )
+ {
+ const size_t nPanelCount( m_rPanelDeck.GetPanelCount() );
+ if ( nPanelCount == 0 )
+ return i_rDeckPlayground;
+
+ const int nWidth( i_rDeckPlayground.GetWidth() );
+ ::boost::optional< size_t > aActivePanel( m_rPanelDeck.GetActivePanel() );
+ if ( !aActivePanel )
+ aActivePanel = m_aLastKnownActivePanel;
+
+ // arrange the title bars which are *above* the active panel (or *all* if there is no active panel), plus
+ // the title bar of the active panel itself
+ Point aUpperDrawerPos( i_rDeckPlayground.TopLeft() );
+ const size_t nUpperBound = !!aActivePanel ? *aActivePanel : nPanelCount - 1;
+ for ( size_t i=0; i<=nUpperBound; ++i )
+ {
+ sal_uInt32 nDrawerHeight = m_aDrawers[i]->GetPreferredHeightPixel();
+ m_aDrawers[i]->SetPosSizePixel(
+ aUpperDrawerPos, Size( nWidth, nDrawerHeight ) );
+ aUpperDrawerPos.Move( 0, nDrawerHeight );
+ }
+
+ // arrange title bars which are below the active panel (or *none* if there is no active panel)
+ Point aLowerDrawerPos( i_rDeckPlayground.BottomLeft() );
+ for ( size_t j = nPanelCount - 1; j > nUpperBound; --j )
+ {
+ sal_uInt32 nDrawerHeight = m_aDrawers[j]->GetPreferredHeightPixel();
+ m_aDrawers[j]->SetPosSizePixel(
+ Point( aLowerDrawerPos.X(), aLowerDrawerPos.Y() - nDrawerHeight + 1 ),
+ Size( nWidth, nDrawerHeight )
+ );
+ aLowerDrawerPos.Move( 0, -nDrawerHeight );
+ }
+
+ // fincally calculate the rectangle for the active panel
+ return Rectangle(
+ aUpperDrawerPos,
+ Size( nWidth, aLowerDrawerPos.Y() - aUpperDrawerPos.Y() + 1 )
+ );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void DrawerDeckLayouter::Destroy()
+ {
+ while ( !m_aDrawers.empty() )
+ impl_removeDrawer( 0 );
+ m_rPanelDeck.RemoveListener( *this );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void DrawerDeckLayouter::SetFocusToPanelSelector()
+ {
+ const size_t nPanelCount( m_rPanelDeck.GetPanelCount() );
+ if ( !nPanelCount )
+ // nothing to focus
+ return;
+ ::boost::optional< size_t > aActivePanel( m_rPanelDeck.GetActivePanel() );
+ if ( !aActivePanel )
+ aActivePanel = 0;
+ ENSURE_OR_RETURN_VOID( *aActivePanel < m_aDrawers.size(), "DrawerDeckLayouter::SetFocusToPanelSelector: invalid active panel, or inconsistent drawers!" );
+ m_aDrawers[ *aActivePanel ]->GrabFocus();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ size_t DrawerDeckLayouter::GetAccessibleChildCount() const
+ {
+ return m_aDrawers.size();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Reference< XAccessible > DrawerDeckLayouter::GetAccessibleChild( const size_t i_nChildIndex, const Reference< XAccessible >& i_rParentAccessible )
+ {
+ ENSURE_OR_RETURN( i_nChildIndex < m_aDrawers.size(), "illegal index", NULL );
+
+ const PToolPanelDrawer pDrawer( m_aDrawers[ i_nChildIndex ] );
+
+ Reference< XAccessible > xItemAccessible = pDrawer->GetAccessible( FALSE );
+ if ( !xItemAccessible.is() )
+ {
+ xItemAccessible = pDrawer->GetAccessible( TRUE );
+ ENSURE_OR_RETURN( xItemAccessible.is(), "illegal accessible provided by the drawer implementation!", NULL );
+ OSL_VERIFY( ::comphelper::OAccessibleImplementationAccess::setAccessibleParent( xItemAccessible->getAccessibleContext(),
+ i_rParentAccessible ) );
+ }
+
+ return xItemAccessible;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void DrawerDeckLayouter::PanelInserted( const PToolPanel& i_pPanel, const size_t i_nPosition )
+ {
+ OSL_PRECOND( i_nPosition <= m_aDrawers.size(), "DrawerDeckLayouter::PanelInserted: inconsistency!" );
+
+ PToolPanelDrawer pDrawer( new ToolPanelDrawer( m_rParentWindow, i_pPanel->GetDisplayName() ) );
+ pDrawer->SetSmartHelpId( i_pPanel->GetHelpID() );
+ // proper Z-Order
+ if ( i_nPosition == 0 )
+ {
+ pDrawer->SetZOrder( NULL, WINDOW_ZORDER_FIRST );
+ }
+ else
+ {
+ const PToolPanelDrawer pFirstDrawer( m_aDrawers[ i_nPosition - 1 ] );
+ pDrawer->SetZOrder( pFirstDrawer.get(), WINDOW_ZORDER_BEHIND );
+ }
+
+ pDrawer->Show();
+ pDrawer->AddEventListener( LINK( this, DrawerDeckLayouter, OnWindowEvent ) );
+ m_aDrawers.insert( m_aDrawers.begin() + i_nPosition, pDrawer );
+ impl_triggerRearrange();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void DrawerDeckLayouter::PanelRemoved( const size_t i_nPosition )
+ {
+ impl_removeDrawer( i_nPosition );
+ impl_triggerRearrange();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void DrawerDeckLayouter::impl_triggerRearrange() const
+ {
+ // this is somewhat hacky, it assumes that the parent of our panels is a tool panel deck, which, in its
+ // Resize implementation, rearrances all elements.
+ m_rParentWindow.Resize();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void DrawerDeckLayouter::ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive )
+ {
+ if ( !!i_rOldActive )
+ {
+ OSL_ENSURE( *i_rOldActive < m_aDrawers.size(), "DrawerDeckLayouter::ActivePanelChanged: illegal old index!" );
+ m_aDrawers[ *i_rOldActive ]->SetExpanded( false );
+ }
+
+ if ( !!i_rNewActive )
+ {
+ OSL_ENSURE( *i_rNewActive < m_aDrawers.size(), "DrawerDeckLayouter::ActivePanelChanged: illegal new index!" );
+ m_aDrawers[ *i_rNewActive ]->SetExpanded( true );
+ }
+
+ impl_triggerRearrange();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void DrawerDeckLayouter::LayouterChanged( const PDeckLayouter& i_rNewLayouter )
+ {
+ // not interested in
+ (void)i_rNewLayouter;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ size_t DrawerDeckLayouter::impl_getPanelPositionFromWindow( const Window* i_pDrawerWindow ) const
+ {
+ for ( ::std::vector< PToolPanelDrawer >::const_iterator drawerPos = m_aDrawers.begin();
+ drawerPos != m_aDrawers.end();
+ ++drawerPos
+ )
+ {
+ if ( drawerPos->get() == i_pDrawerWindow )
+ return drawerPos - m_aDrawers.begin();
+ }
+ return m_aDrawers.size();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void DrawerDeckLayouter::impl_removeDrawer( const size_t i_nPosition )
+ {
+ OSL_PRECOND( i_nPosition < m_aDrawers.size(), "DrawerDeckLayouter::impl_removeDrawer: invalid panel position!" );
+ m_aDrawers[ i_nPosition ]->RemoveEventListener( LINK( this, DrawerDeckLayouter, OnWindowEvent ) );
+ OSL_ENSURE( m_aDrawers[ i_nPosition ].unique(), "DrawerDeckLayouter::impl_removeDrawer: somebody else is still holding a reference!" );
+ m_aDrawers.erase( m_aDrawers.begin() + i_nPosition );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ IMPL_LINK( DrawerDeckLayouter, OnWindowEvent, VclSimpleEvent*, i_pEvent )
+ {
+ const VclWindowEvent* pWindowEvent = PTR_CAST( VclWindowEvent, i_pEvent );
+ ENSURE_OR_RETURN( pWindowEvent, "no WindowEvent", 0L );
+
+ bool bActivatePanel = false;
+ switch ( pWindowEvent->GetId() )
+ {
+ case VCLEVENT_WINDOW_MOUSEBUTTONUP:
+ {
+ const MouseEvent* pMouseEvent = static_cast< const MouseEvent* >( pWindowEvent->GetData() );
+ ENSURE_OR_RETURN( pMouseEvent, "no mouse event with MouseButtonUp", 0L );
+ if ( pMouseEvent->GetButtons() == MOUSE_LEFT )
+ {
+ bActivatePanel = true;
+ }
+ }
+ break;
+ case VCLEVENT_WINDOW_KEYINPUT:
+ {
+ const KeyEvent* pKeyEvent = static_cast< const KeyEvent* >( pWindowEvent->GetData() );
+ ENSURE_OR_RETURN( pKeyEvent, "no key event with KeyInput", 0L );
+ const KeyCode& rKeyCode( pKeyEvent->GetKeyCode() );
+ if ( ( rKeyCode.GetModifier() == 0 ) && ( rKeyCode.GetCode() == KEY_RETURN ) )
+ {
+ bActivatePanel = true;
+ }
+ }
+ break;
+ }
+ if ( bActivatePanel )
+ {
+ const size_t nPanelPos = impl_getPanelPositionFromWindow( pWindowEvent->GetWindow() );
+ if ( nPanelPos != m_rPanelDeck.GetActivePanel() )
+ {
+ m_rPanelDeck.ActivatePanel( nPanelPos );
+ }
+ else
+ {
+ PToolPanel pPanel( m_rPanelDeck.GetPanel( nPanelPos ) );
+ pPanel->GrabFocus();
+ }
+ return 1L;
+ }
+ return 0L;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void DrawerDeckLayouter::Dying()
+ {
+ Destroy();
+ }
+
+//......................................................................................................................
+} // namespace svt
+//......................................................................................................................
diff --git a/svtools/source/toolpanel/dummypanel.cxx b/svtools/source/toolpanel/dummypanel.cxx
new file mode 100644
index 000000000000..20f140a6e610
--- /dev/null
+++ b/svtools/source/toolpanel/dummypanel.cxx
@@ -0,0 +1,107 @@
+/*************************************************************************
+ * 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();
+ }
+
+ //--------------------------------------------------------------------
+ SmartId DummyPanel::GetHelpID() const
+ {
+ return SmartId();
+ }
+
+ //--------------------------------------------------------------------
+ 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..adb98e52077e
--- /dev/null
+++ b/svtools/source/toolpanel/dummypanel.hxx
@@ -0,0 +1,70 @@
+/*************************************************************************
+ * 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 SmartId GetHelpID() 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..58282056f529
--- /dev/null
+++ b/svtools/source/toolpanel/makefile.mk
@@ -0,0 +1,68 @@
+#*************************************************************************
+#
+# 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)$/drawerlayouter.obj \
+ $(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)$/toolpaneldrawer.obj \
+ $(SLO)$/toolpaneldrawerpeer.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..38aee00c8f55
--- /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 "svtools/svtools.hrc"
+
+#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 <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_TOOL_PANEL_BUTTON_FWD ) ) );
+ 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_TOOL_PANEL_BUTTON_BACK ) ) );
+ 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..f7b999494563
--- /dev/null
+++ b/svtools/source/toolpanel/toolpanel.cxx
@@ -0,0 +1,54 @@
+/*************************************************************************
+ * 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/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..5908a8fbcf98 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,34 @@
*
************************************************************************/
-#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)
-
-
-#endif
-
+#include "svtools/svtools.hrc"
+
+String STR_SVT_TOOL_PANEL_BUTTON_FWD
+{
+ Text [ en-US ] = "Tab Panel Scroll Button, backward";
+};
+
+String STR_SVT_TOOL_PANEL_BUTTON_BACK
+{
+ Text [ en-US ] = "Tab Panel Scroll Button, forward";
+};
+
+Image IMG_TRIANGLE_RIGHT
+{
+ ImageBitmap = Bitmap { File = "triangle_right.png"; };
+};
+
+Image IMG_TRIANGLE_RIGHT_HC
+{
+ ImageBitmap = Bitmap { File = "triangle_right_hc.png"; };
+};
+
+Image IMG_TRIANGLE_DOWN
+{
+ ImageBitmap = Bitmap { File = "triangle_down.png"; };
+};
+
+Image IMG_TRIANGLE_DOWN_HC
+{
+ ImageBitmap = Bitmap { File = "plus.png"; } ;
+};
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..e157090bbf0e
--- /dev/null
+++ b/svtools/source/toolpanel/toolpaneldeck.cxx
@@ -0,0 +1,560 @@
+/*************************************************************************
+ * 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"
+#include "svtools/toolpanel/drawerlayouter.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, WB_DIALOGCONTROL | WB_CHILDDLGCTRL )
+ ,m_aPanels()
+ ,m_pDummyPanel( new DummyPanel )
+ ,m_pLayouter()
+ ,m_bInDtor( false )
+ ,m_pAccessibleParent( NULL )
+ {
+ m_aPanels.AddListener( *this );
+ m_aPanelAnchor.Show();
+ m_aPanelAnchor.SetAccessibleRole( AccessibleRole::PANEL );
+ }
+
+ ~ToolPanelDeck_Impl()
+ {
+ m_bInDtor = true;
+ }
+
+ PDeckLayouter GetLayouter() const { return m_pLayouter; }
+ void SetLayouter( const PDeckLayouter& i_pNewLayouter );
+
+ Window& GetPanelWindowAnchor() { return m_aPanelAnchor; }
+ const Window& GetPanelWindowAnchor() const { return m_aPanelAnchor; }
+
+ bool IsDead() const { return m_bInDtor; }
+
+ /// 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 );
+
+ bool FocusActivePanel();
+
+ void SetAccessibleParentWindow( Window* i_pAccessibleParent );
+ Window* GetAccessibleParentWindow() const { return m_pAccessibleParent; }
+
+ 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;
+ bool m_bInDtor;
+ 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 );
+ }
+ }
+
+ //--------------------------------------------------------------------
+ bool ToolPanelDeck_Impl::FocusActivePanel()
+ {
+ ::boost::optional< size_t > aActivePanel( m_aPanels.GetActivePanel() );
+ if ( !aActivePanel )
+ return false;
+
+ PToolPanel pActivePanel( m_aPanels.GetPanel( *aActivePanel ) );
+ pActivePanel->GrabFocus();
+ return true;
+ }
+
+ //--------------------------------------------------------------------
+ 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 ) ) );
+ SetLayouter( PDeckLayouter( new DrawerDeckLayouter( *this, *this ) ) );
+ }
+
+ //--------------------------------------------------------------------
+ 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();
+ }
+
+ //--------------------------------------------------------------------
+ const Window& ToolPanelDeck::GetPanelWindowAnchor() const
+ {
+ 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();
+ if ( m_pImpl->IsDead() )
+ return;
+ if ( !m_pImpl->FocusActivePanel() )
+ {
+ PDeckLayouter pLayouter( GetLayouter() );
+ ENSURE_OR_RETURN_VOID( pLayouter.get(), "ToolPanelDeck::GetFocus: no layouter?!" );
+ pLayouter->SetFocusToPanelSelector();
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void ToolPanelDeck::SetAccessibleParentWindow( Window* i_pAccessibleParent )
+ {
+ m_pImpl->SetAccessibleParentWindow( i_pAccessibleParent );
+ }
+
+ //--------------------------------------------------------------------
+ Window* ToolPanelDeck::GetAccessibleParentWindow() const
+ {
+ Window* pAccessibleParent( m_pImpl->GetAccessibleParentWindow() );
+ if ( !pAccessibleParent )
+ pAccessibleParent = Window::GetAccessibleParentWindow();
+ return pAccessibleParent;
+ }
+
+ //--------------------------------------------------------------------
+ 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/toolpanel/toolpaneldrawer.cxx b/svtools/source/toolpanel/toolpaneldrawer.cxx
new file mode 100644
index 000000000000..851556bc7874
--- /dev/null
+++ b/svtools/source/toolpanel/toolpaneldrawer.cxx
@@ -0,0 +1,373 @@
+/*************************************************************************
+ * 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 "toolpaneldrawer.hxx"
+#include "toolpaneldrawerpeer.hxx"
+#include "svtools/svtdata.hxx"
+#include "svtools/svtools.hrc"
+
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+
+#include <vcl/lineinfo.hxx>
+#include <vcl/image.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/vclevent.hxx>
+
+//......................................................................................................................
+namespace svt
+{
+//......................................................................................................................
+
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::awt::XWindowPeer;
+ namespace AccessibleRole = ::com::sun::star::accessibility::AccessibleRole;
+
+ static const int s_nIndentationWidth = 16;
+
+ //==================================================================================================================
+ //= DrawerVisualization
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ DrawerVisualization::DrawerVisualization( ToolPanelDrawer& i_rParent )
+ :Window( &i_rParent )
+ ,m_rDrawer( i_rParent )
+ {
+ SetMouseTransparent( TRUE );
+ Show();
+ SetAccessibleRole( AccessibleRole::LABEL );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ DrawerVisualization::~DrawerVisualization()
+ {
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void DrawerVisualization::Paint( const Rectangle& i_rBoundingBox )
+ {
+ Window::Paint( i_rBoundingBox );
+ m_rDrawer.Paint();
+ }
+
+ //==================================================================================================================
+ //= ToolPanelDrawer
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ ToolPanelDrawer::ToolPanelDrawer( Window& i_rParent, const ::rtl::OUString& i_rTitle )
+ :Window( &i_rParent, WB_TABSTOP )
+ ,m_pPaintDevice( new VirtualDevice( *this ) )
+ ,m_aVisualization( *this )
+ ,m_bFocused( false )
+ ,m_bExpanded( false )
+ {
+ EnableMapMode( FALSE );
+ SetBackground( Wallpaper() );
+ SetPointer( POINTER_REFHAND );
+
+ SetAccessibleRole( AccessibleRole::LIST_ITEM );
+
+ SetText( i_rTitle );
+ SetAccessibleName( i_rTitle );
+ SetAccessibleDescription( i_rTitle );
+
+ m_aVisualization.SetAccessibleName( i_rTitle );
+ m_aVisualization.SetAccessibleDescription( i_rTitle );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ToolPanelDrawer::~ToolPanelDrawer()
+ {
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ long ToolPanelDrawer::GetPreferredHeightPixel() const
+ {
+ Rectangle aTitleBarBox( impl_calcTitleBarBox( impl_calcTextBoundingBox() ) );
+ return aTitleBarBox.GetHeight();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void ToolPanelDrawer::Paint()
+ {
+ m_pPaintDevice->SetMapMode( GetMapMode() );
+ m_pPaintDevice->SetOutputSize( GetOutputSizePixel() );
+ m_pPaintDevice->SetSettings( GetSettings() );
+ m_pPaintDevice->SetDrawMode( GetDrawMode() );
+
+ const Rectangle aTextBox( impl_calcTextBoundingBox() );
+ impl_paintBackground( impl_calcTitleBarBox( aTextBox ) );
+
+ Rectangle aFocusBox( impl_paintExpansionIndicator( aTextBox ) );
+
+ m_pPaintDevice->DrawText( aTextBox, GetText(), impl_getTextStyle() );
+
+ aFocusBox.Union( aTextBox );
+ aFocusBox.Left() += 2;
+ impl_paintFocusIndicator( aFocusBox );
+
+ m_aVisualization.DrawOutDev(
+ Point(), GetOutputSizePixel(),
+ Point(), GetOutputSizePixel(),
+ *m_pPaintDevice
+ );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Rectangle ToolPanelDrawer::impl_paintExpansionIndicator( const Rectangle& i_rTextBox )
+ {
+ Rectangle aExpansionIndicatorArea;
+
+ Image aImage( impl_getExpansionIndicator() );
+ const int nHeight( aImage.GetSizePixel().Height() );
+ if ( nHeight > 0 )
+ {
+ Point aPosition(
+ 0,
+ i_rTextBox.Top() + ( GetTextHeight() - nHeight ) / 2
+ );
+ m_pPaintDevice->DrawImage( aPosition, aImage );
+
+ aExpansionIndicatorArea = Rectangle( aPosition, aImage.GetSizePixel() );
+ }
+
+ return aExpansionIndicatorArea;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Image ToolPanelDrawer::impl_getExpansionIndicator() const
+ {
+ const bool bHighContrastMode( GetSettings().GetStyleSettings().GetHighContrastMode() != 0 );
+ USHORT nResourceId = 0;
+ if ( m_bExpanded )
+ if ( bHighContrastMode )
+ nResourceId = IMG_TRIANGLE_DOWN_HC;
+ else
+ nResourceId = IMG_TRIANGLE_DOWN;
+ else
+ if ( bHighContrastMode )
+ nResourceId = IMG_TRIANGLE_RIGHT_HC;
+ else
+ nResourceId = IMG_TRIANGLE_RIGHT;
+ return Image( SvtResId( nResourceId ) );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ USHORT ToolPanelDrawer::impl_getTextStyle() const
+ {
+ const USHORT nBasicStyle = TEXT_DRAW_LEFT
+ | TEXT_DRAW_TOP
+ | TEXT_DRAW_WORDBREAK;
+
+ if ( IsEnabled() )
+ return nBasicStyle;
+
+ return nBasicStyle | TEXT_DRAW_DISABLE;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void ToolPanelDrawer::impl_paintBackground( const Rectangle& i_rTitleBarBox )
+ {
+ m_pPaintDevice->SetFillColor( GetSettings().GetStyleSettings().GetDialogColor() );
+ m_pPaintDevice->DrawRect( i_rTitleBarBox );
+
+ m_pPaintDevice->SetFillColor();
+ m_pPaintDevice->SetLineColor( GetSettings().GetStyleSettings().GetLightColor() );
+ m_pPaintDevice->DrawLine( i_rTitleBarBox.TopLeft(), i_rTitleBarBox.TopRight() );
+ m_pPaintDevice->DrawLine( i_rTitleBarBox.TopLeft(), i_rTitleBarBox.BottomLeft() );
+
+ m_pPaintDevice->SetLineColor( GetSettings().GetStyleSettings().GetShadowColor() );
+ m_pPaintDevice->DrawLine( i_rTitleBarBox.BottomLeft(), i_rTitleBarBox.BottomRight() );
+ m_pPaintDevice->DrawLine( i_rTitleBarBox.TopRight(), i_rTitleBarBox.BottomRight() );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void ToolPanelDrawer::impl_paintFocusIndicator( const Rectangle& i_rTextBox )
+ {
+ if ( m_bFocused )
+ {
+ const Rectangle aTextPixelBox( m_pPaintDevice->LogicToPixel( i_rTextBox ) );
+
+ m_pPaintDevice->EnableMapMode( FALSE );
+ m_pPaintDevice->SetFillColor();
+
+ Rectangle aBox( i_rTextBox );
+ aBox.Top() -= 1;
+ aBox.Bottom() += 1;
+
+ m_pPaintDevice->DrawRect( aTextPixelBox );
+
+ LineInfo aDottedStyle( LINE_DASH );
+ aDottedStyle.SetDashCount( 0 );
+ aDottedStyle.SetDotCount( 1 );
+ aDottedStyle.SetDotLen( 1 );
+ aDottedStyle.SetDistance( 1 );
+
+ m_pPaintDevice->SetLineColor( COL_BLACK );
+ m_pPaintDevice->DrawPolyLine( Polygon( aTextPixelBox ), aDottedStyle );
+ m_pPaintDevice->EnableMapMode( FALSE );
+ }
+ else
+ HideFocus();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void ToolPanelDrawer::GetFocus()
+ {
+ m_bFocused = true;
+ Invalidate();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void ToolPanelDrawer::LoseFocus()
+ {
+ m_bFocused = false;
+ Invalidate();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void ToolPanelDrawer::Resize()
+ {
+ Window::Resize();
+ m_aVisualization.SetPosSizePixel( Point(), GetOutputSizePixel() );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void ToolPanelDrawer::MouseButtonDown( const MouseEvent& i_rMouseEvent )
+ {
+ // consume this event, and do not forward to the base class - it would sent a NotifyEvent, which in turn, when
+ // we live in a DockingWindow, would start undocking
+ (void)i_rMouseEvent;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void ToolPanelDrawer::DataChanged( const DataChangedEvent& i_rEvent )
+ {
+ Window::DataChanged( i_rEvent );
+
+ switch ( i_rEvent.GetType() )
+ {
+ case DATACHANGED_SETTINGS:
+ if ( ( i_rEvent.GetFlags() & SETTINGS_STYLE ) == 0 )
+ break;
+ SetSettings( Application::GetSettings() );
+ m_pPaintDevice.reset( new VirtualDevice( *this ) );
+
+ // fall through.
+
+ case DATACHANGED_FONTS:
+ case DATACHANGED_FONTSUBSTITUTION:
+ {
+ const StyleSettings& rStyleSettings( GetSettings().GetStyleSettings() );
+
+ // Font.
+ Font aFont = rStyleSettings.GetAppFont();
+ if ( IsControlFont() )
+ aFont.Merge( GetControlFont() );
+ SetZoomedPointFont( aFont );
+
+ // Color.
+ Color aColor;
+ if ( IsControlForeground() )
+ aColor = GetControlForeground();
+ else
+ aColor = rStyleSettings.GetButtonTextColor();
+ SetTextColor( aColor );
+ SetTextFillColor();
+
+ Invalidate();
+ }
+ break;
+ }
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Reference< XWindowPeer > ToolPanelDrawer::GetComponentInterface( BOOL i_bCreate )
+ {
+ Reference< XWindowPeer > xWindowPeer( Window::GetComponentInterface( FALSE ) );
+ if ( !xWindowPeer.is() && i_bCreate )
+ {
+ xWindowPeer.set( new ToolPanelDrawerPeer() );
+ SetComponentInterface( xWindowPeer );
+ }
+ return xWindowPeer;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Rectangle ToolPanelDrawer::impl_calcTextBoundingBox() const
+ {
+ Font aFont( GetFont() );
+ if ( m_bExpanded )
+ aFont.SetWeight( m_bExpanded ? WEIGHT_BOLD : WEIGHT_NORMAL );
+ m_pPaintDevice->SetFont( aFont );
+
+ int nAvailableWidth = m_pPaintDevice->GetTextWidth( GetText() );
+
+ Rectangle aTextBox(
+ Point(),
+ Size(
+ nAvailableWidth,
+ GetSettings().GetStyleSettings().GetTitleHeight()
+ )
+ );
+ aTextBox.Top() += ( aTextBox.GetHeight() - GetTextHeight() ) / 2;
+ aTextBox.Left() += s_nIndentationWidth;
+ aTextBox.Right() -= 1;
+
+ aTextBox = m_pPaintDevice->GetTextRect( aTextBox, GetText(), impl_getTextStyle() );
+ return aTextBox;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Rectangle ToolPanelDrawer::impl_calcTitleBarBox( const Rectangle& i_rTextBox ) const
+ {
+ Rectangle aTitleBarBox( i_rTextBox );
+ aTitleBarBox.Bottom() += aTitleBarBox.Top();
+ aTitleBarBox.Top() = 0;
+ aTitleBarBox.Left() = 0;
+
+ const long nWidth = GetOutputSizePixel().Width();
+ if ( aTitleBarBox.GetWidth() < nWidth )
+ aTitleBarBox.Right() = nWidth - 1;
+
+ return aTitleBarBox;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void ToolPanelDrawer::SetExpanded( const bool i_bExpanded )
+ {
+ if ( m_bExpanded != i_bExpanded )
+ {
+ m_bExpanded = i_bExpanded;
+ CallEventListeners( m_bExpanded ? VCLEVENT_ITEM_EXPANDED : VCLEVENT_ITEM_COLLAPSED );
+ Invalidate();
+ }
+ }
+
+//......................................................................................................................
+} // namespace svt
+//......................................................................................................................
diff --git a/svtools/source/toolpanel/toolpaneldrawer.hxx b/svtools/source/toolpanel/toolpaneldrawer.hxx
new file mode 100644
index 000000000000..a465a0a6c9e1
--- /dev/null
+++ b/svtools/source/toolpanel/toolpaneldrawer.hxx
@@ -0,0 +1,113 @@
+/*************************************************************************
+ * 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 <vcl/window.hxx>
+#include <vcl/virdev.hxx>
+
+//......................................................................................................................
+namespace svt
+{
+//......................................................................................................................
+
+ class ToolPanelDrawer;
+ //==================================================================================================================
+ //= DrawerVisualization
+ //==================================================================================================================
+ /** serves a single purpose - let ZoomText read the drawers ...
+
+ Strange enough, ZoomText does not read the drawers when they get the focus (in none of the combinations
+ of AccessibleRoles I tried), except when it does have an AccessibleChild with the role LABEL. To "inject"
+ such a child into the A11Y hierarchy, we use this window here.
+
+ (We could also inject the A11Y component on the A11Y level only, but this would mean additional code. With
+ this approach here, VCL/toolkit will take care of creating and maintaining the A11Y component for us.)
+ */
+ class DrawerVisualization : public Window
+ {
+ public:
+ DrawerVisualization( ToolPanelDrawer& i_rParent );
+ ~DrawerVisualization();
+
+ protected:
+ // Window overridables
+ virtual void Paint( const Rectangle& i_rBoundingBox );
+
+ private:
+ ToolPanelDrawer& m_rDrawer;
+ };
+
+ //==================================================================================================================
+ //= ToolPanelDrawer
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ class ToolPanelDrawer : public Window
+ {
+ public:
+ ToolPanelDrawer( Window& i_rParent, const ::rtl::OUString& i_rTitle );
+ ~ToolPanelDrawer();
+
+ long GetPreferredHeightPixel() const;
+ void SetExpanded( const bool i_bExpanded );
+ bool IsExpanded() const { return m_bExpanded; }
+
+ void Paint();
+
+ protected:
+ // Window overridables
+ virtual void GetFocus();
+ virtual void LoseFocus();
+ virtual void Resize();
+ virtual void DataChanged( const DataChangedEvent& i_rEvent );
+ virtual void MouseButtonDown( const MouseEvent& i_rMouseEvent );
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >
+ GetComponentInterface( BOOL i_bCreate );
+
+ private:
+ Rectangle impl_calcTextBoundingBox() const;
+ Rectangle impl_calcTitleBarBox( const Rectangle& i_rTextBox ) const;
+ void impl_paintBackground( const Rectangle& i_rTitleBarBox );
+ USHORT impl_getTextStyle() const;
+ void impl_paintFocusIndicator( const Rectangle& i_rTextBox );
+ Rectangle impl_paintExpansionIndicator( const Rectangle& i_rTextBox );
+ Image impl_getExpansionIndicator() const;
+
+ // don't expose SetText. Our text is used as AccessibleName/Desc, and those are not expected to change.
+ using Window::SetText;
+ using Window::Paint;
+
+ private:
+ ::std::auto_ptr< VirtualDevice > m_pPaintDevice;
+ DrawerVisualization m_aVisualization;
+ bool m_bFocused;
+ bool m_bExpanded;
+ };
+
+//......................................................................................................................
+} // namespace svt
+//......................................................................................................................
diff --git a/svtools/source/toolpanel/toolpaneldrawerpeer.cxx b/svtools/source/toolpanel/toolpaneldrawerpeer.cxx
new file mode 100644
index 000000000000..959527330897
--- /dev/null
+++ b/svtools/source/toolpanel/toolpaneldrawerpeer.cxx
@@ -0,0 +1,142 @@
+/*************************************************************************
+ * 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 "toolpaneldrawerpeer.hxx"
+#include "toolpaneldrawer.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+/** === end UNO includes === **/
+
+#include <tools/diagnose_ex.h>
+#include <toolkit/awt/vclxaccessiblecomponent.hxx>
+#include <unotools/accessiblestatesethelper.hxx>
+#include <vcl/vclevent.hxx>
+
+//......................................................................................................................
+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;
+ /** === end UNO using === **/
+ namespace AccessibleStateType = ::com::sun::star::accessibility::AccessibleStateType;
+ namespace AccessibleEventId = ::com::sun::star::accessibility::AccessibleEventId;
+
+ //==================================================================================================================
+ //= ToolPanelDrawerContext
+ //==================================================================================================================
+ class ToolPanelDrawerContext : public VCLXAccessibleComponent
+ {
+ public:
+ ToolPanelDrawerContext( VCLXWindow& i_rWindow )
+ :VCLXAccessibleComponent( &i_rWindow )
+ {
+ }
+
+ virtual void ProcessWindowEvent( const VclWindowEvent& i_rVclWindowEvent );
+ virtual void FillAccessibleStateSet( ::utl::AccessibleStateSetHelper& i_rStateSet );
+
+ protected:
+ ~ToolPanelDrawerContext()
+ {
+ }
+ };
+
+ //------------------------------------------------------------------------------------------------------------------
+ void ToolPanelDrawerContext::ProcessWindowEvent( const VclWindowEvent& i_rVclWindowEvent )
+ {
+ VCLXAccessibleComponent::ProcessWindowEvent( i_rVclWindowEvent );
+
+ switch ( i_rVclWindowEvent.GetId() )
+ {
+ case VCLEVENT_ITEM_EXPANDED:
+ NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, Any(), makeAny( AccessibleStateType::EXPANDED ) );
+ break;
+ case VCLEVENT_ITEM_COLLAPSED:
+ NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, makeAny( AccessibleStateType::EXPANDED ), Any() );
+ break;
+ }
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void ToolPanelDrawerContext::FillAccessibleStateSet( ::utl::AccessibleStateSetHelper& i_rStateSet )
+ {
+ VCLXAccessibleComponent::FillAccessibleStateSet( i_rStateSet );
+ if ( !GetWindow() )
+ return;
+
+ i_rStateSet.AddState( AccessibleStateType::EXPANDABLE );
+ i_rStateSet.AddState( AccessibleStateType::FOCUSABLE );
+
+ const ToolPanelDrawer* pDrawer( dynamic_cast< const ToolPanelDrawer* > ( GetWindow() ) );
+ ENSURE_OR_RETURN_VOID( pDrawer, "ToolPanelDrawerContext::FillAccessibleStateSet: illegal window!" );
+ if ( pDrawer->IsExpanded() )
+ i_rStateSet.AddState( AccessibleStateType::EXPANDED );
+
+ if ( pDrawer->HasChildPathFocus() )
+ i_rStateSet.AddState( AccessibleStateType::FOCUSED );
+ }
+
+ //==================================================================================================================
+ //= ToolPanelDrawerPeer
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ ToolPanelDrawerPeer::ToolPanelDrawerPeer()
+ :VCLXWindow()
+ {
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ToolPanelDrawerPeer::~ToolPanelDrawerPeer()
+ {
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Reference< XAccessibleContext > ToolPanelDrawerPeer::CreateAccessibleContext()
+ {
+ ::vos::OGuard aSolarGuard( GetMutex() );
+ return new ToolPanelDrawerContext( *this );
+ }
+
+//......................................................................................................................
+} // namespace svt
+//......................................................................................................................
diff --git a/svtools/source/toolpanel/toolpaneldrawerpeer.hxx b/svtools/source/toolpanel/toolpaneldrawerpeer.hxx
new file mode 100644
index 000000000000..5fcf0ac0ae7c
--- /dev/null
+++ b/svtools/source/toolpanel/toolpaneldrawerpeer.hxx
@@ -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.
+ *
+ ************************************************************************/
+
+#ifndef SVT_TOOLPANELDRAWERPEER_HXX
+#define SVT_TOOLPANELDRAWERPEER_HXX
+
+#include <toolkit/awt/vclxwindow.hxx>
+
+//......................................................................................................................
+namespace svt
+{
+//......................................................................................................................
+
+ //==================================================================================================================
+ //= ToolPanelDrawerPeer
+ //==================================================================================================================
+ class ToolPanelDrawerPeer : public VCLXWindow
+ {
+ public:
+ ToolPanelDrawerPeer();
+
+ protected:
+ ~ToolPanelDrawerPeer();
+
+ // VCLXWindow overridables
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > CreateAccessibleContext();
+ };
+
+//......................................................................................................................
+} // namespace svt
+//......................................................................................................................
+
+#endif // SVT_TOOLPANELDRAWERPEER_HXX
diff --git a/svtools/source/uno/makefile.mk b/svtools/source/uno/makefile.mk
index 7bfe37624947..7c1c44006047 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 \
@@ -55,7 +52,9 @@ SLOFILES= \
$(SLO)$/unoevent.obj \
$(SLO)$/unoiface.obj \
$(SLO)$/unoimap.obj \
- $(SLO)$/svtxgridcontrol.obj
+ $(SLO)$/svtxgridcontrol.obj \
+ $(SLO)$/popupwindowcontroller.obj \
+ $(SLO)$/popupmenucontrollerbase.obj
# --- Targets ------------------------------------------------------
diff --git a/svtools/source/uno/popupmenucontrollerbase.cxx b/svtools/source/uno/popupmenucontrollerbase.cxx
new file mode 100644
index 000000000000..ac75a1b9a24b
--- /dev/null
+++ b/svtools/source/uno/popupmenucontrollerbase.cxx
@@ -0,0 +1,420 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include "svtools/popupmenucontrollerbase.hxx"
+
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/awt/MenuItemStyle.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/awt/XMenuExtended.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+
+#ifndef _VCL_MENU_HXX_
+#include <vcl/menu.hxx>
+#endif
+#include <vcl/svapp.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/logfile.hxx>
+#include <vos/mutex.hxx>
+
+//_________________________________________________________________________________________________________________
+// Defines
+//_________________________________________________________________________________________________________________
+//
+
+using ::rtl::OUString;
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+
+namespace svt
+{
+
+struct PopupMenuControllerBaseDispatchInfo
+{
+ Reference< XDispatch > mxDispatch;
+ const URL maURL;
+ const Sequence< PropertyValue > maArgs;
+
+ PopupMenuControllerBaseDispatchInfo( const Reference< XDispatch >& xDispatch, const URL& rURL, const Sequence< PropertyValue >& rArgs )
+ : mxDispatch( xDispatch ), maURL( rURL ), maArgs( rArgs ) {}
+};
+
+PopupMenuControllerBase::PopupMenuControllerBase( const Reference< XMultiServiceFactory >& xServiceManager ) :
+ ::comphelper::OBaseMutex(),
+ PopupMenuControllerBaseType(m_aMutex),
+ m_bInitialized( false ),
+ m_xServiceManager( xServiceManager )
+{
+ if ( m_xServiceManager.is() )
+ m_xURLTransformer.set( m_xServiceManager->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer"))),UNO_QUERY );
+}
+
+PopupMenuControllerBase::~PopupMenuControllerBase()
+{
+}
+
+// protected function
+void PopupMenuControllerBase::throwIfDisposed() throw ( RuntimeException )
+{
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ throw com::sun::star::lang::DisposedException();
+}
+
+// protected function
+void PopupMenuControllerBase::resetPopupMenu( com::sun::star::uno::Reference< com::sun::star::awt::XPopupMenu >& rPopupMenu )
+{
+ VCLXPopupMenu* pPopupMenu = 0;
+ if ( rPopupMenu.is() && rPopupMenu->getItemCount() > 0 )
+ {
+ pPopupMenu = (VCLXPopupMenu *)VCLXMenu::GetImplementation( rPopupMenu );
+ if ( pPopupMenu )
+ {
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ PopupMenu* pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu();
+ pVCLPopupMenu->Clear();
+ }
+ }
+}
+
+void SAL_CALL PopupMenuControllerBase::disposing()
+{
+ // Reset our members and set disposed flag
+ osl::MutexGuard aLock( m_aMutex );
+ m_xFrame.clear();
+ m_xDispatch.clear();
+ m_xPopupMenu.clear();
+ m_xServiceManager.clear();
+}
+
+// XServiceInfo
+
+sal_Bool SAL_CALL PopupMenuControllerBase::supportsService( const ::rtl::OUString& ServiceName ) throw (RuntimeException)
+{
+ const Sequence< rtl::OUString > aSNL( getSupportedServiceNames() );
+ const rtl::OUString * pArray = aSNL.getConstArray();
+
+ for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
+ if( pArray[i] == ServiceName )
+ return true;
+
+ return false;
+}
+
+// XEventListener
+void SAL_CALL PopupMenuControllerBase::disposing( const EventObject& ) throw ( RuntimeException )
+{
+ osl::MutexGuard aLock( m_aMutex );
+ m_xFrame.clear();
+ m_xDispatch.clear();
+ m_xPopupMenu.clear();
+}
+
+// XMenuListener
+void SAL_CALL PopupMenuControllerBase::highlight( const awt::MenuEvent& ) throw (RuntimeException)
+{
+}
+
+void PopupMenuControllerBase::impl_select(const Reference< XDispatch >& _xDispatch,const URL& aURL)
+{
+ Sequence<PropertyValue> aArgs;
+ OSL_ENSURE(_xDispatch.is(),"PopupMenuControllerBase::impl_select: No dispatch");
+ if ( _xDispatch.is() )
+ _xDispatch->dispatch( aURL, aArgs );
+}
+
+void SAL_CALL PopupMenuControllerBase::select( const awt::MenuEvent& rEvent ) throw (RuntimeException)
+{
+ throwIfDisposed();
+
+ osl::MutexGuard aLock( m_aMutex );
+
+ Reference< awt::XMenuExtended > xExtMenu( m_xPopupMenu, UNO_QUERY );
+ if( xExtMenu.is() )
+ {
+ Sequence<PropertyValue> aArgs;
+ dispatchCommand( xExtMenu->getCommand( rEvent.MenuId ), aArgs );
+ }
+}
+
+void PopupMenuControllerBase::dispatchCommand( const ::rtl::OUString& sCommandURL, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rArgs )
+{
+ osl::MutexGuard aLock( m_aMutex );
+
+ throwIfDisposed();
+
+ try
+ {
+ Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY_THROW );
+ URL aURL;
+ aURL.Complete = sCommandURL;
+ m_xURLTransformer->parseStrict( aURL );
+
+ Reference< XDispatch > xDispatch( xDispatchProvider->queryDispatch( aURL, OUString(), 0 ), UNO_QUERY_THROW );
+
+ Application::PostUserEvent( STATIC_LINK(0, PopupMenuControllerBase, ExecuteHdl_Impl), new PopupMenuControllerBaseDispatchInfo( xDispatch, aURL, rArgs ) );
+
+ }
+ catch( Exception& )
+ {
+ }
+
+}
+
+IMPL_STATIC_LINK_NOINSTANCE( PopupMenuControllerBase, ExecuteHdl_Impl, PopupMenuControllerBaseDispatchInfo*, pDispatchInfo )
+{
+ pDispatchInfo->mxDispatch->dispatch( pDispatchInfo->maURL, pDispatchInfo->maArgs );
+ delete pDispatchInfo;
+ return 0;
+}
+
+void SAL_CALL PopupMenuControllerBase::activate( const awt::MenuEvent& ) throw (RuntimeException)
+{
+}
+
+void SAL_CALL PopupMenuControllerBase::deactivate( const awt::MenuEvent& ) throw (RuntimeException)
+{
+}
+
+void SAL_CALL PopupMenuControllerBase::updatePopupMenu() throw ( ::com::sun::star::uno::RuntimeException )
+{
+ osl::ClearableMutexGuard aLock( m_aMutex );
+ throwIfDisposed();
+ aLock.clear();
+
+ updateCommand( m_aCommandURL );
+}
+
+void SAL_CALL PopupMenuControllerBase::updateCommand( const rtl::OUString& rCommandURL )
+{
+ osl::ClearableMutexGuard aLock( m_aMutex );
+ Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
+ Reference< XDispatch > xDispatch( m_xDispatch );
+ URL aTargetURL;
+ aTargetURL.Complete = rCommandURL;
+ m_xURLTransformer->parseStrict( aTargetURL );
+ aLock.clear();
+
+ // Add/remove status listener to get a status update once
+ if ( xDispatch.is() )
+ {
+ xDispatch->addStatusListener( xStatusListener, aTargetURL );
+ xDispatch->removeStatusListener( xStatusListener, aTargetURL );
+ }
+}
+
+
+// XDispatchProvider
+Reference< XDispatch > SAL_CALL
+PopupMenuControllerBase::queryDispatch(
+ const URL& /*aURL*/,
+ const rtl::OUString& /*sTarget*/,
+ sal_Int32 /*nFlags*/ )
+throw( RuntimeException )
+{
+ // must be implemented by subclass
+ osl::MutexGuard aLock( m_aMutex );
+ throwIfDisposed();
+
+ return Reference< XDispatch >();
+}
+
+Sequence< Reference< XDispatch > > SAL_CALL PopupMenuControllerBase::queryDispatches( const Sequence< DispatchDescriptor >& lDescriptor ) throw( RuntimeException )
+{
+ // Create return list - which must have same size then the given descriptor
+ // It's not allowed to pack it!
+ osl::ClearableMutexGuard aLock( m_aMutex );
+ throwIfDisposed();
+ aLock.clear();
+
+ sal_Int32 nCount = lDescriptor.getLength();
+ uno::Sequence< uno::Reference< frame::XDispatch > > lDispatcher( nCount );
+
+ // Step over all descriptors and try to get any dispatcher for it.
+ for( sal_Int32 i=0; i<nCount; ++i )
+ {
+ lDispatcher[i] = queryDispatch( lDescriptor[i].FeatureURL ,
+ lDescriptor[i].FrameName ,
+ lDescriptor[i].SearchFlags );
+ }
+
+ return lDispatcher;
+}
+
+// XDispatch
+void SAL_CALL
+PopupMenuControllerBase::dispatch(
+ const URL& /*aURL*/,
+ const Sequence< PropertyValue >& /*seqProperties*/ )
+throw( ::com::sun::star::uno::RuntimeException )
+{
+ // must be implemented by subclass
+ osl::MutexGuard aLock( m_aMutex );
+ throwIfDisposed();
+}
+
+void SAL_CALL
+PopupMenuControllerBase::addStatusListener(
+ const Reference< XStatusListener >& xControl,
+ const URL& aURL )
+throw( ::com::sun::star::uno::RuntimeException )
+{
+ osl::ResettableMutexGuard aLock( m_aMutex );
+ throwIfDisposed();
+ aLock.clear();
+
+ bool bStatusUpdate( false );
+ rBHelper.addListener( ::getCppuType( &xControl ), xControl );
+
+ aLock.reset();
+ if ( aURL.Complete.indexOf( m_aBaseURL ) == 0 )
+ bStatusUpdate = true;
+ aLock.clear();
+
+ if ( bStatusUpdate )
+ {
+ // Dummy update for popup menu controllers
+ FeatureStateEvent aEvent;
+ aEvent.FeatureURL = aURL;
+ aEvent.IsEnabled = sal_True;
+ aEvent.Requery = sal_False;
+ aEvent.State = Any();
+ xControl->statusChanged( aEvent );
+ }
+}
+
+void SAL_CALL PopupMenuControllerBase::removeStatusListener(
+ const Reference< XStatusListener >& xControl,
+ const URL& /*aURL*/ )
+throw( ::com::sun::star::uno::RuntimeException )
+{
+ rBHelper.removeListener( ::getCppuType( &xControl ), xControl );
+}
+
+::rtl::OUString PopupMenuControllerBase::determineBaseURL( const ::rtl::OUString& aURL )
+{
+ // Just use the main part of the URL for popup menu controllers
+ sal_Int32 nQueryPart( 0 );
+ sal_Int32 nSchemePart( 0 );
+ rtl::OUString aMainURL( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.popup:" ));
+
+ nSchemePart = aURL.indexOf( ':' );
+ if (( nSchemePart > 0 ) &&
+ ( aURL.getLength() > ( nSchemePart+1 )))
+ {
+ nQueryPart = aURL.indexOf( '?', nSchemePart );
+ if ( nQueryPart > 0 )
+ aMainURL += aURL.copy( nSchemePart, nQueryPart-nSchemePart );
+ else if ( nQueryPart == -1 )
+ aMainURL += aURL.copy( nSchemePart+1 );
+ }
+
+ return aMainURL;
+}
+
+// XInitialization
+void SAL_CALL PopupMenuControllerBase::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException )
+{
+ osl::MutexGuard aLock( m_aMutex );
+
+ sal_Bool bInitalized( m_bInitialized );
+ if ( !bInitalized )
+ {
+ PropertyValue aPropValue;
+ rtl::OUString aCommandURL;
+ Reference< XFrame > xFrame;
+
+ for ( int i = 0; i < aArguments.getLength(); i++ )
+ {
+ if ( aArguments[i] >>= aPropValue )
+ {
+ if ( aPropValue.Name.equalsAscii( "Frame" ))
+ aPropValue.Value >>= xFrame;
+ else if ( aPropValue.Name.equalsAscii( "CommandURL" ))
+ aPropValue.Value >>= aCommandURL;
+ }
+ }
+
+ if ( xFrame.is() && aCommandURL.getLength() )
+ {
+ m_xFrame = xFrame;
+ m_aCommandURL = aCommandURL;
+ m_aBaseURL = determineBaseURL( aCommandURL );
+ m_bInitialized = true;
+ }
+ }
+}
+// XPopupMenuController
+void SAL_CALL PopupMenuControllerBase::setPopupMenu( const Reference< awt::XPopupMenu >& xPopupMenu ) throw ( RuntimeException )
+{
+ osl::MutexGuard aLock( m_aMutex );
+ throwIfDisposed();
+
+ if ( m_xFrame.is() && !m_xPopupMenu.is() )
+ {
+ // Create popup menu on demand
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ m_xPopupMenu = xPopupMenu;
+ m_xPopupMenu->addMenuListener( Reference< awt::XMenuListener >( (OWeakObject*)this, UNO_QUERY ));
+
+ Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
+
+ URL aTargetURL;
+ aTargetURL.Complete = m_aCommandURL;
+ m_xURLTransformer->parseStrict( aTargetURL );
+ m_xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
+
+ impl_setPopupMenu();
+
+ updatePopupMenu();
+ }
+}
+void PopupMenuControllerBase::impl_setPopupMenu()
+{
+}
+}
diff --git a/svtools/source/uno/popupwindowcontroller.cxx b/svtools/source/uno/popupwindowcontroller.cxx
new file mode 100644
index 000000000000..4fbaff23714d
--- /dev/null
+++ b/svtools/source/uno/popupwindowcontroller.cxx
@@ -0,0 +1,258 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include <toolkit/helper/vclunohelper.hxx>
+
+#include <vcl/toolbox.hxx>
+#include <vcl/svapp.hxx>
+
+#include "svtools/popupwindowcontroller.hxx"
+#include "svtools/toolbarmenu.hxx"
+
+using rtl::OUString;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+
+
+namespace svt
+{
+
+class PopupWindowControllerImpl
+{
+public:
+ PopupWindowControllerImpl();
+ ~PopupWindowControllerImpl();
+
+ void SetPopupWindow( ::Window* pPopupWindow, ToolBox* pToolBox );
+
+ DECL_LINK( WindowEventListener, VclSimpleEvent* );
+ DECL_STATIC_LINK( PopupWindowControllerImpl, AsyncDeleteWindowHdl, Window* );
+
+private:
+ ::Window* mpPopupWindow;
+ ToolBox* mpToolBox;
+};
+
+PopupWindowControllerImpl::PopupWindowControllerImpl()
+: mpPopupWindow( 0 )
+, mpToolBox( 0 )
+{
+}
+
+PopupWindowControllerImpl::~PopupWindowControllerImpl()
+{
+ if( mpPopupWindow )
+ SetPopupWindow(0,0);
+}
+
+void PopupWindowControllerImpl::SetPopupWindow( ::Window* pPopupWindow, ToolBox* pToolBox )
+{
+ if( mpPopupWindow )
+ {
+ mpPopupWindow->RemoveEventListener( LINK( this, PopupWindowControllerImpl, WindowEventListener ) );
+ Application::PostUserEvent( STATIC_LINK( this, PopupWindowControllerImpl, AsyncDeleteWindowHdl ), mpPopupWindow );
+ }
+ mpPopupWindow = pPopupWindow;
+ mpToolBox = pToolBox;
+
+ if( mpPopupWindow )
+ {
+ mpPopupWindow->AddEventListener( LINK( this, PopupWindowControllerImpl, WindowEventListener ));
+ }
+}
+
+IMPL_LINK( PopupWindowControllerImpl, WindowEventListener, VclSimpleEvent*, pEvent )
+{
+ VclWindowEvent* pWindowEvent = dynamic_cast< VclWindowEvent* >( pEvent );
+ if( pWindowEvent )
+ {
+ switch( pWindowEvent->GetId() )
+ {
+ case VCLEVENT_WINDOW_CLOSE:
+ case VCLEVENT_WINDOW_ENDPOPUPMODE:
+ SetPopupWindow(0,0);
+ break;
+
+ case VCLEVENT_WINDOW_SHOW:
+ {
+ if( mpPopupWindow )
+ {
+ if( mpToolBox )
+ mpToolBox->CallEventListeners( VCLEVENT_DROPDOWN_OPEN, (void*)mpPopupWindow );
+ mpPopupWindow->CallEventListeners( VCLEVENT_WINDOW_GETFOCUS, 0 );
+
+ svtools::ToolbarMenu* pToolbarMenu = dynamic_cast< svtools::ToolbarMenu* >( mpPopupWindow );
+ if( pToolbarMenu )
+ pToolbarMenu->highlightFirstEntry();
+ break;
+ }
+ break;
+ }
+ case VCLEVENT_WINDOW_HIDE:
+ {
+ if( mpPopupWindow )
+ {
+ mpPopupWindow->CallEventListeners( VCLEVENT_WINDOW_LOSEFOCUS, 0 );
+ if( mpToolBox )
+ mpToolBox->CallEventListeners( VCLEVENT_DROPDOWN_CLOSE, (void*)mpPopupWindow );
+ }
+ break;
+ }
+ }
+ }
+ return 1;
+}
+
+//--------------------------------------------------------------------
+
+IMPL_STATIC_LINK( PopupWindowControllerImpl, AsyncDeleteWindowHdl, Window*, pWindow )
+{
+ (void)*pThis;
+ delete pWindow;
+ return 0;
+}
+
+//========================================================================
+// class PopupWindowController
+//========================================================================
+
+PopupWindowController::PopupWindowController( const Reference< lang::XMultiServiceFactory >& rServiceManager,
+ const Reference< frame::XFrame >& xFrame,
+ const OUString& aCommandURL )
+: svt::ToolboxController( rServiceManager, xFrame, aCommandURL )
+, mpImpl( new PopupWindowControllerImpl() )
+{
+}
+
+PopupWindowController::~PopupWindowController()
+{
+}
+
+// XInterface
+Any SAL_CALL PopupWindowController::queryInterface( const Type& aType )
+throw (RuntimeException)
+{
+ Any a( ToolboxController::queryInterface( aType ) );
+ if ( a.hasValue() )
+ return a;
+
+ return ::cppu::queryInterface( aType, static_cast< lang::XServiceInfo* >( this ));
+}
+
+void SAL_CALL PopupWindowController::acquire() throw ()
+{
+ ToolboxController::acquire();
+}
+
+void SAL_CALL PopupWindowController::release() throw ()
+{
+ ToolboxController::release();
+}
+
+// XServiceInfo
+sal_Bool SAL_CALL PopupWindowController::supportsService( const OUString& ServiceName ) throw(RuntimeException)
+{
+ const Sequence< OUString > aSNL( getSupportedServiceNames() );
+ const OUString * pArray = aSNL.getConstArray();
+
+ for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
+ if( pArray[i] == ServiceName )
+ return true;
+
+ return false;
+}
+
+// XInitialization
+void SAL_CALL PopupWindowController::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ svt::ToolboxController::initialize( aArguments );
+ if( m_aCommandURL.getLength() )
+ addStatusListener( m_aCommandURL );
+}
+
+// XComponent
+void SAL_CALL PopupWindowController::dispose() throw (RuntimeException)
+{
+ if( m_aCommandURL.getLength() )
+ removeStatusListener( m_aCommandURL );
+
+ svt::ToolboxController::dispose();
+}
+
+
+// XStatusListener
+void SAL_CALL PopupWindowController::statusChanged( const frame::FeatureStateEvent& rEvent ) throw ( RuntimeException )
+{
+ svt::ToolboxController::statusChanged(rEvent);
+ enable( rEvent.IsEnabled );
+}
+
+// XToolbarController
+void SAL_CALL PopupWindowController::execute( sal_Int16 KeyModifier ) throw (RuntimeException)
+{
+ svt::ToolboxController::execute( KeyModifier );
+}
+
+void SAL_CALL PopupWindowController::click() throw (RuntimeException)
+{
+ svt::ToolboxController::click();
+}
+
+void SAL_CALL PopupWindowController::doubleClick() throw (RuntimeException)
+{
+ svt::ToolboxController::doubleClick();
+}
+
+Reference< awt::XWindow > SAL_CALL PopupWindowController::createPopupWindow() throw (RuntimeException)
+{
+ ToolBox* pToolBox = dynamic_cast< ToolBox* >( VCLUnoHelper::GetWindow( getParent() ) );
+ if( pToolBox )
+ {
+ ::Window* pItemWindow = pToolBox->GetItemWindow( pToolBox->GetDownItemId() );
+ ::Window* pWin = createPopupWindow( pItemWindow ? pItemWindow : pToolBox );
+ if( pWin )
+ {
+ pWin->EnableDocking(true);
+ mpImpl->SetPopupWindow(pWin,pToolBox);
+ ::Window::GetDockingManager()->StartPopupMode( pToolBox, pWin, FLOATWIN_POPUPMODE_NOFOCUSCLOSE|FLOATWIN_POPUPMODE_ALLMOUSEBUTTONCLOSE |FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE );
+ }
+ }
+ return Reference< awt::XWindow >();
+}
+
+Reference< awt::XWindow > SAL_CALL PopupWindowController::createItemWindow( const Reference< awt::XWindow >& /*Parent*/ )
+ throw (RuntimeException)
+{
+ return Reference< awt::XWindow >();
+}
+
+}
+
diff --git a/svtools/source/uno/toolboxcontroller.cxx b/svtools/source/uno/toolboxcontroller.cxx
index 3f0b4e7c0ee6..d9b84aa2e356 100644
--- a/svtools/source/uno/toolboxcontroller.cxx
+++ b/svtools/source/uno/toolboxcontroller.cxx
@@ -43,6 +43,8 @@
#endif
#include <vcl/toolbox.hxx>
+using ::rtl::OUString;
+
using namespace ::cppu;
using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::uno;
@@ -54,10 +56,29 @@ using namespace ::com::sun::star::frame;
namespace svt
{
+
+struct DispatchInfo
+{
+ Reference< XDispatch > mxDispatch;
+ const URL maURL;
+ const Sequence< PropertyValue > maArgs;
+
+ DispatchInfo( const Reference< XDispatch >& xDispatch, const URL& rURL, const Sequence< PropertyValue >& rArgs )
+ : mxDispatch( xDispatch ), maURL( rURL ), maArgs( rArgs ) {}
+};
+
struct ToolboxController_Impl
{
::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > m_xParentWindow;
::com::sun::star::uno::Reference< ::com::sun::star::util::XURLTransformer > m_xUrlTransformer;
+ rtl::OUString m_sModuleName;
+ sal_uInt16 m_nToolBoxId;
+
+ DECL_STATIC_LINK( ToolboxController_Impl, ExecuteHdl_Impl, DispatchInfo* );
+
+ ToolboxController_Impl()
+ : m_nToolBoxId( SAL_MAX_UINT16 )
+ {}
};
ToolboxController::ToolboxController(
@@ -166,11 +187,6 @@ void SAL_CALL ToolboxController::release() throw ()
void SAL_CALL ToolboxController::initialize( const Sequence< Any >& aArguments )
throw ( Exception, RuntimeException )
{
- const rtl::OUString aFrameName( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
- const rtl::OUString aCommandURLName( RTL_CONSTASCII_USTRINGPARAM( "CommandURL" ));
- const rtl::OUString aServiceManagerName( RTL_CONSTASCII_USTRINGPARAM( "ServiceManager" ));
- const rtl::OUString aParentWindow( RTL_CONSTASCII_USTRINGPARAM( "ParentWindow" ));
-
bool bInitialized( true );
{
@@ -192,14 +208,16 @@ throw ( Exception, RuntimeException )
{
if ( aArguments[i] >>= aPropValue )
{
- if ( aPropValue.Name.equalsAscii( "Frame" ))
+ if ( aPropValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Frame") ))
m_xFrame.set(aPropValue.Value,UNO_QUERY);
- else if ( aPropValue.Name.equalsAscii( "CommandURL" ))
+ else if ( aPropValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("CommandURL") ))
aPropValue.Value >>= m_aCommandURL;
- else if ( aPropValue.Name.equalsAscii( "ServiceManager" ))
+ else if ( aPropValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("ServiceManager") ))
m_xServiceManager.set(aPropValue.Value,UNO_QUERY);
- else if ( aPropValue.Name.equalsAscii( "ParentWindow" ))
+ else if ( aPropValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("ParentWindow") ))
m_pImpl->m_xParentWindow.set(aPropValue.Value,UNO_QUERY);
+ else if ( aPropValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("ModuleName" ) ) )
+ aPropValue.Value >>= m_pImpl->m_sModuleName;
}
}
@@ -704,4 +722,77 @@ Reference< ::com::sun::star::awt::XWindow > ToolboxController::getParent() const
{
return m_pImpl->m_xParentWindow;
}
+
+const rtl::OUString& ToolboxController::getModuleName() const
+{
+ return m_pImpl->m_sModuleName;
+}
+
+void ToolboxController::dispatchCommand( const OUString& sCommandURL, const Sequence< PropertyValue >& rArgs )
+{
+ try
+ {
+ Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY_THROW );
+ URL aURL;
+ aURL.Complete = sCommandURL;
+ getURLTransformer()->parseStrict( aURL );
+
+ Reference< XDispatch > xDispatch( xDispatchProvider->queryDispatch( aURL, OUString(), 0 ), UNO_QUERY_THROW );
+
+ Application::PostUserEvent( STATIC_LINK(0, ToolboxController_Impl, ExecuteHdl_Impl), new DispatchInfo( xDispatch, aURL, rArgs ) );
+
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+//--------------------------------------------------------------------
+
+IMPL_STATIC_LINK_NOINSTANCE( ToolboxController_Impl, ExecuteHdl_Impl, DispatchInfo*, pDispatchInfo )
+{
+ pDispatchInfo->mxDispatch->dispatch( pDispatchInfo->maURL, pDispatchInfo->maArgs );
+ delete pDispatchInfo;
+ return 0;
+}
+
+void ToolboxController::enable( bool bEnable )
+{
+ ToolBox* pToolBox = 0;
+ sal_uInt16 nItemId = 0;
+ if( getToolboxId( nItemId, &pToolBox ) )
+ {
+ pToolBox->EnableItem( nItemId, bEnable ? TRUE : FALSE );
+ }
+}
+
+bool ToolboxController::getToolboxId( sal_uInt16& rItemId, ToolBox** ppToolBox )
+{
+ if( (m_pImpl->m_nToolBoxId != SAL_MAX_UINT16) && (ppToolBox == 0) )
+ return m_pImpl->m_nToolBoxId;
+
+ ToolBox* pToolBox = static_cast< ToolBox* >( VCLUnoHelper::GetWindow( getParent() ) );
+
+ if( (m_pImpl->m_nToolBoxId == SAL_MAX_UINT16) && pToolBox )
+ {
+ const sal_uInt16 nCount = pToolBox->GetItemCount();
+ for ( sal_uInt16 nPos = 0; nPos < nCount; ++nPos )
+ {
+ const sal_uInt16 nItemId = pToolBox->GetItemId( nPos );
+ if ( pToolBox->GetItemCommand( nItemId ) == String( m_aCommandURL ) )
+ {
+ m_pImpl->m_nToolBoxId = nItemId;
+ break;
+ }
+ }
+ }
+
+ if( ppToolBox )
+ *ppToolBox = pToolBox;
+
+ rItemId = m_pImpl->m_nToolBoxId;
+
+ return (rItemId != SAL_MAX_UINT16) && (( ppToolBox == 0) || (*ppToolBox != 0) );
+}
+
} // svt
diff --git a/svtools/source/uno/treecontrolpeer.cxx b/svtools/source/uno/treecontrolpeer.cxx
index a46b9605a00d..e5a273bbbf6d 100644
--- a/svtools/source/uno/treecontrolpeer.cxx
+++ b/svtools/source/uno/treecontrolpeer.cxx
@@ -196,7 +196,9 @@ void TreeControlPeer::addEntry( UnoTreeListEntry* pEntry )
mpTreeNodeMap = new TreeNodeMap();
}
- (*mpTreeNodeMap)[ pEntry->mxNode ] = pEntry;
+ const Reference< XTreeNode > xNormalizedNode( pEntry->mxNode, UNO_QUERY );
+ (*mpTreeNodeMap)[ xNormalizedNode ] = pEntry;
+ OSL_TRACE( "tree: adding %p => %p", xNormalizedNode.get(), pEntry );
}
}
@@ -206,9 +208,13 @@ void TreeControlPeer::removeEntry( UnoTreeListEntry* pEntry )
{
if( mpTreeNodeMap && pEntry && pEntry->mxNode.is() )
{
- TreeNodeMap::iterator aIter( mpTreeNodeMap->find( pEntry->mxNode ) );
+ const Reference< XTreeNode > xNormalizedNode( pEntry->mxNode, UNO_QUERY );
+ TreeNodeMap::iterator aIter( mpTreeNodeMap->find( xNormalizedNode ) );
if( aIter != mpTreeNodeMap->end() )
+ {
+ OSL_TRACE( "tree: removing %p => %p", xNormalizedNode.get(), pEntry );
mpTreeNodeMap->erase( aIter );
+ }
}
}
@@ -218,7 +224,8 @@ UnoTreeListEntry* TreeControlPeer::getEntry( const Reference< XTreeNode >& xNode
{
if( mpTreeNodeMap )
{
- TreeNodeMap::iterator aIter( mpTreeNodeMap->find( xNode ) );
+ const Reference< XTreeNode > xNormalizedNode( xNode, UNO_QUERY );
+ TreeNodeMap::iterator aIter( mpTreeNodeMap->find( xNormalizedNode ) );
if( aIter != mpTreeNodeMap->end() )
return (*aIter).second;
}
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" ;
- };
- };
-};
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-