Philipp Hörist pushed to branch mainwindow at gajim / gajim
Commits: eb737c71 by lovetox at 2021-01-23T21:53:24+01:00 Add/Remove Workspaces
- - - - -
8 changed files:
- gajim/common/app.py - gajim/data/gui/main.ui - gajim/data/style/gajim.css - gajim/gtk/chat_list.py - gajim/gtk/chat_list_stack.py - gajim/gtk/chat_stack.py - gajim/gtk/main.py - gajim/gtk/workspace_side_bar.py
Changes:
===================================== gajim/common/app.py ===================================== @@ -63,6 +63,7 @@ bob_cache = {} # type: Dict[str, bytes] ipython_window = None app = None # Gtk.Application +window = None # MainWindow
ged = ged_module.GlobalEventsDispatcher() # Global Events Dispatcher nec = cast(NetworkEventsControllerT, None)
===================================== gajim/data/gui/main.ui ===================================== @@ -1,18 +1,16 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.38.2 --> +<!-- Generated with glade 3.36.0 --> <interface> <requires lib="gtk+" version="3.22"/> - <!-- n-columns=3 n-rows=3 --> <object class="GtkGrid" id="main_grid"> <property name="visible">True</property> - <property name="can-focus">False</property> + <property name="can_focus">False</property> <property name="hexpand">True</property> <property name="vexpand">True</property> <child> - <!-- n-columns=3 n-rows=3 --> <object class="GtkGrid" id="right_grid"> <property name="visible">True</property> - <property name="can-focus">False</property> + <property name="can_focus">False</property> <property name="hexpand">True</property> <property name="vexpand">True</property> <child> @@ -44,49 +42,47 @@ </child> </object> <packing> - <property name="left-attach">2</property> - <property name="top-attach">0</property> + <property name="left_attach">2</property> + <property name="top_attach">0</property> </packing> </child> <child> - <!-- n-columns=3 n-rows=3 --> <object class="GtkGrid" id="middle_grid"> <property name="visible">True</property> - <property name="can-focus">False</property> + <property name="can_focus">False</property> <property name="vexpand">True</property> <property name="orientation">vertical</property> <child> - <!-- n-columns=2 n-rows=1 --> <object class="GtkGrid"> <property name="visible">True</property> - <property name="can-focus">False</property> - <property name="column-spacing">6</property> + <property name="can_focus">False</property> + <property name="column_spacing">6</property> <child> <object class="GtkSearchEntry" id="search_entry"> - <property name="width-request">200</property> + <property name="width_request">200</property> <property name="visible">True</property> - <property name="can-focus">True</property> - <property name="primary-icon-name">edit-find-symbolic</property> - <property name="primary-icon-activatable">False</property> - <property name="primary-icon-sensitive">False</property> - <property name="placeholder-text" translatable="yes">Search…</property> + <property name="can_focus">True</property> + <property name="primary_icon_name">edit-find-symbolic</property> + <property name="primary_icon_activatable">False</property> + <property name="primary_icon_sensitive">False</property> + <property name="placeholder_text" translatable="yes">Search…</property> </object> <packing> - <property name="left-attach">1</property> - <property name="top-attach">0</property> + <property name="left_attach">1</property> + <property name="top_attach">0</property> </packing> </child> <child> <object class="GtkButton" id="start_chat_button"> <property name="visible">True</property> - <property name="can-focus">True</property> - <property name="receives-default">True</property> - <property name="tooltip-text" translatable="yes">Start Chat</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="tooltip_text" translatable="yes">Start Chat</property> <child> <object class="GtkImage"> <property name="visible">True</property> - <property name="can-focus">False</property> - <property name="icon-name">list-add-symbolic</property> + <property name="can_focus">False</property> + <property name="icon_name">list-add-symbolic</property> </object> </child> <style> @@ -94,8 +90,8 @@ </style> </object> <packing> - <property name="left-attach">0</property> - <property name="top-attach">0</property> + <property name="left_attach">0</property> + <property name="top_attach">0</property> </packing> </child> <style> @@ -103,97 +99,66 @@ </style> </object> <packing> - <property name="left-attach">0</property> - <property name="top-attach">0</property> + <property name="left_attach">0</property> + <property name="top_attach">0</property> </packing> </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> </object> <packing> - <property name="left-attach">1</property> - <property name="top-attach">0</property> + <property name="left_attach">1</property> + <property name="top_attach">0</property> </packing> </child> <child> - <!-- n-columns=3 n-rows=3 --> <object class="GtkGrid" id="left_grid"> <property name="visible">True</property> - <property name="can-focus">False</property> + <property name="can_focus">False</property> <property name="vexpand">True</property> <property name="orientation">vertical</property> <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> + <object class="GtkScrolledWindow" id="workspace_scrolled"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="vexpand">True</property> + <property name="hscrollbar_policy">never</property> + <property name="shadow_type">in</property> + <property name="propagate_natural_height">True</property> + <child> + <placeholder/> + </child> + <style> + <class name="no-border"/> + </style> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + </packing> </child> <child> - <placeholder/> + <object class="GtkBox" id="account_box"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="valign">end</property> + <property name="orientation">vertical</property> + <property name="spacing">6</property> + <child> + <placeholder/> + </child> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">1</property> + </packing> </child> + <style> + <class name="chatlist-left-grid"/> + </style> </object> <packing> - <property name="left-attach">0</property> - <property name="top-attach">0</property> + <property name="left_attach">0</property> + <property name="top_attach">0</property> </packing> </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> </object> </interface>
===================================== gajim/data/style/gajim.css ===================================== @@ -6,6 +6,7 @@ border: none; }
+.no-border { border: none; } .scrolled-no-border { border: none; } .no-scroll-indicator undershoot.top, undershoot.bottom { background-image: none; } .scrollbar-style scrollbar trough {background-color:@theme_base_color; }
===================================== gajim/gtk/chat_list.py ===================================== @@ -4,7 +4,7 @@ from gi.repository import Gdk from gi.repository import Gtk from gi.repository import Pango -from gi.repository import GObject +from gi.repository import GLib
from gajim.common import app from gajim.common.const import AvatarSize @@ -18,19 +18,12 @@
class ChatList(Gtk.ListBox): - - __gsignals__ = { - 'chat-closed': ( - GObject.SignalFlags.RUN_LAST, - None, - (Gtk.ListBoxRow,) - )} - - def __init__(self): + def __init__(self, workspace_id): Gtk.ListBox.__init__(self)
self._chats = {} self._current_filter_text = '' + self._workspace_id = workspace_id self.set_size_request(250, -1)
self.show_all() @@ -51,7 +44,7 @@ def add_chat(self, account, jid): # Chat is already in the List return
- row = ChatRow(account, jid) + row = ChatRow(self._workspace_id, account, jid) self._chats[(account, jid)] = row self.add(row)
@@ -72,11 +65,12 @@ def get_open_chats(self):
class ChatRow(Gtk.ListBoxRow): - def __init__(self, account, jid): + def __init__(self, workspace_id, account, jid): Gtk.ListBoxRow.__init__(self)
self.account = account self.jid = jid + self.workspace_id = workspace_id self._unread_count = 0
self.get_style_context().add_class('chatlist-row') @@ -201,7 +195,9 @@ def _on_state_flags_changed(self, _listboxrow, *args): self._revealer.set_reveal_child(False)
def _on_close_button_clicked(self, _button): - self.get_parent().emit('chat-closed', self) + self.get_toplevel().activate_action( + 'remove-chat', + GLib.Variant('as', [self.workspace_id, self.account, self.jid]))
def set_unread(self, count): log.info('Set unread count: %s (%s)', self.jid, count)
===================================== gajim/gtk/chat_list_stack.py ===================================== @@ -32,9 +32,8 @@ def _on_search_changed(self, search_entry): chat_list.set_filter_text(search_entry.get_text())
def add_chat_list(self, workspace_id): - chat_list = ChatList() + chat_list = ChatList(workspace_id) chat_list.connect('row-selected', self._on_row_selected) - chat_list.connect('chat-closed', self._on_chat_closed, workspace_id)
self._chat_lists[workspace_id] = chat_list self.add_named(chat_list, workspace_id) @@ -46,9 +45,6 @@ def _on_row_selected(self, _chat_list, row): return self._chat_stack.show_chat(row.account, row.jid)
- def _on_chat_closed(self, _chat_list, row, workspace_id): - self.remove_chat(workspace_id, row.account, row.jid) - def show_chat_list(self, workspace_id): self.set_visible_child_name(workspace_id)
===================================== gajim/gtk/chat_stack.py ===================================== @@ -1,5 +1,4 @@
-from collections import defaultdict
from gi.repository import Gtk
===================================== gajim/gtk/main.py ===================================== @@ -1,5 +1,7 @@
from gi.repository import Gtk +from gi.repository import GLib +from gi.repository import Gio
from gajim.common import app from gajim.gui.util import get_builder @@ -33,13 +35,10 @@ def __init__(self): self._chat_list_stack = ChatListStack(self._ui, self._chat_stack) self._account_side_bar = AccountSideBar() self._workspace_side_bar = WorkspaceSideBar() - self._ui.left_grid.get_style_context().add_class('chatlist-left-grid') - self._ui.left_grid.add(self._workspace_side_bar) - account_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6) - account_box.set_valign(Gtk.Align.END) - account_box.add(Gtk.Separator()) - account_box.add(self._account_side_bar) - self._ui.left_grid.add(account_box) + self._ui.workspace_scrolled.add(self._workspace_side_bar) + + self._ui.account_box.add(self._account_side_bar) + self._ui.middle_grid.add(self._chat_list_stack) self._ui.right_grid.add(self._chat_stack) self._ui.connect_signals(self) @@ -47,6 +46,21 @@ def __init__(self): self.show_all()
self._load_chats() + self._add_actions() + + def _add_actions(self): + actions = [ + ('add-workspace', 's', self.add_workspace), + ('remove-workspace', 's', self.remove_workspace), + ('remove-chat', 'as', self.remove_chat), + ] + + for action in actions: + action_name, variant, func = action + variant = GLib.VariantType.new(variant) + act = Gio.SimpleAction.new(action_name, variant) + act.connect('activate', func) + self.add_action(act)
def get_widget(self, name): return getattr(self._ui, name) @@ -67,6 +81,16 @@ def get_active_workspace(self): # TODO return app.settings.get_workspaces()[0]
+ def add_workspace(self, _action, param): + name = param.get_string() + workspace_id = app.settings.add_workspace(name) + self._workspace_side_bar.add_workspace(workspace_id) + + def remove_workspace(self, _action, param): + workspace_id = param.get_string() + self._workspace_side_bar.remove_workspace(workspace_id) + app.settings.remove_workspace(workspace_id) + def add_chat(self, account, jid): workspace_id = self.get_active_workspace() self.add_chat_for_workspace(workspace_id, account, jid) @@ -79,7 +103,8 @@ def add_chat_for_workspace(self, workspace_id, account, jid): self._chat_list_stack.select_chat(workspace_id, account, jid) self._chat_list_stack.store_open_chats(workspace_id)
- def remove_chat(self, workspace_id, account, jid): + def remove_chat(self, _action, param): + workspace_id, account, jid = param.unpack() self._chat_list_stack.remove_chat(workspace_id, account, jid)
def get_control(self, account, jid):
===================================== gajim/gtk/workspace_side_bar.py ===================================== @@ -1,8 +1,11 @@
from gi.repository import Gtk +from gi.repository import GLib from gajim.common.const import AvatarSize from gajim.common import app
+from gajim.common.i18n import _ + from gajim.gui.avatar import generate_default_avatar
@@ -11,27 +14,108 @@ def __init__(self): Gtk.ListBox.__init__(self) self.set_vexpand(True) self.set_valign(Gtk.Align.START) + self.set_sort_func(self._sort_func) + self.add(AddWorkspace('add')) + self.connect('button-press-event', self._on_button_press) + self.connect('row-activated', self._on_row_activated) + + @staticmethod + def _sort_func(child1, child2): + if child1.sort_index < child2.sort_index: + return -1 + + if child1.sort_index == child2.sort_index: + return 0 + return 1 + + def _on_button_press(self, _listbox, button_event): + if button_event.button != 3: + return + row = self.get_row_at_y(button_event.y) + WorspaceMenu(row) + + def _on_row_activated(self, _listbox, row): + main_window = self.get_toplevel() + if row.workspace_id == 'add': + main_window.activate_action( + 'add-workspace', GLib.Variant('s', 'test')) + else: + main_window.activate_action( + 'activate-workspace', GLib.Variant('s', row.workspace_id))
def add_workspace(self, workspace_id): self.add(Workspace(workspace_id))
def remove_workspace(self, workspace_id): - pass + for row in self.get_children(): + if row.workspace_id == workspace_id: + self.remove(row) + break
-class Workspace(Gtk.ListBoxRow): +class CommonWorkspace(Gtk.ListBoxRow): def __init__(self, workspace_id): Gtk.ListBoxRow.__init__(self) self.get_style_context().add_class('workspace-sidebar-item')
- self._workspace_id = workspace_id + self.workspace_id = workspace_id + + +class Workspace(CommonWorkspace): + def __init__(self, workspace_id): + CommonWorkspace.__init__(self, workspace_id) + + self.sort_index = 0 + name = app.settings.get_workspace_setting(workspace_id, 'name') letter = name[:2]
scale = self.get_scale_factor() surface = generate_default_avatar( letter, name, AvatarSize.WORKSPACE, scale) - self._image = Gtk.Image.new_from_surface(surface) - self._image.set_halign(Gtk.Align.CENTER) - self.add(self._image) + image = Gtk.Image.new_from_surface(surface) + image.set_halign(Gtk.Align.CENTER) + self.add(image) self.show_all() + + +class AddWorkspace(CommonWorkspace): + def __init__(self, workspace_id): + CommonWorkspace.__init__(self, workspace_id) + + self.set_selectable(False) + + self.sort_index = 10000 + + image = Gtk.Image.new_from_icon_name('list-add-symbolic', + Gtk.IconSize.DND) + image.set_halign(Gtk.Align.CENTER) + self.add(image) + self.show_all() + + +class WorspaceMenu(Gtk.Popover): + def __init__(self, row): + Gtk.Popover.__init__(self) + entries = [ + (_('Remove'), 'remove-workspace'), + ] + + self._workspace_id = row.workspace_id + + box = Gtk.Box() + for label, action in entries: + button = Gtk.Button(label=label) + button.connect('clicked', self._on_click, action) + box.add(button) + box.show_all() + + self.add(box) + self.set_relative_to(row) + self.popup() + + def _on_click(self, _button, action): + self.popdown() + self.set_relative_to(None) + app.window.activate_action(action, + GLib.Variant('s', self._workspace_id))
View it on GitLab: https://dev.gajim.org/gajim/gajim/-/commit/eb737c7128046a5391d044a66cb90065c...