Difference between revisions of "Sidebar"

From Apache OpenOffice Wiki
Jump to: navigation, search
m (New date for 0.7 dev build)
Line 1: Line 1:
The sidebar (working title) is a new feature likely to be in the 4.0 release. It combines ideas and code from both the [[Symphony]] sidebar and the OpenOffice [[Impress]] task pane.
+
The sidebar (working title) is a new feature likely to be in the 4.0 release. It combines ideas and code from both the [[Symphony]] sidebar and the OpenOffice [[Impress]] task pane.
  
The UX part of the work is described on another [[AOO_UX_Design_Exploration_-_Task_Pane_Content_-_Information_Design|page]]. This page focuses on the API design and implementation.
+
The UX part of the work is described on another [[AOO_UX_Design_Exploration_-_Task_Pane_Content_-_Information_Design|page]]. This page focuses on the API design and implementation.
  
 
Help in whatever form (writing code, designing the UI, testing) is welcome.
 
Help in whatever form (writing code, designing the UI, testing) is welcome.
Line 16: Line 16:
  
 
19. Feb. 2013:
 
19. Feb. 2013:
Impress panels have been migrated (left). The closer in the deck title bar hides the deck but leaves the tab bar visible (right). The three master page panels are now first class citizens in the sidebar world. That makes it possible to reorder them or show/hide them independently.
+
Impress panels have been migrated (left). The closer in the deck title bar hides the deck but leaves the tab bar visible (right). The three master page panels are now first class citizens in the sidebar world. That makes it possible to reorder them or show/hide them independently.
  
 
[[File:sidebar-2013-02-19-a.png|200px]], [[File:sidebar-2013-02-19-c.png|45px]].
 
[[File:sidebar-2013-02-19-a.png|200px]], [[File:sidebar-2013-02-19-c.png|45px]].
  
 
18. Jan. 2013:
 
18. Jan. 2013:
Migration of Symphony text properties panel (work in progress). With original Symphony icons (far left) and OpenOffice icons (all other) and with different colors for panel titles and panel backgrounds:
+
Migration of Symphony text properties panel (work in progress). With original Symphony icons (far left) and OpenOffice icons (all other) and with different colors for panel titles and panel backgrounds:
  
 
[[File:sidebar-2013-01-18-a.png|200px]], [[File:sidebar-2013-01-18-b.png|200px]], [[File:sidebar-2013-01-18-c.png|200px]], [[File:sidebar-2013-01-18-d.png|200px]]
 
[[File:sidebar-2013-01-18-a.png|200px]], [[File:sidebar-2013-01-18-b.png|200px]], [[File:sidebar-2013-01-18-c.png|200px]], [[File:sidebar-2013-01-18-d.png|200px]]
  
 
15. Jan. 2013:
 
15. Jan. 2013:
Controls in sidebar pane are themable. Click one of the preset buttons in the Java theme dialog to see one of the proposed themes applied to a working panel:
+
Controls in sidebar pane are themable. Click one of the preset buttons in the Java theme dialog to see one of the proposed themes applied to a working panel:
  
 
[[File:sidebar-2013-01-15.png|400px]]
 
[[File:sidebar-2013-01-15.png|400px]]
Line 35: Line 35:
 
** by already existing extensions using the XUIElementProvider interface family,
 
** by already existing extensions using the XUIElementProvider interface family,
 
** by Impress (but there are still severe painting problems).
 
** by Impress (but there are still severe painting problems).
* The sidebar menu already works. It is almost identical to its Symphony counterpart with one additional entry for docking or undocking the sidebar.
+
* The sidebar menu already works. It is almost identical to its Symphony counterpart with one additional entry for docking or undocking the sidebar.
 
* Individual panels can be collapsed or expanded.
 
* Individual panels can be collapsed or expanded.
 
* The older and unfinished sidebar support that was done when OpenOffice was developed by Oracle is still active as a reference.
 
* The older and unfinished sidebar support that was done when OpenOffice was developed by Oracle is still active as a reference.
 
*Designed API (new services and interfaces) and configuration for declaration of sidebar decks and panels and notification of context changes.
 
*Designed API (new services and interfaces) and configuration for declaration of sidebar decks and panels and notification of context changes.
*Initial implementation as test of the design. Most of the changes can be found in [http://svn.apache.org/viewvc/openoffice/branches/sidebar/main/sfx2/source/sidebar/sfx2/source/sidebar] and [http://svn.apache.org/viewvc/openoffice/branches/sidebar/main/svx/source/sidebar/svx/source/sidebar].
+
*Initial implementation as test of the design. Most of the changes can be found in [http://svn.apache.org/viewvc/openoffice/branches/sidebar/main/sfx2/source/sidebar/sfx2/source/sidebar] and [http://svn.apache.org/viewvc/openoffice/branches/sidebar/main/svx/source/sidebar/svx/source/sidebar].
* Migration of first Symphony panel is progressing well. Simple theming is already in place.
+
* Migration of first Symphony panel is progressing well. Simple theming is already in place.
* Theme is represented as XPropertySet. See screenshot below for a Java extension that a) displays the current context in a sidebar panel and that b) provides a dialog for visualizing the different property values and allows simple switching between theme presets.
+
* Theme is represented as XPropertySet. See screenshot below for a Java extension that a) displays the current context in a sidebar panel and that b) provides a dialog for visualizing the different property values and allows simple switching between theme presets.
  
 
==Resources==
 
==Resources==
Line 63: Line 63:
 
