summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/source/plugins/index.rst6
-rw-r--r--doc/source/plugins/reorder.rst6
-rw-r--r--doc/stub/tabs.py2
-rw-r--r--plugins/reorder.py129
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()
+