Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 82 additions & 21 deletions cournal/mainwindow.glade
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,29 @@
</child>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuitem6">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_View</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkMenu" id="menu2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkCheckMenuItem" id="imagemenuitem_userlist">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">User list</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuitem4">
<property name="use_action_appearance">False</property>
Expand Down Expand Up @@ -367,27 +390,6 @@
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkOverlay" id="overlay">
<property name="visible">True</property>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="vscrollbar_policy">always</property>
<property name="shadow_type">in</property>
<child>
<placeholder/>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkBox" id="statusbar">
<property name="visible">True</property>
Expand Down Expand Up @@ -507,5 +509,64 @@
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkBox" id="box1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkOverlay" id="overlay">
<property name="visible">True</property>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="vscrollbar_policy">always</property>
<property name="shadow_type">in</property>
<child>
<placeholder/>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkTreeView" id="userlist_tree_view">
<property name="width_request">130</property>
<property name="can_focus">True</property>
<property name="no_show_all">True</property>
<property name="model">userlist_store</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview_user_selection"/>
</child>
<child>
<object class="GtkTreeViewColumn" id="treeview_user_column">
<property name="title" translatable="yes">Users</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
</object>
<object class="GtkTreeStore" id="userlist_store">
<columns>
<!-- column-name gchararray1 -->
<column type="gchararray"/>
</columns>
</object>
</interface>
35 changes: 35 additions & 0 deletions cournal/mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ def __init__(self, **args):
self.menu_import_xoj = builder.get_object("imagemenuitem_import_xoj")
self.menu_quit = builder.get_object("imagemenuitem_quit")
self.menu_about = builder.get_object("imagemenuitem_about")
self.menu_user_list = builder.get_object("imagemenuitem_userlist")

# Toolbar:
self.tool_open_pdf = builder.get_object("tool_open_pdf")
Expand Down Expand Up @@ -119,6 +120,7 @@ def __init__(self, **args):
self.menu_import_xoj.connect("activate", self.run_import_xoj_dialog)
self.menu_quit.connect("activate", lambda _: self.destroy())
self.menu_about.connect("activate", self.run_about_dialog)
self.menu_user_list.connect("toggled", self.toggle_user_list)
self.tool_open_pdf.connect("clicked", self.run_open_pdf_dialog)
self.tool_save.connect("clicked", self.save)
self.tool_connect.connect("clicked", self.run_connection_dialog)
Expand All @@ -143,6 +145,39 @@ def __init__(self, **args):
self.button_prev_page.connect("clicked", self.jump_to_prev_page)
self.button_next_page.connect("clicked", self.jump_to_next_page)

# User list:
self.userlist_tree_view = builder.get_object("userlist_tree_view")
self.userlist_store = builder.get_object("userlist_store")
self.treeview_user_column = builder.get_object("treeview_user_column")

self.cell = Gtk.CellRendererText()
self.treeview_user_column.pack_start(self.cell, True)
self.treeview_user_column.add_attribute(self.cell, "text", 0)
self.userlist_store.set_sort_column_id(0, Gtk.SortType.ASCENDING)

def toggle_user_list(self, menuitem):
"""
Toggle user lists visibility

Positional arguments:
menuitem -- triggeing menu item
"""
if menuitem.get_active():
self.userlist_tree_view.set_visible(True)
else:
self.userlist_tree_view.set_visible(False)

def got_user_list(self, users):
"""
Received user list from sever

Positional arguments:
users -- user list
"""
self.userlist_store.clear()
for i in users:
self.userlist_store.append(None, [i])

def connect_event(self):
"""
Called by the networking layer when a connection is established.
Expand Down
17 changes: 17 additions & 0 deletions cournal/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,23 @@ def get_document_list(self):
d.addErrback(self.disconnect)
return d

def get_user_list(self):
"""
Request user list from server
"""
if self.is_connected:
d = self.server_document.callRemote("list_users")
return d

def remote_user_list(self, users):
"""
User list request resonse

Positional arguments:
users -- user list
"""
self.window.got_user_list(users)

def join_document_session(self, documentname):
"""
Joins a "document editing session". This means, that we will automatically
Expand Down
34 changes: 34 additions & 0 deletions cournal/server/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,15 @@ def perspective_list_documents(self):
debug(2, _("User {} requested document list").format(self.name))

return list(self.server.documents.keys())

def perspective_list_users(self, document):
"""
Return a list of all our documents.
"""
debug(2, _("User {} requested user list for {}").format(self.name), document)

return list(self.server.documents.keys())


def perspective_join_document(self, documentname):
"""
Expand Down Expand Up @@ -343,6 +352,7 @@ def add_user(self, user):
for pagenum in range(len(self.pages)):
for stroke in self.pages[pagenum].strokes:
user.call_remote("new_stroke", pagenum, stroke)
self.broadcast_user_list()

def remove_user(self, user):
"""
Expand All @@ -352,6 +362,7 @@ def remove_user(self, user):
user -- The concerning User object.
"""
self.users.remove(user)
self.broadcast_user_list()

def broadcast(self, method, *args, except_user=None):
"""
Expand All @@ -368,6 +379,29 @@ def broadcast(self, method, *args, except_user=None):
if user != except_user:
user.call_remote(method, *args)

def broadcast_user_list(self):
"""
Broadcast user list to all clients.
"""
user_names = []
for u in self.users:
user_names.append(u.name)
for u in self.users:
u.call_remote("user_list", user_names)

def view_list_users(self, from_user):
"""
Send user name list to clients

Positional arguments:
from_user -- user that sent the request
"""
user_names = []
for u in self.users:
user_names.append(u.name)
#from_user.call_remote("user_list", user_names)
return user_names

def view_new_stroke(self, from_user, pagenum, stroke):
"""
Broadcast the stroke received from one to all other clients.
Expand Down