diff options
-rw-r--r-- | doc/source/plugins/index.rst | 6 | ||||
-rw-r--r-- | doc/source/plugins/reorder.rst | 6 | ||||
-rw-r--r-- | doc/stub/tabs.py | 2 | ||||
-rw-r--r-- | plugins/reorder.py | 129 |
4 files changed, 143 insertions, 0 deletions
diff --git a/doc/source/plugins/index.rst b/doc/source/plugins/index.rst index d1f021de..9df47c3b 100644 --- a/doc/source/plugins/index.rst +++ b/doc/source/plugins/index.rst @@ -210,6 +210,11 @@ Plugin index Display the time between two messages. + Reorder + :ref:`Documentation <reorder-plugin>` + + Reorder the tabs according to a static layout. + Revstr :ref:`Documentation <revstr-plugin>` @@ -291,3 +296,4 @@ Plugin index change_title pipe_cmd close_all + reorder diff --git a/doc/source/plugins/reorder.rst b/doc/source/plugins/reorder.rst new file mode 100644 index 00000000..a6a44244 --- /dev/null +++ b/doc/source/plugins/reorder.rst @@ -0,0 +1,6 @@ +.. _reorder-plugin: + +Reorder +======= + +.. automodule:: reorder diff --git a/doc/stub/tabs.py b/doc/stub/tabs.py index cd3dc073..b4d23c1c 100644 --- a/doc/stub/tabs.py +++ b/doc/stub/tabs.py @@ -6,4 +6,6 @@ class ConversationTab(ChatTab): pass class RosterInfoTab(Tab): pass class XMLTab(Tab): pass class DynamicConversationTab(Tab): pass +class StaticConversationTab(Tab): pass +class GapTab(Tab): pass diff --git a/plugins/reorder.py b/plugins/reorder.py new file mode 100644 index 00000000..13d873e7 --- /dev/null +++ b/plugins/reorder.py @@ -0,0 +1,129 @@ +""" +``reorder`` plugin: Reorder the tabs according to a layout + +Commands +-------- + +.. glossary:: + + /reorder + **Usage:** ``/reorder`` + + Reorder the tabs according to the configuration. + + +Configuration +------------- + +The configuration file must contain a section ``[reorder]`` and each option +must be formatted like ``[tab number] = [tab type]:[tab name]``. + +For example: + +.. code-block:: ini + + [reorder] + 1 = muc:toto@conference.example.com + 2 = muc:example@muc.example.im + 3 = dynamic:robert@example.org + +The ``[tab number]`` must be at least ``1``; if the range is not entirely +covered, e.g.: + +.. code-block:: ini + + [reorder] + 1 = muc:toto@conference.example.com + 3 = dynamic:robert@example.org + +Poezio will insert gaps between the tabs in order to keep the specified +numbering (so in this case, there will be a tab 1, a tab 3, but no tab 2). + + +The ``[tab type]`` must be one of: + +- ``muc`` (for multi-user chats) +- ``private`` (for chats with a specific user inside a multi-user chat) +- ``dynamic`` (for normal, dynamic conversations tabs) +- ``static`` (for conversations with a specific resource) + +And finally, the ``[tab name]`` must be: + +- For a type ``muc``, the bare JID of the room +- For a type ``private``, the full JID of the user (room JID with the username as a resource) +- For a type ``dynamic``, the bare JID of the contact +- For a type ``static``, the full JID of the contact +""" +from plugin import BasePlugin +import tabs +from decorators import command_args_parser + +mapping = { + 'muc': tabs.MucTab, + 'private': tabs.PrivateTab, + 'dynamic': tabs.DynamicConversationTab, + 'static': tabs.StaticConversationTab, + 'empty': tabs.GapTab +} + +def parse_config(config): + result = {} + for option in config.options('reorder'): + if not option.isdecimal(): + continue + pos = int(option) + if pos in result or pos <= 0: + return + + typ, name = config.get(option, default=':').split(':', maxsplit=1) + if typ not in mapping: + return + result[pos] = (mapping[typ], name) + + return result + +class Plugin(BasePlugin): + def init(self): + self.api.add_command('reorder', self.command_reorder, + help='Reorder all tabs.') + + @command_args_parser.ignored + def command_reorder(self): + """ + /reorder + """ + self.core.go_to_roster() + self.core.current_tab_nb = 0 + + tabs_spec = parse_config(self.config) + if not tabs_spec: + return self.api.information('Invalid reorder config', 'Error') + + old_tabs = self.core.tabs[1:] + roster = self.core.tabs[0] + + new_tabs = [] + last = 0 + for pos in sorted(tabs_spec): + if pos > last + 1: + new_tabs += [tabs.GapTab() for i in range(pos - last)] + cls, name = tabs_spec[pos] + tab = self.core.get_tab_by_name(name, typ=cls) + if tab and tab in old_tabs: + new_tabs.append(tab) + old_tabs.remove(tab) + else: + self.api.information('Tab %s not found' % name, 'Warning') + new_tabs.append(tabs.GapTab()) + last = pos + + for tab in old_tabs: + if tab: + new_tabs.append(tab) + + self.core.tabs.clear() + self.core.tabs.append(roster) + self.core.tabs += new_tabs + + self.core.refresh_window() + |