Page 1 of 1

[Solved] Sidebar for Developers

PostPosted: Mon Jun 10, 2013 8:46 pm
by RGB
Andre Fischer, author of the new and improved sidebar that will be part of AOO 4.0 and later of other related projects, started a wiki page explaining how to create a custom panel for the new sidebar. Here is the announcement on the dev mailing list:

Andre Fischer wrote:Hi,

I have created a new Wiki page for developers how want to add new panels to the sidebar [1]. At the moment it focuses on the explanation of a demo extension that with some Java code shows an analog clock in a new "Tools" deck. The part that explains how a sidebar panel extension works in general has to be extended in the future. But it's a start.

Until I find a better place, maybe in the SDK, the source code (as Eclipse project) [3] and OXT file [2] can be found on my apache people directory.

I also have a question for those of you with a better understanding of Mediawiki: do we have an extension that allows syntax highlighting of XML and Java code snippets?



NOTE: maybe make this thread sticky? It will be useful for extension developers.

Re: Sidebar for Developers

PostPosted: Mon Jun 10, 2013 8:59 pm
by Villeroy
How do you run the alpha snapshots? Do you have a physical or virtual machine for testing? On my Debian based system Apache_OpenOffice_4.0.0_Linux_x86-64_install-deb_en-US.tar.gz fails to install AND it destroys the installed AOO 3.4.1.

Re: Sidebar for Developers

PostPosted: Mon Jun 10, 2013 9:15 pm
by RGB
You can test the dev snapshots without installing them just unpacking the deb or rpm files. See here for more details

[Tutorial] Installing Apache OpenOffice on GNU/Linux

As alternative, you can get the last automatic build from the build bot in "archive" format,


Just unpack and use, the scripts to launch each app are on


(the new "one layer" design is a lot easier... ;) )

These arc builds do not need to be installed and don't use the profile of the installed version.

Re: Sidebar for Developers

PostPosted: Mon Jun 10, 2013 10:36 pm
by Villeroy
Thank you very much.

Re: Sidebar for Developers

PostPosted: Tue Jun 11, 2013 11:02 am
by hanya
If someone want to make own sidebar that keeps own data, you have to store the data into somewhere else out of your component bound to the lifetime of your component that implements css.ui.XUIElement.
See Bug 122406 for more detail.

Re: Sidebar for Developers

PostPosted: Tue Jun 11, 2013 6:56 pm
by hanya
As described in the page, the sidebar require own UNO-component, so simple macros can not provide it.
Few weeks ago, I made simple helper extension that provides the component helps the macro can be used to write code for own panel.
This helps you to write toys or your custom tools to show something in the sidebar easily only with macro. But if you want to make your panel window better, you need to write some code than you think.

See README file and other files contained in the attached archive for more detail.
Yesterday, sidebar support for Basic has been started to be discussed on dev@.

Re: [Solved] Sidebar for Developers

PostPosted: Wed May 04, 2016 5:53 pm
by hanya
The attached SidebarHelperForMacros.oxt does not work on LO 5.1 or later (maybe LO 5.0 or later).
Because method has been added. No method on the instance of the UI element crashes the office.

Here is the fixed extension package attached. Replace SidebarHelperForMacros.oxt file from the original. The change is just only in file as follows:
Code: Select all   Expand viewCollapse view
--- sidebar.py2   2013-05-29 03:27:14.000000000 +0900
+++   2016-05-05 00:46:57.420470751 +0900
@@ -117,7 +117,8 @@
         self._values = {}
             self.window = self._call_macro(settings.Initialize, (self, self.parent))
-        except:
+        except Exception as e:
+            print(e)
             raise RuntimeException("Error while calling Initialize for " + self.res_url, None)
     # XUIElement
@@ -154,6 +155,10 @@
         return LayoutSize(0, -1, 0)
+    # LO5.1-
+    def getMinimalWidth(self):
+        return 50
     def _call_macro(self, uri, args=()):
         script = self._create_script_provider().getScript(uri)

Re: [Solved] Sidebar for Developers

PostPosted: Thu May 05, 2016 5:28 pm
by Fernand
I used the newest helper extension
and instaled also the testSideBar.oxt
i endup with a private Deck "MytoolsDeck" who contains 2 panels
"MyPanel1" and "MyPanel2" who are not visible and no content is seen.
When running some API test code (LO 5.1 (Windows)) it crashes when y Xray a panel

