How to get Active Tab/Page ID from a python dialog box?

I am trying to create a multi tab dialog box and am having trouble getting the current selected tab. Currently I am using a “UnoMultiPageModel” (which I actually never found on any openoffice/libreoffice API docs) to accomplish this since I couldn’t even get the tabs to show using “UnoControlTabPageContainerModel”. The Tabs work well and I can populate them how I want to, but I would like to know what tab I am currently at when a button action takes place. UnoMultiPageModel has the XSimpleTabController interface but I can’t figure out how to actually use the member functions.

The simplified version of the dialog box is basically a clone of this link:
https://wiki.openoffice.org/wiki/Python/Transfer_from_Basic_to_Python#Input_Box

def tabbedDialog():
    WIDTH = 400
    HORI_MARGIN = VERT_MARGIN = 8
    BUTTON_WIDTH = 100
    BUTTON_HEIGHT = 26
    HORI_SEP = VERT_SEP = 8
    LABEL_HEIGHT = BUTTON_HEIGHT * 2 + 5
    EDIT_HEIGHT = 500
    HEIGHT = VERT_MARGIN * 2 + LABEL_HEIGHT + VERT_SEP + EDIT_HEIGHT
    OFFSET = 25

    ctx = uno.getComponentContext()
    def create(name):
        return ctx.getServiceManager().createInstanceWithContext(name, ctx)
        
    # Setup Dialog window
    dialog = create("com.sun.star.awt.UnoControlDialog")
    dialogModel = create("com.sun.star.awt.UnoControlDialogModel")
    dialog.setModel(dialogModel)
    dialog.setVisible(False)
    dialog.setTitle("Dialog Title")
    dialog.setPosSize(0, 0, WIDTH, HEIGHT, SIZE)

    # Add an element to a parent model and return the model for the new element 
    def add(name, type, parentModel, x_, y_, width_, height_, props):
        model = parentModel.createInstance("com.sun.star.awt." + type)
        parentModel.insertByName(name, model)
        control = dialog.getControl(name)
        if width_ > 0 and height_ > 0:
            control.setPosSize(x_, y_, width_, height_, POSSIZE)
        for key, value in props.items():
            setattr(model, key, value)
        return model
    
    # Set up Dialog Box 
    add("btn_cancel", "UnoControlButtonModel", dialogModel,
        (WIDTH/2), (HEIGHT) - (BUTTON_HEIGHT + OFFSET), 
        BUTTON_WIDTH, BUTTON_HEIGHT, 
        {"PushButtonType": CANCEL, "DefaultButton": True})

    add("btn_action", "UnoControlButtonModel", dialogModel,
        (WIDTH/2) - (BUTTON_WIDTH), (HEIGHT) - (BUTTON_HEIGHT + OFFSET), 
        BUTTON_WIDTH, BUTTON_HEIGHT, 
        {"PushButtonType": STANDARD, "Label": "Page Action"})

    # Do stuff with info on the current tab
    dialog.getControl("btn_action").addActionListener(ButtonEvent())

    tabContainer = add("tabController", "UnoMultiPageModel", dialogModel,
                        HORI_MARGIN, VERT_MARGIN, 
                        WIDTH - (HORI_MARGIN*2), HEIGHT -  OFFSET - (BUTTON_HEIGHT*2),
                        {"Enabled": True, "EnableVisible": True})

    pgNames = ["Page_1", "Page_2", "Page_3"]
    for idx, name in enumerate(pgNames):
        pgModel = add(pgNames[idx], "UnoPageModel", tabContainer,
                        0, 0, 0, 0,
                        {"Title": name, "EnableVisible": True})
        # How to use XSimpleTabController interface functions to get Tab Info needed

    frame = create("com.sun.star.frame.Desktop").getCurrentFrame()
    window = frame.getContainerWindow() if frame else None
    dialog.createPeer(create("com.sun.star.awt.Toolkit"), window)
    pos = window.getPosSize()
    _x = pos.Width / 2 - WIDTH / 2
    _y = pos.Height / 2 - HEIGHT / 2
    dialog.setPosSize(_x, _y, 0, 0, POS)
    if dialog.execute() == 0:
        print("Cancel Pressed")
    dialog.dispose()
    return 

In the page model creation loop, I have tried different combinations of “insertTab()”, “setTabProps()” “insertByName()” “insertByIndex()”, but have had no luck. Mostly been trying to follow this: How to insert tab pages to a dialog using Java? (View topic) • Apache OpenOffice Community Forum

All of the “XSimpleTabController” functions return errors for me.
setTabProps(int, NameValue()) → com.sun.star.script.CannotConvertException: conversion not possible!
insertTab() → com.sun.star.uno.RuntimeException
getActiveTabID() → com.sun.star.uno.RuntimeException: unsatisfied query for interface of type com.sun.star.awt.XSimpleTabController!

I also tried using an XTabListener to the MultiPageModel but couldn’t figure out how to connect it.

class TabEvent(unohelper.Base, XTabListener):
    def __init__(self, name):
        self._name = name
    def inserted(self, ID):
        self._ID = ID
    def activated(self, ID):
        pass

Also tried this API:

But couldn’t get it working.

Using Libreoffice 6.1 on Linux

Hello,

Have not looked in depth at your code but this will get what you are looking for. Have set this per your request of the button action for the Page Action button.

Edited 2018-11-30 (to remove global):

You want a class for the button listener:

from com.sun.star.awt import XActionListener
class ActionListener(unohelper.Base, XActionListener):
    def __init__(self, dialog):
        self.my_dialog = dialog
    def disposing(self, ev):
        pass
    def actionPerformed(self, ev):
        oControl = self.my_dialog.getControl("tabController")
        active_tab = oControl.getActiveTabID()

Next change:

 dialog.getControl("btn_action").addActionListener(ButtonEvent())

To:

oControl = dialog.getControl("btn_action")
oControl.addActionListener(ActionListener(dialog))

Add:

oControl = dialog.getControl("btn_action")
oControl.removeActionListener(ActionListener(dialog))

Before:

dialog.dispose()

When the button is pressed the selected tab is available as active_tab in the actionPerformed definition. Event is also available (ev). Did not put further code there, just access to the data.

Thanks for the heads up on tabs. Will have to look closer into this. Have had at least one other question on this but did not find the answer. This helps.

The above gets you what was needed but still looking into XSimpleTabController and also looking at XTabPageContainerListener.

Perfect @Ratslinger. Exactly what I needed. Thanks a lot