*[http://people.apache.org/~af/sidebar/0.7/Apache_OpenOffice_3.5.0_MacOS_x86_install-arc_en-US.tar.gz MacOSX].
 
*[http://people.apache.org/~af/sidebar/0.7/Apache_OpenOffice_3.5.0_MacOS_x86_install-arc_en-US.tar.gz MacOSX].
  
All builds are archives, to avoid accidental installation. On Windows there seems to be trouble with the name of the top level directory ("Apache_OpenOffice_3.5.0 ..."). Possible fixes:
+
All builds are archives, to avoid accidental installation. On Windows there seems to be trouble with the name of the top level directory ("Apache_OpenOffice_3.5.0 ..."). Possible fixes:
 
- Copy the content of that directory to some other place and run from there
 
- Copy the content of that directory to some other place and run from there
 
- Rename to something shorter/simpler.
 
- Rename to something shorter/simpler.
Line 76: Line 76:
 
**Slide transition
 
**Slide transition
 
**Table
 
**Table
* A special activation of the sidebar is not necessary anymore. It works now out of the box.
+
* A special activation of the sidebar is not necessary anymore. It works now out of the box.
  
 
===SidebarWorkbench===
 
===SidebarWorkbench===
  
There is a Java extension for development and debugging of the sidebar. It can be downloaded [http://people.apache.org/~af/sidebar/0.7/SidebarWorkbench.oxt here]. Note that it writes a log file to <code>/tmp/sidebar.log</code>. On Windows without cygwin this may not work. Do not use the developer builds for important documents: there may be dragons (aka severe bugs).
+
There is a Java extension for development and debugging of the sidebar. It can be downloaded [http://people.apache.org/~af/sidebar/0.7/SidebarWorkbench.oxt here]. Note that it writes a log file to <code>/tmp/sidebar.log</code>. On Windows without cygwin this may not work. Do not use the developer builds for important documents: there may be dragons (aka severe bugs).
  
 
On Windows and Linux you can use it to
 
On Windows and Linux you can use it to
 
# add some dummy decks and panels to the sidebar.
 
# add some dummy decks and panels to the sidebar.
# monitor the current context. It is displayed in a panel in the Properties deck.
+
# monitor the current context. It is displayed in a panel in the Properties deck.
 
# modify the look of the sidebar with an external Java dialog called "Theme Dialog".
 
# modify the look of the sidebar with an external Java dialog called "Theme Dialog".
  
 
The "Theme Dialog" has three sections:
 
The "Theme Dialog" has three sections:
;Presets: Ten buttons let you choose between the nine themes proposed on [[AOO_UX_Design_Exploration_-_Task_Pane_Content_Panel_-_User_Interface_Design_Proposals|this UX page]]. A tenth button activates a theme that is similar to the original Symphony sidebar.
+
;Presets: Ten buttons let you choose between the nine themes proposed on [[AOO_UX_Design_Exploration_-_Task_Pane_Content_Panel_-_User_Interface_Design_Proposals|this UX page]]. A tenth button activates a theme that is similar to the original Symphony sidebar.
;Options: More fine grained options for changing the panel title bar background (normal, dark), the panel background (normal, white), use of Symphony icons, use of system colors (not yet fully implemented), use of the high contrast mode color scheme. The later does not activate the high contrast mode. It is just a quick way to activate the color scheme.
+
;Options: More fine grained options for changing the panel title bar background (normal, dark), the panel background (normal, white), use of Symphony icons, use of system colors (not yet fully implemented), use of the high contrast mode color scheme. The later does not activate the high contrast mode. It is just a quick way to activate the color scheme.
;Properties: A list of all the properties in the sidebar theme XPropertySet that are evaluated for the look of the sidebar. Editing is not (yet) possible.
+
;Properties: A list of all the properties in the sidebar theme XPropertySet that are evaluated for the look of the sidebar. Editing is not (yet) possible.
  
 
==Glossary==
 
==Glossary==
Work in progress. Comments are welcome.
+
Work in progress. Comments are welcome.
  
[[File:SidebarNames.png|thumb|200px|Schematic overview of sidebar components. Location of elements do not reflect UX design.]]
+
[[File:SidebarNames.png|thumb|200px|Schematic overview of sidebar components. Location of elements do not reflect UX design.]]
 
;sidebar: Name of the feature and name of the control including all its components (icon bar, content panels).
 
;sidebar: Name of the feature and name of the control including all its components (icon bar, content panels).
 
:Also known as task pane(l) or tool pane(l)
 
:Also known as task pane(l) or tool pane(l)
;tab bar: Similar to a vertical tool bar. Clicking on buttons switches between sidebar decks.
+
;tab bar: Similar to a vertical tool bar. Clicking on buttons switches between sidebar decks.
;deck: Contains one or more content panels. Only one deck is visible at any one time.
+
;deck: Contains one or more content panels. Only one deck is visible at any one time.
 
;content panel: Displays information about the document and/or provides the means for document modification.
 
;content panel: Displays information about the document and/or provides the means for document modification.
 
:Each content panel focuses on one topic like font, table or shape properties.
 
:Each content panel focuses on one topic like font, table or shape properties.
Line 113: Line 113:
 
The sidebar consists of two major components:
 
The sidebar consists of two major components:
 
*The buttons in the vertical tab bar on the right switch manually between sidebar decks.
 
*The buttons in the vertical tab bar on the right switch manually between sidebar decks.
*The content area contains a two-tier hierarchy of deck and content panels. There is exactly one deck visible at any one time. It contains one or more content panels. A content panel can be displayed expanded or collapsed.
+
*The content area contains a two-tier hierarchy of deck and content panels. There is exactly one deck visible at any one time. It contains one or more content panels. A content panel can be displayed expanded or collapsed.
  
The set of visible deck and content panels changes when a context change is broadcast. Context changes occur for example when in Writer the cursor is moved from text into a table or when in Impress text editing of a shape is activated.
+
The set of visible deck and content panels changes when a context change is broadcast. Context changes occur for example when in Writer the cursor is moved from text into a table or when in Impress text editing of a shape is activated.
  
 
Decks and context panels are specified via configuration and UNO interfaces and thus can be implemented not only in the AOO core code but also by extensions.
 
Decks and context panels are specified via configuration and UNO interfaces and thus can be implemented not only in the AOO core code but also by extensions.
Line 142: Line 142:
 
===Content panels===
 
===Content panels===
  
Decks and content panels are specified via the configuration. The
+
Decks and content panels are specified via the configuration. The
 
new Sidebar.xcs defines schemas for decks and content panels that
 
new Sidebar.xcs defines schemas for decks and content panels that
 
contain:
 
contain:
Line 148: Line 148:
 
* Context matcher: decks and panels are displayed only for matching contexts
 
* Context matcher: decks and panels are displayed only for matching contexts
 
* Icons for normal and high-contrast mode.
 
* Icons for normal and high-contrast mode.
* Oder index. Smaller is up, larger is down.
+
* Oder index. Smaller is up, larger is down.
 
* Service/implementation name of the implementation.
 
* Service/implementation name of the implementation.
  
Line 211: Line 211:
 
**table design (I) [http://issues.apache.org/ooo/show_bug.cgi?id=121797 121797]
 
**table design (I) [http://issues.apache.org/ooo/show_bug.cgi?id=121797 121797]
 
*:sd/source/ui/propertypanel/tabledesignpage.cxx
 
*:sd/source/ui/propertypanel/tabledesignpage.cxx
**text (W,I,C/cell selected,C/(text (editing cell text)) (started) [http://issues.apache.org/ooo/show_bug.cgi?id=121798 121798]
+
**text (W,I,C/cell selected,C/(text (editing cell text)) (started) [http://issues.apache.org/ooo/show_bug.cgi?id=121798 121798] (Already assigned to zhengfan)
 
*:svx/source/propertypanel/textpropertypage.cxx
 
*:svx/source/propertypanel/textpropertypage.cxx
 
**wrap (W) [http://issues.apache.org/ooo/show_bug.cgi?id=121799 121799]
 
**wrap (W) [http://issues.apache.org/ooo/show_bug.cgi?id=121799 121799]
Line 244: Line 244:
 
==How to help==
 
==How to help==
  
The migration of the Symphony panels to OpenOffice is a lot of work. Here is how you can help.
+
The migration of the Symphony panels to OpenOffice is a lot of work. Here is how you can help.
  
 
===Introduction===
 
===Introduction===
The content in the sidebar is organized into decks, panels and tabs. There is always exactly one deck visible. It can contain one or more panels. Tabs are allow manual switching between decks.
+
The content in the sidebar is organized into decks, panels and tabs. There is always exactly one deck visible. It can contain one or more panels. Tabs are allow manual switching between decks.
In general the current deck and its panels is defined by the current context. A context consists of an identifier for the application and one identifier for the actual context like text editing, cursor in table, image editing and so on.
+
In general the current deck and its panels is defined by the current context. A context consists of an identifier for the application and one identifier for the actual context like text editing, cursor in table, image editing and so on.
  
  
Line 255: Line 255:
 
; registry : org/openoffice/Office/UI/Sidebar.xcs / Context
 
; registry : org/openoffice/Office/UI/Sidebar.xcs / Context
 
For the C++ implementation there is a enum wrapper that allows switch() statements:
 
For the C++ implementation there is a enum wrapper that allows switch() statements:
    sfx2/sidebar/EnumContext.hxx
+
  sfx2/sidebar/EnumContext.hxx
 
like this
 
like this
    void DoSomething (const EnumContext& rContext)
+
  void DoSomething (const EnumContext& rContext)
    {  
+
  {  
        switch (rContext.GetCombinedContext())
+
  switch (rContext.GetCombinedContext())
        {
+
  {
            case CombinedEnumContext(Application_Calc, Context_Cell):
+
  case CombinedEnumContext(Application_Calc, Context_Cell):
                ...
+
  ...
  
 
===Notification of context changes===
 
===Notification of context changes===
Line 270: Line 270:
 
;interface: com/sun/star/ui/XContextChangeEventMultiplexer.idl
 
;interface: com/sun/star/ui/XContextChangeEventMultiplexer.idl
 
There is a C++ convenience wrapper in svx:
 
There is a C++ convenience wrapper in svx:
    svx/inc/sidebar/ContextChangeEventMultiplexer.hxx
+
  svx/inc/sidebar/ContextChangeEventMultiplexer.hxx
 
that has a single static method:
 
that has a single static method:
    static void NotifyContextChange (
+
  static void NotifyContextChange (
        const cssu::Reference<css::frame::XController>& rxController,
+
  const cssu::Reference<css::frame::XController>& rxController,
        const ::sfx2::sidebar::EnumContext::Context eContext);
+
  const ::sfx2::sidebar::EnumContext::Context eContext);
 
It hides the messy instantiation of the UNO singleton and conversion of the parameters.
 
It hides the messy instantiation of the UNO singleton and conversion of the parameters.
 
The rxController is used for two things:
 
The rxController is used for two things:
Line 280: Line 280:
 
# Allow listeners to be notified only for context changes of a single view
 
# Allow listeners to be notified only for context changes of a single view
 
The eContext argument is defined in
 
The eContext argument is defined in
    sfx2/sidebar/EnumContext.hxx
+
  sfx2/sidebar/EnumContext.hxx
  
 
====Task====
 
====Task====
Line 288: Line 288:
 
====Tips====
 
====Tips====
 
Look for Update calls for SID_SVX_PROPERTY_CONTEXT
 
Look for Update calls for SID_SVX_PROPERTY_CONTEXT
    in sfx2/source/control/dispatch.cxx, SfxDispatcher::Update_Impl()
+
  in sfx2/source/control/dispatch.cxx, SfxDispatcher::Update_Impl()
    and sfx2/source/control/bindings.cxx, IMPL_LINK(SfxBindings, NextJob_Impl...)
+
  and sfx2/source/control/bindings.cxx, IMPL_LINK(SfxBindings, NextJob_Impl...)
and for calls to    
+
and for calls to  
    sfx2/source/view/viewfrm.cxx, SfxViewFrame::GetPropertyContextId()
+
  sfx2/source/view/viewfrm.cxx, SfxViewFrame::GetPropertyContextId()
  
 
====Examples====
 
====Examples====
  
 
Notification of start of text editing in Draw/Impress:
 
Notification of start of text editing in Draw/Impress:
    sd/source/ui/func/futext.cxx, FuText::DoExecute()
+
  sd/source/ui/func/futext.cxx, FuText::DoExecute()
  
 
Notification of Draw/Impress having been started:
 
Notification of Draw/Impress having been started:
    sd/source/ui/view/ViewShellBase.cxx, ViewShellBase::Activate()
+
  sd/source/ui/view/ViewShellBase.cxx, ViewShellBase::Activate()
  
 
===Creation of a panel factory===
 
===Creation of a panel factory===
 
Panels are created by factories via the <code>ui::XUIElementFactory</code> interface and its
 
Panels are created by factories via the <code>ui::XUIElementFactory</code> interface and its
    createUIElement(
+
  createUIElement(
        const ::rtl::OUString& rsResourceURL,
+
  const ::rtl::OUString& rsResourceURL,
        const ::cssu::Sequence<css::beans::PropertyValue>& rArguments)
+
  const ::cssu::Sequence<css::beans::PropertyValue>& rArguments)
 
method.
 
method.
 
====Task====
 
====Task====
Line 311: Line 311:
  
 
The sidebar calles the createUIElement() method with the these arguments:
 
The sidebar calles the createUIElement() method with the these arguments:
;ParentWindow: a awt::XWindow object that is to be used as parent window for any new windows created by the panel. Both size and location of this parent window are modified by the panel layouter of the current deck. A panel that wants to layout its controls manually has to listen for size changes of the parent window.
+
;ParentWindow: a awt::XWindow object that is to be used as parent window for any new windows created by the panel. Both size and location of this parent window are modified by the panel layouter of the current deck. A panel that wants to layout its controls manually has to listen for size changes of the parent window.
 
;Frame: the frame::XFrame object of the view for which the sidebar displays decks and panels.
 
;Frame: the frame::XFrame object of the view for which the sidebar displays decks and panels.
;SfxBindings: a pointer to an SfxBindings object (wrapped in a sal_uInt64) that can be used to create controls. This hack is intended as a temporary solution. It is desirable to replace it with a UNO based solution.
+
;SfxBindings: a pointer to an SfxBindings object (wrapped in a sal_uInt64) that can be used to create controls. This hack is intended as a temporary solution. It is desirable to replace it with a UNO based solution.
The panel factory is expected to create and return a ui::XUIElement object for a given URL. Create a new panel like this:
+
The panel factory is expected to create and return a ui::XUIElement object for a given URL. Create a new panel like this:
    if (sURL.equals("my/panel"))
+
  if (sURL.equals("my/panel"))
    {
+
  {
        Control* pPanelControl = new PanelControl(pParentWindow, xFrame, pBindings);
+
  Control* pPanelControl = new PanelControl(pParentWindow, xFrame, pBindings);
        return sfx2::sidebar::SidebarPanelBase::Create(
+
  return sfx2::sidebar::SidebarPanelBase::Create(
            rsResourceURL,
+
  rsResourceURL,
            xFrame,
+
  xFrame,
            pPanel);
+
  pPanel);
    }
+
  }
  
 
====Examples====
 
====Examples====
Line 329: Line 329:
  
 
===Creation of a panel control===
 
===Creation of a panel control===
The content of a panel is typically painted by an instantiation of the <code>vcl::Control</code> class. The <code>XUIElement</code> interface gives access to the <code>XWindow</code> component of the control via the <code>XUIElement::getWindow()</code> method.
+
The content of a panel is typically painted by an instantiation of the <code>vcl::Control</code> class. The <code>XUIElement</code> interface gives access to the <code>XWindow</code> component of the control via the <code>XUIElement::getWindow()</code> method.
  
 
====Task====
 
====Task====
Line 335: Line 335:
 
Implement the <code>XUIElement</code> interface and add it to a panel factory.
 
Implement the <code>XUIElement</code> interface and add it to a panel factory.
  
Choose a panel factory in the module where the new panel class will be located. Add support for the panel class to the <code>XUIElementFactory::createUIElement()</code> method.
+
Choose a panel factory in the module where the new panel class will be located. Add support for the panel class to the <code>XUIElementFactory::createUIElement()</code> method.
  
You can use the <code>sfx2::sidebar::SidebarPanelBase</code> class for taking care of the boiler plate code. Despite its name (which should be change) <code>SidebarPanelBase</code> is not a base class for the new panel class. Due to the design of the <code>XUIElement</code> interface (with its <code>XUIElement::getRealInterface()</code> and <code>XUIElement::getWindow()</code> methods) the <code>XUIElement</code> interface can be implemented independently from the actual panel control.
+
You can use the <code>sfx2::sidebar::SidebarPanelBase</code> class for taking care of the boiler plate code. Despite its name (which should be change) <code>SidebarPanelBase</code> is not a base class for the new panel class. Due to the design of the <code>XUIElement</code> interface (with its <code>XUIElement::getRealInterface()</code> and <code>XUIElement::getWindow()</code> methods) the <code>XUIElement</code> interface can be implemented independently from the actual panel control.
SidebarPanelBase implements the <code>XUIElement::getRealInterface()</code> to return itself. It implements the <code>XUIElement::getWindow()</code> to return the awt::XWindow interface of the panel control. <code>XUIElement::createAccessible()</code> is not yet implemented.
+
SidebarPanelBase implements the <code>XUIElement::getRealInterface()</code> to return itself. It implements the <code>XUIElement::getWindow()</code> to return the awt::XWindow interface of the panel control. <code>XUIElement::createAccessible()</code> is not yet implemented.
 
The <code>SidebarPanelBase</code> provides additional functionality:
 
The <code>SidebarPanelBase</code> provides additional functionality:
* Forwarding of context change events: It registers at the <code>ContextChangeEventMultiplexer</code> and forwards all relevant events to the panel control if it implements the ContextChangeReceiverInterface interface (which is a local class of SidebarPanelBase). It uses a
+
* Forwarding of context change events: It registers at the <code>ContextChangeEventMultiplexer</code> and forwards all relevant events to the panel control if it implements the ContextChangeReceiverInterface interface (which is a local class of SidebarPanelBase). It uses a
<code>dynamic_cast<></code> to check if the interface is supported. If it is <code>SidebarPanelBase</code> converts the event data to an <code>EnumContext</code> object and calls <code>ContextChangeReceiverInterface::HandleContextChange()</code>.
+
<code>dynamic_cast<></code> to check if the interface is supported. If it is <code>SidebarPanelBase</code> converts the event data to an <code>EnumContext</code> object and calls <code>ContextChangeReceiverInterface::HandleContextChange()</code>.
 
* A simple implementation of the <code>ui::XVerticalStackLayoutElement</code> interface that returns the current height of the control (<code>mpControl->GetSizePixel().Height()</code>).
 
* A simple implementation of the <code>ui::XVerticalStackLayoutElement</code> interface that returns the current height of the control (<code>mpControl->GetSizePixel().Height()</code>).
 
For the implementation or migration of the actual panel control see the following section.
 
For the implementation or migration of the actual panel control see the following section.
Line 351: Line 351:
 
===Migration of property pages===
 
===Migration of property pages===
  
The Symphony property pages represent much functionality that in AOO can be found in toolbars. That may explain the extensive use of ToolBox controls in the panels.
+
The Symphony property pages represent much functionality that in AOO can be found in toolbars. That may explain the extensive use of ToolBox controls in the panels.
  
 
====Task====
 
====Task====
 
* Migrate the panels listed in http://wiki.openoffice.org/wiki/AOO_Symphony_UX_Migration/Merge_Analysis_-_Task_Pane or come up with a better list.
 
* Migrate the panels listed in http://wiki.openoffice.org/wiki/AOO_Symphony_UX_Migration/Merge_Analysis_-_Task_Pane or come up with a better list.
* Locate the panel implementation in the Symphony code branch. Typical places are:
+
* Locate the panel implementation in the Symphony code branch. Typical places are:
 
** svx/source/propertypanel/
 
** svx/source/propertypanel/
 
** sw/source/ui/propertypanel/
 
** sw/source/ui/propertypanel/
Line 361: Line 361:
 
** sd/source/ui/propertypanel/
 
** sd/source/ui/propertypanel/
 
* Use <code>::sfx2::sidebar::SidebarPanelBase</code> and <code>::sfx2::sidebar::ControllerItem::ItemUpdateReceiverInterface</code>
 
* Use <code>::sfx2::sidebar::SidebarPanelBase</code> and <code>::sfx2::sidebar::ControllerItem::ItemUpdateReceiverInterface</code>
as base classes. These take care of registering at the <code>ContextChangeEventMultiplexer</code> and item controllers.
+
as base classes. These take care of registering at the <code>ContextChangeEventMultiplexer</code> and item controllers.
 
* Replace member declarations of controls with scoped_ptrs, so that the controls can be created by a factory and can have a different, derived type:
 
* Replace member declarations of controls with scoped_ptrs, so that the controls can be created by a factory and can have a different, derived type:
 
Replace
 
Replace
Line 370: Line 370:
 
The mpToolBoxIncDecBackground object is the background/border of the tool box control while mpToolBoxIncDec is the actual tool box object.
 
The mpToolBoxIncDecBackground object is the background/border of the tool box control while mpToolBoxIncDec is the actual tool box object.
 
Then, in the constructor replace
 
Then, in the constructor replace
  maToolBoxIncDec (this, SVX_RES(TB_INCREASE_DECREASE)),
+
  maToolBoxIncDec (this, SVX_RES(TB_INCREASE_DECREASE)),
 
with
 
with
 
   mpToolBoxIncDecBackground(ControlFactory::CreateToolBoxBackground(this)),
 
   mpToolBoxIncDecBackground(ControlFactory::CreateToolBoxBackground(this)),
 
   mpToolBoxIncDec(ControlFactory::CreateToolBox(
 
   mpToolBoxIncDec(ControlFactory::CreateToolBox(
      mpToolBoxIncDecBackground.get(),
+
  mpToolBoxIncDecBackground.get(),
      SVX_RES(TB_INCREASE_DECREASE))),
+
  SVX_RES(TB_INCREASE_DECREASE))),
  
 
* Handle context changes:
 
* Handle context changes:
 
Replace
 
Replace
    virtual void Init(PropertyContextType nContextId);
+
  virtual void Init(PropertyContextType nContextId);
 
with
 
with
    virtual void HandleContextChange (
+
  virtual void HandleContextChange (
        const ::sfx2::sidebar::EnumContext aContext);
+
  const ::sfx2::sidebar::EnumContext aContext);
 
In the implementation replace
 
In the implementation replace
    void SvxTextPropertyPage::Init(PropertyContextType nContextId)
+
  void SvxTextPropertyPage::Init(PropertyContextType nContextId)
    {
+
  {
        meContextType = nContextId;
+
  meContextType = nContextId;
        if( nContextId == PROPERTY_CONTEXT_SC_CELL || nContextId == PROPERTY_CONTEXT_SC_PIVOT ) //modified::add s
+
  if( nContextId == PROPERTY_CONTEXT_SC_CELL || nContextId == PROPERTY_CONTEXT_SC_PIVOT ) //modified::add s
 
with
 
with
    void TextPropertyPanel::HandleContextChange (
+
  void TextPropertyPanel::HandleContextChange (
        const ::sfx2::sidebar::EnumContext aContext)
+
  const ::sfx2::sidebar::EnumContext aContext)
    {
+
  {
        if (maContext == aContext)
+
  if (maContext == aContext)
        {
+
  {
            // Nothing to do.
+
  // Nothing to do.
            return;
+
  return;
        }
+
  }
        maContext = aContext;
+
  maContext = aContext;
        switch (maContext.GetCombinedContext())
+
  switch (maContext.GetCombinedContext())
        {
+
  {
            case CombinedEnumContext(Application_Calc, Context_Cell):
+
  case CombinedEnumContext(Application_Calc, Context_Cell):
            case CombinedEnumContext(Application_Calc, Context_Pivot):
+
  case CombinedEnumContext(Application_Calc, Context_Pivot):
 
The first lines (above the switch() statement) could be moved into the base class.
 
The first lines (above the switch() statement) could be moved into the base class.
 
* Make a similar replacement wherever meContextType is used in if() statements.
 
* Make a similar replacement wherever meContextType is used in if() statements.
* Replace the use of SfxPropertyPageController with ::sfx2::sidebar::ControllerItem. Controller items connect items (basically the model of toolbar buttons) and state change listeners (the panel that you are migrating).
+
* Replace the use of SfxPropertyPageController with ::sfx2::sidebar::ControllerItem. Controller items connect items (basically the model of toolbar buttons) and state change listeners (the panel that you are migrating).
 
In the header replace
 
In the header replace
  SfxPropertyPageController maFontNameControl;
+
  SfxPropertyPageController maFontNameControl;
 
with
 
with
  ::sfx2::sidebar::ControllerItem maFontNameControl;
+
  ::sfx2::sidebar::ControllerItem maFontNameControl;
 
In the constructor replace
 
In the constructor replace
    maFontNameControl (SID_ATTR_CHAR_FONT, this, GetBindings())
+
  maFontNameControl (SID_ATTR_CHAR_FONT, this, GetBindings())
 
with
 
with
    maFontNameControl (SID_ATTR_CHAR_FONT, *pBindings, *this)
+
  maFontNameControl (SID_ATTR_CHAR_FONT, *pBindings, *this)
  
 
Also transform
 
Also transform
    void SvxTextPropertyPage::StateChangedImpl(USHORT nSID, SfxItemState eState, const SfxPoolItem* pState)
+
  void SvxTextPropertyPage::StateChangedImpl(USHORT nSID, SfxItemState eState, const SfxPoolItem* pState)
 
into
 
into
    virtual void NotifyItemUpdate(
+
  virtual void NotifyItemUpdate(
        const sal_uInt16 nSId,
+
  const sal_uInt16 nSId,
        const SfxItemState eState,
+
  const SfxItemState eState,
        const SfxPoolItem* pState);
+
  const SfxPoolItem* pState);
 
to be informed of state changes.
 
to be informed of state changes.
  
Line 426: Line 426:
 
Where possible we should use the standard AOO icons (although in same places we should thing about replacing the AOO icons with Symphony icons).
 
Where possible we should use the standard AOO icons (although in same places we should thing about replacing the AOO icons with Symphony icons).
 
Find the uno command name and do a replacement like:
 
Find the uno command name and do a replacement like:
    maToolBoxIncDec.SetItemImage(TBI_INCREASE, Application::GetSettings().GetStyleSettings().GetHighContrastMode()? maImgIncreaseHigh : maImgIncrease);
+
  maToolBoxIncDec.SetItemImage(TBI_INCREASE, Application::GetSettings().GetStyleSettings().GetHighContrastMode()? maImgIncreaseHigh : maImgIncrease);
    maToolBoxIncDec.SetItemImage(TBI_DECREASE, Application::GetSettings().GetStyleSettings().GetHighContrastMode()? maImgDecreaseHigh : maImgDecrease);
+
  maToolBoxIncDec.SetItemImage(TBI_DECREASE, Application::GetSettings().GetStyleSettings().GetHighContrastMode()? maImgDecreaseHigh : maImgDecrease);
 
with
 
with
    mpToolBoxIncDec->SetItemImage(TBI_INCREASE, GetIcon(A2S(".uno:Grow")));
+
  mpToolBoxIncDec->SetItemImage(TBI_INCREASE, GetIcon(A2S(".uno:Grow")));
    mpToolBoxIncDec->SetItemImage(TBI_DECREASE, GetIcon(A2S(".uno:Shrink")));
+
  mpToolBoxIncDec->SetItemImage(TBI_DECREASE, GetIcon(A2S(".uno:Shrink")));
 
The GetIcon() method takes care (hopefully) of the high contrast mode.
 
The GetIcon() method takes care (hopefully) of the high contrast mode.
* One source file may contain more than one class definition. It is good practice to separate these into their own files. And it makes it easier for others to work on other panels in the same source file.
+
* One source file may contain more than one class definition. It is good practice to separate these into their own files. And it makes it easier for others to work on other panels in the same source file.
 
* Use namespaces instead of the Svx class prefixes, ie use svx::sidebar namespace (or sw::sidebar, etc) and get rid of the Svx class prefixes.
 
* Use namespaces instead of the Svx class prefixes, ie use svx::sidebar namespace (or sw::sidebar, etc) and get rid of the Svx class prefixes.
  
Line 443: Line 443:
 
==Existing implementation==
 
==Existing implementation==
  
Not all the API design and implementation work has to be started from scratch. There several parts that can be used/reused/adapted.
+
Not all the API design and implementation work has to be started from scratch. There several parts that can be used/reused/adapted.
  
 
===In main/sd/===
 
===In main/sd/===
The [[drawing framework]] is used for the Impress taskpane, all Impress views and the slide show. A tree of URLs (called a configuration) defines the different layers of containers (windows) and views (taskpane panels). SD views only modify a configuration, update and synchronization of the associated view shells is left to the ConfigurationController.
+
The [[drawing framework]] is used for the Impress taskpane, all Impress views and the slide show. A tree of URLs (called a configuration) defines the different layers of containers (windows) and views (taskpane panels). SD views only modify a configuration, update and synchronization of the associated view shells is left to the ConfigurationController.
  
Contextual changes of tool bars are handled in SD in a single place by the ToolBarManager. It receives notifications about context changes by registering as listener at the EventMultiplexer.
+
Contextual changes of tool bars are handled in SD in a single place by the ToolBarManager. It receives notifications about context changes by registering as listener at the EventMultiplexer.
  
 
Example:
 
Example:
 
When an Impress shape enters text edit mode then sd::View sends an
 
When an Impress shape enters text edit mode then sd::View sends an
event to the EventMultiplexer. That forwards the event to the
+
event to the EventMultiplexer. That forwards the event to the
 
ToolBarManager.
 
ToolBarManager.
 
The ToolBarManager checks its set of rules, finds the one that
 
The ToolBarManager checks its set of rules, finds the one that
Line 484: Line 484:
 
===In main/svtools/ and main/sfx2/===
 
===In main/svtools/ and main/sfx2/===
  
The unfinished implementation of an office wide toolpane with Symphony like functionality can be found in svtools/source/toolpanel/ and sfx2/source/dialog/taskpane/. See [[Framework/Article/Tool Panels Internals]] for details.
+
The unfinished implementation of an office wide toolpane with Symphony like functionality can be found in svtools/source/toolpanel/ and sfx2/source/dialog/taskpane/. See [[Framework/Article/Tool Panels Internals]] for details.
  
 
===Existing API (main/offapi/)===
 
===Existing API (main/offapi/)===
Line 499: Line 499:
  
 
Find application specific content panels in sw/source/ui/propertypanel, sc/source/ui/propertypanel, sd/source/ui/propertypanel.
 
Find application specific content panels in sw/source/ui/propertypanel, sc/source/ui/propertypanel, sd/source/ui/propertypanel.
In these directories the files propertydlg.cxx defines the set of panels that are to be displayed. These lists are hardcoded and can not be modified by extensions.
+
In these directories the files propertydlg.cxx defines the set of panels that are to be displayed. These lists are hardcoded and can not be modified by extensions.
  
Painting of control backgrounds is also hardcoded. Look for instance at svx/source/propertypanel/paragraphpropertypage.cxx and search for calls to DrawGradient(). Colors for the background gradients are defined in every file that paints button backgrounds.
+
Painting of control backgrounds is also hardcoded. Look for instance at svx/source/propertypanel/paragraphpropertypage.cxx and search for calls to DrawGradient(). Colors for the background gradients are defined in every file that paints button backgrounds.

Revision as of 10:54, 27 February 2013

The sidebar (working title) is a new feature likely to be in the 4.0 release. It combines ideas and code from both the Symphony sidebar and the OpenOffice Impress task pane.

The UX part of the work is described on another page. This page focuses on the API design and implementation.

Help in whatever form (writing code, designing the UI, testing) is welcome.

Status

  • Impress panels are migrated.
  • Deck title bar has closer that hides deck but leaves TabBar visible.
  • Panel title bar supports button that opens detail dialog with more options.
  • Deck shows vertical scroll bar when not all panel fit into deck.
  • Developer builds are available, see below

Current screenshots:

19. Feb. 2013: Impress panels have been migrated (left). The closer in the deck title bar hides the deck but leaves the tab bar visible (right). The three master page panels are now first class citizens in the sidebar world. That makes it possible to reorder them or show/hide them independently.

Sidebar-2013-02-19-a.png, Sidebar-2013-02-19-c.png.

18. Jan. 2013: Migration of Symphony text properties panel (work in progress). With original Symphony icons (far left) and OpenOffice icons (all other) and with different colors for panel titles and panel backgrounds:

Sidebar-2013-01-18-a.png, Sidebar-2013-01-18-b.png, Sidebar-2013-01-18-c.png, Sidebar-2013-01-18-d.png

15. Jan. 2013: Controls in sidebar pane are themable. Click one of the preset buttons in the Java theme dialog to see one of the proposed themes applied to a working panel:

Sidebar-2013-01-15.png

Past activities:

  • Created a new sidebar that at this moment can display panels that are provided
    • by a new extension (see above),
    • by already existing extensions using the XUIElementProvider interface family,
    • by Impress (but there are still severe painting problems).
  • The sidebar menu already works. It is almost identical to its Symphony counterpart with one additional entry for docking or undocking the sidebar.
  • Individual panels can be collapsed or expanded.
  • The older and unfinished sidebar support that was done when OpenOffice was developed by Oracle is still active as a reference.
  • Designed API (new services and interfaces) and configuration for declaration of sidebar decks and panels and notification of context changes.
  • Initial implementation as test of the design. Most of the changes can be found in [1] and [2].
  • Migration of first Symphony panel is progressing well. Simple theming is already in place.
  • Theme is represented as XPropertySet. See screenshot below for a Java extension that a) displays the current context in a sidebar panel and that b) provides a dialog for visualizing the different property values and allows simple switching between theme presets.

Resources

Developer Builds

Current version is 0.7 from Februray, 22nd, 2013 for

All builds are archives, to avoid accidental installation. On Windows there seems to be trouble with the name of the top level directory ("Apache_OpenOffice_3.5.0 ..."). Possible fixes: - Copy the content of that directory to some other place and run from there - Rename to something shorter/simpler.


Changed since version 0.6:

  • Closer of deck title bar closes the deck but leaves the tab bar visible.
  • The Impress panels are now available:
    • Layouts
    • Master pages (all, recent, used)
    • Custom animation
    • Slide transition
    • Table
  • A special activation of the sidebar is not necessary anymore. It works now out of the box.

SidebarWorkbench

There is a Java extension for development and debugging of the sidebar. It can be downloaded here. Note that it writes a log file to /tmp/sidebar.log. On Windows without cygwin this may not work. Do not use the developer builds for important documents: there may be dragons (aka severe bugs).

On Windows and Linux you can use it to

  1. add some dummy decks and panels to the sidebar.
  2. monitor the current context. It is displayed in a panel in the Properties deck.
  3. modify the look of the sidebar with an external Java dialog called "Theme Dialog".

The "Theme Dialog" has three sections:

Presets
Ten buttons let you choose between the nine themes proposed on this UX page. A tenth button activates a theme that is similar to the original Symphony sidebar.
Options
More fine grained options for changing the panel title bar background (normal, dark), the panel background (normal, white), use of Symphony icons, use of system colors (not yet fully implemented), use of the high contrast mode color scheme. The later does not activate the high contrast mode. It is just a quick way to activate the color scheme.
Properties
A list of all the properties in the sidebar theme XPropertySet that are evaluated for the look of the sidebar. Editing is not (yet) possible.

Glossary

Work in progress. Comments are welcome.

Schematic overview of sidebar components. Location of elements do not reflect UX design.
sidebar
Name of the feature and name of the control including all its components (icon bar, content panels).
Also known as task pane(l) or tool pane(l)
tab bar
Similar to a vertical tool bar. Clicking on buttons switches between sidebar decks.
deck
Contains one or more content panels. Only one deck is visible at any one time.
content panel
Displays information about the document and/or provides the means for document modification.
Each content panel focuses on one topic like font, table or shape properties.
There may be more than one content panel in a deck.
Examples are the task panels of the Impress task pane or the property views of the Symphony sidebar.
title bar
Displays the title for the current sidebar deck.
Can contain a closer button.
content panel title
Displays the title for one content panel. Optional when there is only one content panel.
configuration menu button
Opens a popup menu that allows switching between decks and also allows the activation and deactivation (tab is not shown) of decks.

Implemenation design

The sidebar consists of two major components:

  • The buttons in the vertical tab bar on the right switch manually between sidebar decks.
  • The content area contains a two-tier hierarchy of deck and content panels. There is exactly one deck visible at any one time. It contains one or more content panels. A content panel can be displayed expanded or collapsed.

The set of visible deck and content panels changes when a context change is broadcast. Context changes occur for example when in Writer the cursor is moved from text into a table or when in Impress text editing of a shape is activated.

Decks and context panels are specified via configuration and UNO interfaces and thus can be implemented not only in the AOO core code but also by extensions.


Context change notification

Context changes are broadcast via the new ui::ContextSwitchEventMultiplexer singleton (which is based on the equally new ui::EventMultiplexer service).

Context change broadcasts have to be manually inserted into application code.

Notifications about context changes are restricted to single views by using the XController as selector: an XController object is passed to ui::EventMultiplexer::addEventListener() and ui::EventMultiplexer::broadcastEvent() methods.

The sidebars (there is one per document window) listen for context change notifications and rearrange the set of visible decks and panels according to the configuration entries for each deck and panel.

There will be a predefined standard set of contexts but extensions can provide decks and panels for new contexts and can also notify context changes for them.

Content panels

Decks and content panels are specified via the configuration. The new Sidebar.xcs defines schemas for decks and content panels that contain:

  • UI title
  • Context matcher: decks and panels are displayed only for matching contexts
  • Icons for normal and high-contrast mode.
  • Oder index. Smaller is up, larger is down.
  • Service/implementation name of the implementation.

Legacy addons are find in the application specific WindowState configuration files and instaniated via the existing ui::UIElementFactoryManager infrastructure is used.

Sidebar

It is the responsibility of the sidebar to display the right set of content panels for the current combination of application (writer, calc, impress, draw, base) and context (eg text-editing, table-is-selected).

The visible set of deck and content panels changes on three occasions:

  1. A context change is notified via the ContextSwitchEventMultiplexer
  2. User clicks on one of the buttons in the sidebar tab bar.
  3. Explicit requests to show a certain deck or panel (used by Impress to show the layout panel when the user opens the page context menu and clicks Slide->Slide Layout)


Implementation Work

Using bugzilla issue 121420.

The list of open and done parts of the sidebar implementation are (to be expanded and color coded):

Content Change Notification

Decks and content panels

  • Configuration (all done)
  • Implement manager for decks and panels (done)
  • Example code for testing and as tutorial (work in progress)
  • Migration of Symphony decks and content panels for Writer(W), Calc(C), Impress(I) (see proposal)
    sc/source/ui/propertypanel/alignmentpropertypage.cxx
    svx/source/propertypanel/areapropertypage.cxx
    sc/source/ui/propertypanel/appearpropertypage.cxx
    svx/source/propertypanel/graphicpropertypage.cxx
    svx/source/propertypanel/linepropertypage.cxx
    sc/source/ui/propertypanel/numformatpropertypage.cxx
    sw/source/ui/propertypanel/pagepropertypage.cxx
    svx/source/propertypanel/paragraphpropertypage.cxx
    • position and size (I,C/chart and media,W/graphic,C/(text, line, shape and graphic),W/(text, line, shape)) 121795
    svx/source/propertypanel/posizepropertypage.cxx
    sd/source/ui/propertypanel/pagelayoutpage.cxx
    sd/source/ui/propertypanel/tabledesignpage.cxx
    • text (W,I,C/cell selected,C/(text (editing cell text)) (started) 121798 (Already assigned to zhengfan)
    svx/source/propertypanel/textpropertypage.cxx
    sw/source/ui/propertypanel/wrappropertypage.cxx
  • Migration of AOO decks and content panels (see proposal)
    • Style List
    • Clipart
    • Navigator
    • Functions
    • Data Pilot
  • Migration of Impress panels (see proposal) (done)
    • Slide Templates/Master Slides
    • Custom Animation/Animation Effects
    • Slide Transition

Sidebar

  • Tab bar (done)
  • Tabs (done)
    • Icons and high contrast icons, read from configuration (done)
    • Test with internal and external (extension) code (done)
  • Title bars for decks and content panels (done)
  • Outer layouting of content panels (done)
    • Distribution of vertical space between panels
    • Collaps and expand panels (done)
  • Management of context changes (done)
    • Read specification of decks and content panels from configuration (done)
    • Connect to EventMultiplexer and listen for content changes
    • Update visible deck and panels on context change
  • Dockable child window as container of sidebar
  • Configuration menu (done)

How to help

The migration of the Symphony panels to OpenOffice is a lot of work. Here is how you can help.

Introduction

The content in the sidebar is organized into decks, panels and tabs. There is always exactly one deck visible. It can contain one or more panels. Tabs are allow manual switching between decks. In general the current deck and its panels is defined by the current context. A context consists of an identifier for the application and one identifier for the actual context like text editing, cursor in table, image editing and so on.


Both UNO API and configuration represent a context with two strings:

UNO 
com/sun/star/ui/ContextChangeEventObject
registry 
org/openoffice/Office/UI/Sidebar.xcs / Context

For the C++ implementation there is a enum wrapper that allows switch() statements:

 sfx2/sidebar/EnumContext.hxx

like this

 void DoSomething (const EnumContext& rContext)
 { 
 switch (rContext.GetCombinedContext())
 {
 case CombinedEnumContext(Application_Calc, Context_Cell):
 ...

Notification of context changes

Notification of context changes is done via one single event multiplexer that is used by all documents and views:

service
com/sun/star/ui/ContextChangeEventMultiplexer.idl
interface
com/sun/star/ui/XContextChangeEventMultiplexer.idl

There is a C++ convenience wrapper in svx:

 svx/inc/sidebar/ContextChangeEventMultiplexer.hxx

that has a single static method:

 static void NotifyContextChange (
 const cssu::Reference<css::frame::XController>& rxController,
 const ::sfx2::sidebar::EnumContext::Context eContext);

It hides the messy instantiation of the UNO singleton and conversion of the parameters. The rxController is used for two things:

  1. Determine the application and fill in the right string/identifier in the resulting context change event.
  2. Allow listeners to be notified only for context changes of a single view

The eContext argument is defined in

 sfx2/sidebar/EnumContext.hxx

Task

  • Add calls to ContextChangeEventMultiplexer::NotifyContextChange() whenever a relevant context change occurs so that the sidebar can display the appropriate deck and panels.
  • Add missing contexts to EnumContext.hxx and Sidebar.xcs and provide a word or two of explanation.

Tips

Look for Update calls for SID_SVX_PROPERTY_CONTEXT

 in sfx2/source/control/dispatch.cxx, SfxDispatcher::Update_Impl()
 and sfx2/source/control/bindings.cxx, IMPL_LINK(SfxBindings, NextJob_Impl...)

and for calls to

 sfx2/source/view/viewfrm.cxx, SfxViewFrame::GetPropertyContextId()

Examples

Notification of start of text editing in Draw/Impress:

 sd/source/ui/func/futext.cxx, FuText::DoExecute()

Notification of Draw/Impress having been started:

 sd/source/ui/view/ViewShellBase.cxx, ViewShellBase::Activate()

Creation of a panel factory

Panels are created by factories via the ui::XUIElementFactory interface and its

 createUIElement(
 const ::rtl::OUString& rsResourceURL,
 const ::cssu::Sequence<css::beans::PropertyValue>& rArguments)

method.

Task

Implement the ui::XUIElementFactory interface.

The sidebar calles the createUIElement() method with the these arguments:

ParentWindow
a awt::XWindow object that is to be used as parent window for any new windows created by the panel. Both size and location of this parent window are modified by the panel layouter of the current deck. A panel that wants to layout its controls manually has to listen for size changes of the parent window.
Frame
the frame::XFrame object of the view for which the sidebar displays decks and panels.
SfxBindings
a pointer to an SfxBindings object (wrapped in a sal_uInt64) that can be used to create controls. This hack is intended as a temporary solution. It is desirable to replace it with a UNO based solution.

The panel factory is expected to create and return a ui::XUIElement object for a given URL. Create a new panel like this:

 if (sURL.equals("my/panel"))
 {
 Control* pPanelControl = new PanelControl(pParentWindow, xFrame, pBindings);
 return sfx2::sidebar::SidebarPanelBase::Create(
 rsResourceURL,
 xFrame,
 pPanel);
 }

Examples

See svx/source/sidebar/PanelFactory.cxx


Creation of a panel control

The content of a panel is typically painted by an instantiation of the vcl::Control class. The XUIElement interface gives access to the XWindow component of the control via the XUIElement::getWindow() method.

Task

Implement the XUIElement interface and add it to a panel factory.

Choose a panel factory in the module where the new panel class will be located. Add support for the panel class to the XUIElementFactory::createUIElement() method.

You can use the sfx2::sidebar::SidebarPanelBase class for taking care of the boiler plate code. Despite its name (which should be change) SidebarPanelBase is not a base class for the new panel class. Due to the design of the XUIElement interface (with its XUIElement::getRealInterface() and XUIElement::getWindow() methods) the XUIElement interface can be implemented independently from the actual panel control. SidebarPanelBase implements the XUIElement::getRealInterface() to return itself. It implements the XUIElement::getWindow() to return the awt::XWindow interface of the panel control. XUIElement::createAccessible() is not yet implemented. The SidebarPanelBase provides additional functionality:

  • Forwarding of context change events: It registers at the ContextChangeEventMultiplexer and forwards all relevant events to the panel control if it implements the ContextChangeReceiverInterface interface (which is a local class of SidebarPanelBase). It uses a

dynamic_cast<> to check if the interface is supported. If it is SidebarPanelBase converts the event data to an EnumContext object and calls ContextChangeReceiverInterface::HandleContextChange().

  • A simple implementation of the ui::XVerticalStackLayoutElement interface that returns the current height of the control (mpControl->GetSizePixel().Height()).

For the implementation or migration of the actual panel control see the following section.

Example

See svx/source/sidebar/PanelFactory.cxx for the use of the SidebarPanelBase class. See svx/source/sidebar/text/TextPropertyPanel.cxx for the implementation of the HandleContextChange method.

Migration of property pages

The Symphony property pages represent much functionality that in AOO can be found in toolbars. That may explain the extensive use of ToolBox controls in the panels.

Task

  • Migrate the panels listed in http://wiki.openoffice.org/wiki/AOO_Symphony_UX_Migration/Merge_Analysis_-_Task_Pane or come up with a better list.
  • Locate the panel implementation in the Symphony code branch. Typical places are:
    • svx/source/propertypanel/
    • sw/source/ui/propertypanel/
    • sc/source/ui/propertypanel/
    • sd/source/ui/propertypanel/
  • Use ::sfx2::sidebar::SidebarPanelBase and ::sfx2::sidebar::ControllerItem::ItemUpdateReceiverInterface

as base classes. These take care of registering at the ContextChangeEventMultiplexer and item controllers.

  • Replace member declarations of controls with scoped_ptrs, so that the controls can be created by a factory and can have a different, derived type:

Replace

 ToolBox maToolBoxIncDec;

with

 ::boost::scoped_ptr<Window> mpToolBoxIncDecBackground;
 ::boost::scoped_ptr<ToolBox> mpToolBoxIncDec;

The mpToolBoxIncDecBackground object is the background/border of the tool box control while mpToolBoxIncDec is the actual tool box object. Then, in the constructor replace

 maToolBoxIncDec (this, SVX_RES(TB_INCREASE_DECREASE)),

with

 mpToolBoxIncDecBackground(ControlFactory::CreateToolBoxBackground(this)),
 mpToolBoxIncDec(ControlFactory::CreateToolBox(
 mpToolBoxIncDecBackground.get(),
 SVX_RES(TB_INCREASE_DECREASE))),
  • Handle context changes:

Replace

 virtual void Init(PropertyContextType nContextId);

with

 virtual void HandleContextChange (
 const ::sfx2::sidebar::EnumContext aContext);

In the implementation replace

 void SvxTextPropertyPage::Init(PropertyContextType nContextId)
 {
 meContextType = nContextId;
 if( nContextId == PROPERTY_CONTEXT_SC_CELL || nContextId == PROPERTY_CONTEXT_SC_PIVOT ) //modified::add s

with

 void TextPropertyPanel::HandleContextChange (
 const ::sfx2::sidebar::EnumContext aContext)
 {
 if (maContext == aContext)
 {
 // Nothing to do.
 return;
 }
 maContext = aContext;
 switch (maContext.GetCombinedContext())
 {
 case CombinedEnumContext(Application_Calc, Context_Cell):
 case CombinedEnumContext(Application_Calc, Context_Pivot):

The first lines (above the switch() statement) could be moved into the base class.

  • Make a similar replacement wherever meContextType is used in if() statements.
  • Replace the use of SfxPropertyPageController with ::sfx2::sidebar::ControllerItem. Controller items connect items (basically the model of toolbar buttons) and state change listeners (the panel that you are migrating).

In the header replace

 SfxPropertyPageController maFontNameControl;

with

 ::sfx2::sidebar::ControllerItem maFontNameControl;

In the constructor replace

 maFontNameControl (SID_ATTR_CHAR_FONT, this, GetBindings())

with

 maFontNameControl (SID_ATTR_CHAR_FONT, *pBindings, *this)

Also transform

 void SvxTextPropertyPage::StateChangedImpl(USHORT nSID, SfxItemState eState, const SfxPoolItem* pState)

into

 virtual void NotifyItemUpdate(
 const sal_uInt16 nSId,
 const SfxItemState eState,
 const SfxPoolItem* pState);

to be informed of state changes.

  • Replace icons

Where possible we should use the standard AOO icons (although in same places we should thing about replacing the AOO icons with Symphony icons). Find the uno command name and do a replacement like:

 maToolBoxIncDec.SetItemImage(TBI_INCREASE, Application::GetSettings().GetStyleSettings().GetHighContrastMode()? maImgIncreaseHigh : maImgIncrease);
 maToolBoxIncDec.SetItemImage(TBI_DECREASE, Application::GetSettings().GetStyleSettings().GetHighContrastMode()? maImgDecreaseHigh : maImgDecrease);

with

 mpToolBoxIncDec->SetItemImage(TBI_INCREASE, GetIcon(A2S(".uno:Grow")));
 mpToolBoxIncDec->SetItemImage(TBI_DECREASE, GetIcon(A2S(".uno:Shrink")));

The GetIcon() method takes care (hopefully) of the high contrast mode.

  • One source file may contain more than one class definition. It is good practice to separate these into their own files. And it makes it easier for others to work on other panels in the same source file.
  • Use namespaces instead of the Svx class prefixes, ie use svx::sidebar namespace (or sw::sidebar, etc) and get rid of the Svx class prefixes.

Tips

Do the Draw/Impress panels last, these are more complicated than the others due to their use of an Impress specific framework.

Examples

See svx/source/sidebar/text/TextPropertyPanel.cxx in the sidebar branch for the first migrated panel.

Existing implementation

Not all the API design and implementation work has to be started from scratch. There several parts that can be used/reused/adapted.

In main/sd/

The drawing framework is used for the Impress taskpane, all Impress views and the slide show. A tree of URLs (called a configuration) defines the different layers of containers (windows) and views (taskpane panels). SD views only modify a configuration, update and synchronization of the associated view shells is left to the ConfigurationController.

Contextual changes of tool bars are handled in SD in a single place by the ToolBarManager. It receives notifications about context changes by registering as listener at the EventMultiplexer.

Example: When an Impress shape enters text edit mode then sd::View sends an event to the EventMultiplexer. That forwards the event to the ToolBarManager. The ToolBarManager checks its set of rules, finds the one that activates the text edit tool bar and replaces the current context bar with the text edit bar.



Screenshots from the developer snapshots. In all three screenshots mouse is over the third button from the top in the sidebar, button above is selected. Click to enlarge.

Linux: screenshot-linux-sidebar-small.png Mac: screenshot-mac-sidebar-small.png Windows: screenshot-windows-sidebar-small.png

Detail views of regular toolbar buttons. Right "abc" button is selected, mouse is over left "abc" button.

Linux: screenshot-linux-toolbar.png Mac: screenshot-mac-toolbar.png Windows: screenshot-windows-toolbar-detail.png

Examples of toolbars in other applications:

Linux (file explorer): screenshot-linux-explorer-small.png Mac (Garageband): screenshot-mac-GarageBand-small.png Windows (File Explorer): screenshot-windows-Explorer-small.png


For comparison here is a screenshot from Symphony (on Windows):

screenshot-sidebar-symphony.png


In main/svtools/ and main/sfx2/

The unfinished implementation of an office wide toolpane with Symphony like functionality can be found in svtools/source/toolpanel/ and sfx2/source/dialog/taskpane/. See Framework/Article/Tool Panels Internals for details.

Existing API (main/offapi/)

XUIElement and XToolPanel from com::sun::star::ui provide an API abstraction of the toolpanel.

It is already possible to provide new tool panels from an extension.


In the symphony branch

The sidebar is implemented in sfx2/source/propertypanel. Base functionality for sidebar and content panes can be found in svx/source/propertypanel.

Find application specific content panels in sw/source/ui/propertypanel, sc/source/ui/propertypanel, sd/source/ui/propertypanel. In these directories the files propertydlg.cxx defines the set of panels that are to be displayed. These lists are hardcoded and can not be modified by extensions.

Painting of control backgrounds is also hardcoded. Look for instance at svx/source/propertypanel/paragraphpropertypage.cxx and search for calls to DrawGradient(). Colors for the background gradients are defined in every file that paints button backgrounds.

Personal tools