Code: Select all   Expand viewCollapse view
Sub testSidebarApi

controller =  thisComponent.currentcontroller
frameIni =  thisComponent.currentcontroller.frame
sidebar =  thisComponent.currentcontroller.getSidebar()


frame = sidebar.getFrame()

decks = sidebar.getdecks()

c = decks.count

h = decks.hasElements()

e = decks.getElementNames()
xray e
'a =  decks.hasByName("mydeck1")

deck = decks.getByName("MytoolsDeck")

t = deck.getTitle()
'deck.setTitle("new deck title")

       ' deck.moveFirst()
       ' deck.moveUp()

       ' index = deck.getOrderIndex()

panels = deck.getPanels()
ep = panels.getElementnames()
xray ep
'ap = panels.hasByName("mypanel1")

panel = panels.getByName("MyPanel1")
xray panel
'panel.setTitle("new panel title")


'panel.expand(true) ' expand and collapse other

       ' index = panel.getOrderIndex()

       ' panel.moveLast()
      '  panel.moveFirst()
       ' panel.moveDown()
      '  panel.moveUp()

End Sub

when is use the instructions contained in the "readme" file
and run the basic macro "AddMyDeckWithPanel"
i have the same results: also a empty panel who do crashes LO
it seems that the "Initialize" function is never called ?

Code: Select all   Expand viewCollapse view
Sub AddMyDeckWithPanel
  bAdd = true ' set False to remove the existing settings
  ' deck settings
  sDeckName = "MyNewDeck"
  sDeckTitle = "New Deck"
  sDeckId = "mydeck1"
  sIconURL = "file:///home/asuka/misc/SidebarByMacros/icon2.png" ' 24x24
  sHCIconURL = sIconURL
  aDeckContextList = Array("Writer, any, visible")
  nDeckOrderIndex = 600
  ' panel settings
  sPanelName = "MyPanel"
  sPanelTitle = "My Panel"
  sPanelId = "mypanel1"
  aPanelContextList = Array("Writer, any, visible")
  bTitleBarIsOptional = True
  nPanelOrderIndex = 600
  ' resource URL for the panel
  sPath = "MyPanel3"
  sResourceURL = "private:resource/toolpanel/" & sPath
  ' macro settings
  sMacroFor_Initialize = "Standard.Module1.Initialize"
  sMacroLocation = "user"
  sMacroLanguage = "Basic"
  sMacroQuery = "?location=" & sMacroLocation & "&language=" & sMacroLanguage
  if bAdd then
    AddDeck(sDeckName, sDeckTitle, sDeckId, _
            sIconURL, sHCIconURL, aDeckContextList, nDeckOrderIndex)
    AddPanel(sPanelName, sPanelTitle, bTitleBarIsOptional, sPanelId, _
           sDeckId, aPanelContextList, sResourceURL, nPanelOrderIndex)
    AddSidebarItemForMacro(sResourceURL, _
      "" & sMacroFor_Initialize & sMacroQuery)
  end if
End Sub
' This file contains the macros to add or remove settings of sidebar components.
' See docs.odt for more detail.

Const CONFIG_DECK = "/org.openoffice.Office.UI.Sidebar/Content/DeckList"
Const CONFIG_PANEL = "/org.openoffice.Office.UI.Sidebar/Content/PanelList"
Const CONFIG_CUSTOM = "/mytools.UI.SidebarsByMacros/Content/Imples"

Sub AddSidebarItemForMacro(sResourceURI as string, sURI1 as string)
  config = GetConfigurationByName(CONFIG_CUSTOM)
  if not config.hasByName(sResourceURI) then
    item = config.createInstance()
    config.insertByName(sResourceURI, item)
    item = config.getByName(sResourceURI)
  end if
  item.Initialize = sURI1
End Sub

Sub RemoveSidebarItemForMacro(sResourceURI as string)
  RemoveItemFromConfiguration(CONFIG_CUSTOM, sResourceURI)
End Sub

Sub AddDeck( _
    sName As String, sTitle As String, sId As String, _
    sIconURL As String, sHighContrastIconURL As String, _
    aContextList as Variant, nOrderIndex as integer )
print config_deck
  config = GetConfigurationByName(CONFIG_DECK)
  if not config.hasByName(sName) then
    item = config.createInstance()
    config.insertByName(sName, item)
    item = config.getByName(sName)
  end if
    item.Title = sTitle
    item.Id = sId
    item.IconURL = sIconURL
    item.HighContrastIconURL = sHighContrastIconURL
    item.ContextList = aContextList
    item.OrderIndex = nOrderIndex
End Sub

Sub RemoveDeck( sName as string )
  RemoveItemFromConfiguration(CONFIG_DECK, sName)
End Sub

Sub AddPanel(_
    sName As String, sTitle as String, bTitleBarIsOptional as boolean, _
    sId as string, sDeckId as string, aContextList as Variant, _
    sImplementationURL as string, nOrderIndex as integer )
  config = GetConfigurationByName(CONFIG_PANEL)
  if not config.hasByName(sName) then
    item = config.createInstance()
    config.insertByName(sName, item)
    item = config.getByName(sName)
  end if
    item.Title = sTitle
    item.TitleBarIsOptional = bTitleBarIsOptional
    item.Id = sId
    item.DeckId = sDeckId
    item.ContextList = aContextList
    item.ImplementationURL = sImplementationURL
    item.OrderIndex = nOrderIndex
End Sub

Sub RemovePanel( sName as string )
  RemoveItemFromConfiguration(CONFIG_PANEL, sName)
End Sub

Function GetConfigurationByName(sNodePath as string)
  Dim args(0) as new
  args(0).Name = "nodepath"
  args(0).Value = sNodePath
  GetConfigurationByName = CreateUnoService("")._
      "", args)
End Function

Function RemoveItemFromConfiguration(sNodePath as string, sName as string) As Boolean
  bState = False
  config = GetConfigurationByName(sNodePath)
  if config.hasByName(sName) then
    bState = True
  end if
  RemoveItemFromConfiguration = bState
End Function

' Initialize with UIElement and parent window.
' @param oElement instance that implements css.ui.XUIElement,
'                 XToolPanel and XSidebarPanel.
'                 Additionally css.container.XNameContainer that
'                 allows you to set XSidebarPanel.
' @param oParent parent window
' @return panel window

Function Initialize( oElement as Variant, oParent as Variant ) As Variant
print "init"
  window = CreateChildWindow("$(user)/basic/Standard/Dialog3.xdl", oParent, True)
  window.setPosSize(0, 0, 0, 0,
  Initialize = window       ' return value
' If you do not need to set complicated resizing, simply you do not need this.
  oElement.insertByName("XSidebarPanel", _
      CreateUnoListener("XSidebarPanel_", ""))
End Function

Function XSidebarPanel_getHeightForWidth( nWidth as Variant )
  ls = CreateUnoStruct("")
  ls.Minimum = 150
  ls.Maximum = 150
  ls.Preferred = 150
  XSidebarPanel_getHeightForWidth = ls
End Function

Function CreateChildWindow( sDialogURL as string, oParent as Variant, Optional bMakeVisible as boolean )
  sDialogURI = CreateUnoService("").substituteVariables(sDialogURL, True)
  dp = CreateUnoService("")
  window = dp.createContainerWindow( sDialogURI, "", oParent, Null )
  if not IsNull(window) and Not IsMissing(bMakeVisible) and bMakeVisible then window.setVisible(True)
  CreateChildWindow = window
End Function

Re: [Solved] Sidebar for Developers

PostPosted: Thu May 05, 2016 6:08 pm
by Fernand
I do not know how, but when i open the Deck made by the "testSidebar.oxt" then when clicking on the icon there is 1 panel visible due to the fact that the basic function "Initialize" is called. I supose because there is a "sidebarbymacros.xcu" available who points to the basic "Initialize" function ?
When i made a Deck with the macro's, then the initialize function is never called and the panel do still crash LO
in the helper exention there is a "sidebarbymacros.xcs" schema file present, not a xcu (data) file
or do the basic macro's not create a proper "sidebarbymacros.xcu" file ?

Re: [Solved] Sidebar for Developers

PostPosted: Fri May 06, 2016 11:03 am
by Fernand

Found the reason why the "Initialize" function never was called

Code: Select all   Expand viewCollapse view
' macro settings
  sMacroFor_Initialize = "Standard.Module1.Initialize"
  sMacroLocation = "user"
  sMacroLanguage = "Basic"
  sMacroQuery = "?location=" & sMacroLocation & "&language=" & sMacroLanguage

the sMacroLocation must been "application" and not "user"

thanks a lot