Philipp Hörist pushed to branch master at gajim / gajim
Commits:
-
25e31bd5
by Philipp Hörist at 2019-07-10T16:36:18Z
-
799c284e
by Philipp Hörist at 2019-07-10T16:53:43Z
-
5586a209
by Philipp Hörist at 2019-07-10T17:34:07Z
-
b6c26e57
by Philipp Hörist at 2019-07-11T21:29:49Z
-
7f33ecfb
by Philipp Hörist at 2019-07-11T21:31:33Z
8 changed files:
- gajim/application.py
- gajim/data/gui/start_chat_dialog.ui
- gajim/data/style/gajim.css
- gajim/dialog_messages.py
- gajim/gtk/groupchat_info.py
- gajim/gtk/start_chat.py
- gajim/gui_interface.py
- gajim/remote_control.py
Changes:
| ... | ... | @@ -39,6 +39,8 @@ from pathlib import Path |
| 39 | 39 |
from urllib.parse import unquote
|
| 40 | 40 |
|
| 41 | 41 |
import nbxmpp
|
| 42 |
+from nbxmpp import JID
|
|
| 43 |
+from nbxmpp.protocol import InvalidJid
|
|
| 42 | 44 |
from gi.repository import Gio
|
| 43 | 45 |
from gi.repository import GLib
|
| 44 | 46 |
from gi.repository import Gtk
|
| ... | ... | @@ -236,6 +238,10 @@ class GajimApplication(Gtk.Application): |
| 236 | 238 |
self._on_feature_discovered)
|
| 237 | 239 |
|
| 238 | 240 |
def _open_uris(self, uris):
|
| 241 |
+ accounts = list(app.connections.keys())
|
|
| 242 |
+ if not accounts:
|
|
| 243 |
+ return
|
|
| 244 |
+ |
|
| 239 | 245 |
for uri in uris:
|
| 240 | 246 |
app.log('uri_handler').info('open %s', uri)
|
| 241 | 247 |
if not uri.startswith('xmpp:'):
|
| ... | ... | @@ -247,10 +253,30 @@ class GajimApplication(Gtk.Application): |
| 247 | 253 |
except ValueError:
|
| 248 | 254 |
# No query argument
|
| 249 | 255 |
jid, cmd = uri, 'message'
|
| 256 |
+ |
|
| 257 |
+ try:
|
|
| 258 |
+ jid = JID(jid)
|
|
| 259 |
+ except InvalidJid as error:
|
|
| 260 |
+ app.log('uri_handler').warning('Invalid JID %s: %s', uri, error)
|
|
| 261 |
+ continue
|
|
| 262 |
+ |
|
| 263 |
+ if cmd == 'join' and jid.getResource():
|
|
| 264 |
+ app.log('uri_handler').warning('Invalid MUC JID %s', uri)
|
|
| 265 |
+ continue
|
|
| 266 |
+ |
|
| 267 |
+ jid = str(jid)
|
|
| 268 |
+ |
|
| 250 | 269 |
if cmd == 'join':
|
| 251 |
- self.interface.join_gc_minimal(None, jid)
|
|
| 270 |
+ if len(accounts) == 1:
|
|
| 271 |
+ self.activate_action(
|
|
| 272 |
+ 'groupchat-join',
|
|
| 273 |
+ GLib.Variant('as', [accounts[0], jid]))
|
|
| 274 |
+ else:
|
|
| 275 |
+ self.activate_action('start-chat', GLib.Variant('s', jid))
|
|
| 276 |
+ |
|
| 252 | 277 |
elif cmd == 'roster':
|
| 253 | 278 |
self.activate_action('add-contact', GLib.Variant('s', jid))
|
| 279 |
+ |
|
| 254 | 280 |
elif cmd.startswith('message'):
|
| 255 | 281 |
attributes = cmd.split(';')
|
| 256 | 282 |
message = None
|
| ... | ... | @@ -261,15 +287,11 @@ class GajimApplication(Gtk.Application): |
| 261 | 287 |
message = unquote(key.split('=')[1])
|
| 262 | 288 |
except Exception:
|
| 263 | 289 |
app.log('uri_handler').error('Invalid URI: %s', cmd)
|
| 264 |
- accounts = list(app.connections.keys())
|
|
| 265 |
- if not accounts:
|
|
| 266 |
- continue
|
|
| 290 |
+ |
|
| 267 | 291 |
if len(accounts) == 1:
|
| 268 | 292 |
app.interface.new_chat_from_jid(accounts[0], jid, message)
|
| 269 | 293 |
else:
|
| 270 |
- self.activate_action('start-chat', GLib.Variant('s', ''))
|
|
| 271 |
- start_chat = app.get_app_window('StartChatDialog')
|
|
| 272 |
- start_chat.set_search_text(jid)
|
|
| 294 |
+ self.activate_action('start-chat', GLib.Variant('s', jid))
|
|
| 273 | 295 |
|
| 274 | 296 |
def do_shutdown(self, *args):
|
| 275 | 297 |
Gtk.Application.do_shutdown(self)
|
| ... | ... | @@ -2,57 +2,6 @@ |
| 2 | 2 |
<!-- Generated with glade 3.22.1 -->
|
| 3 | 3 |
<interface>
|
| 4 | 4 |
<requires lib="gtk+" version="3.20"/>
|
| 5 |
- <object class="GtkBox" id="box">
|
|
| 6 |
- <property name="visible">True</property>
|
|
| 7 |
- <property name="can_focus">False</property>
|
|
| 8 |
- <property name="border_width">18</property>
|
|
| 9 |
- <property name="orientation">vertical</property>
|
|
| 10 |
- <property name="spacing">6</property>
|
|
| 11 |
- <child>
|
|
| 12 |
- <object class="GtkSearchEntry" id="search_entry">
|
|
| 13 |
- <property name="visible">True</property>
|
|
| 14 |
- <property name="can_focus">True</property>
|
|
| 15 |
- <property name="has_focus">True</property>
|
|
| 16 |
- <property name="is_focus">True</property>
|
|
| 17 |
- <property name="primary_icon_name">edit-find-symbolic</property>
|
|
| 18 |
- <property name="primary_icon_activatable">False</property>
|
|
| 19 |
- <property name="primary_icon_sensitive">False</property>
|
|
| 20 |
- </object>
|
|
| 21 |
- <packing>
|
|
| 22 |
- <property name="expand">False</property>
|
|
| 23 |
- <property name="fill">True</property>
|
|
| 24 |
- <property name="position">0</property>
|
|
| 25 |
- </packing>
|
|
| 26 |
- </child>
|
|
| 27 |
- <child>
|
|
| 28 |
- <object class="GtkScrolledWindow" id="scrolledwindow">
|
|
| 29 |
- <property name="visible">True</property>
|
|
| 30 |
- <property name="can_focus">True</property>
|
|
| 31 |
- <property name="hscrollbar_policy">never</property>
|
|
| 32 |
- <property name="shadow_type">in</property>
|
|
| 33 |
- <child>
|
|
| 34 |
- <object class="GtkViewport">
|
|
| 35 |
- <property name="visible">True</property>
|
|
| 36 |
- <property name="can_focus">False</property>
|
|
| 37 |
- <child>
|
|
| 38 |
- <object class="GtkListBox" id="listbox">
|
|
| 39 |
- <property name="name">StartChatListBox</property>
|
|
| 40 |
- <property name="visible">True</property>
|
|
| 41 |
- <property name="can_focus">False</property>
|
|
| 42 |
- <property name="selection_mode">browse</property>
|
|
| 43 |
- <property name="activate_on_single_click">False</property>
|
|
| 44 |
- </object>
|
|
| 45 |
- </child>
|
|
| 46 |
- </object>
|
|
| 47 |
- </child>
|
|
| 48 |
- </object>
|
|
| 49 |
- <packing>
|
|
| 50 |
- <property name="expand">True</property>
|
|
| 51 |
- <property name="fill">True</property>
|
|
| 52 |
- <property name="position">1</property>
|
|
| 53 |
- </packing>
|
|
| 54 |
- </child>
|
|
| 55 |
- </object>
|
|
| 56 | 5 |
<object class="GtkGrid" id="search_result_grid">
|
| 57 | 6 |
<property name="visible">True</property>
|
| 58 | 7 |
<property name="can_focus">False</property>
|
| ... | ... | @@ -128,6 +77,234 @@ |
| 128 | 77 |
</packing>
|
| 129 | 78 |
</child>
|
| 130 | 79 |
</object>
|
| 80 |
+ <object class="GtkStack" id="stack">
|
|
| 81 |
+ <property name="visible">True</property>
|
|
| 82 |
+ <property name="can_focus">False</property>
|
|
| 83 |
+ <child>
|
|
| 84 |
+ <object class="GtkBox" id="box">
|
|
| 85 |
+ <property name="visible">True</property>
|
|
| 86 |
+ <property name="can_focus">False</property>
|
|
| 87 |
+ <property name="border_width">18</property>
|
|
| 88 |
+ <property name="orientation">vertical</property>
|
|
| 89 |
+ <property name="spacing">6</property>
|
|
| 90 |
+ <child>
|
|
| 91 |
+ <object class="GtkSearchEntry" id="search_entry">
|
|
| 92 |
+ <property name="visible">True</property>
|
|
| 93 |
+ <property name="can_focus">True</property>
|
|
| 94 |
+ <property name="has_focus">True</property>
|
|
| 95 |
+ <property name="is_focus">True</property>
|
|
| 96 |
+ <property name="primary_icon_name">edit-find-symbolic</property>
|
|
| 97 |
+ <property name="primary_icon_activatable">False</property>
|
|
| 98 |
+ <property name="primary_icon_sensitive">False</property>
|
|
| 99 |
+ </object>
|
|
| 100 |
+ <packing>
|
|
| 101 |
+ <property name="expand">False</property>
|
|
| 102 |
+ <property name="fill">True</property>
|
|
| 103 |
+ <property name="position">0</property>
|
|
| 104 |
+ </packing>
|
|
| 105 |
+ </child>
|
|
| 106 |
+ <child>
|
|
| 107 |
+ <object class="GtkScrolledWindow" id="scrolledwindow">
|
|
| 108 |
+ <property name="visible">True</property>
|
|
| 109 |
+ <property name="can_focus">True</property>
|
|
| 110 |
+ <property name="hscrollbar_policy">never</property>
|
|
| 111 |
+ <property name="shadow_type">in</property>
|
|
| 112 |
+ <child>
|
|
| 113 |
+ <object class="GtkViewport">
|
|
| 114 |
+ <property name="visible">True</property>
|
|
| 115 |
+ <property name="can_focus">False</property>
|
|
| 116 |
+ <child>
|
|
| 117 |
+ <object class="GtkListBox" id="listbox">
|
|
| 118 |
+ <property name="name">StartChatListBox</property>
|
|
| 119 |
+ <property name="visible">True</property>
|
|
| 120 |
+ <property name="can_focus">False</property>
|
|
| 121 |
+ <property name="selection_mode">browse</property>
|
|
| 122 |
+ <property name="activate_on_single_click">False</property>
|
|
| 123 |
+ </object>
|
|
| 124 |
+ </child>
|
|
| 125 |
+ </object>
|
|
| 126 |
+ </child>
|
|
| 127 |
+ </object>
|
|
| 128 |
+ <packing>
|
|
| 129 |
+ <property name="expand">True</property>
|
|
| 130 |
+ <property name="fill">True</property>
|
|
| 131 |
+ <property name="position">1</property>
|
|
| 132 |
+ </packing>
|
|
| 133 |
+ </child>
|
|
| 134 |
+ </object>
|
|
| 135 |
+ <packing>
|
|
| 136 |
+ <property name="name">search</property>
|
|
| 137 |
+ </packing>
|
|
| 138 |
+ </child>
|
|
| 139 |
+ <child>
|
|
| 140 |
+ <object class="GtkBox">
|
|
| 141 |
+ <property name="visible">True</property>
|
|
| 142 |
+ <property name="can_focus">False</property>
|
|
| 143 |
+ <property name="orientation">vertical</property>
|
|
| 144 |
+ <child>
|
|
| 145 |
+ <object class="GtkSpinner" id="spinner">
|
|
| 146 |
+ <property name="visible">True</property>
|
|
| 147 |
+ <property name="can_focus">False</property>
|
|
| 148 |
+ <property name="halign">center</property>
|
|
| 149 |
+ <property name="valign">center</property>
|
|
| 150 |
+ <property name="vexpand">True</property>
|
|
| 151 |
+ <property name="active">True</property>
|
|
| 152 |
+ </object>
|
|
| 153 |
+ <packing>
|
|
| 154 |
+ <property name="expand">False</property>
|
|
| 155 |
+ <property name="fill">True</property>
|
|
| 156 |
+ <property name="position">0</property>
|
|
| 157 |
+ </packing>
|
|
| 158 |
+ </child>
|
|
| 159 |
+ </object>
|
|
| 160 |
+ <packing>
|
|
| 161 |
+ <property name="name">progress</property>
|
|
| 162 |
+ <property name="position">1</property>
|
|
| 163 |
+ </packing>
|
|
| 164 |
+ </child>
|
|
| 165 |
+ <child>
|
|
| 166 |
+ <object class="GtkBox">
|
|
| 167 |
+ <property name="visible">True</property>
|
|
| 168 |
+ <property name="can_focus">False</property>
|
|
| 169 |
+ <property name="orientation">vertical</property>
|
|
| 170 |
+ <child>
|
|
| 171 |
+ <object class="GtkBox">
|
|
| 172 |
+ <property name="visible">True</property>
|
|
| 173 |
+ <property name="can_focus">False</property>
|
|
| 174 |
+ <property name="orientation">vertical</property>
|
|
| 175 |
+ <property name="spacing">12</property>
|
|
| 176 |
+ <property name="homogeneous">True</property>
|
|
| 177 |
+ <child>
|
|
| 178 |
+ <object class="GtkImage">
|
|
| 179 |
+ <property name="visible">True</property>
|
|
| 180 |
+ <property name="can_focus">False</property>
|
|
| 181 |
+ <property name="valign">end</property>
|
|
| 182 |
+ <property name="icon_name">dialog-error</property>
|
|
| 183 |
+ <property name="icon_size">6</property>
|
|
| 184 |
+ </object>
|
|
| 185 |
+ <packing>
|
|
| 186 |
+ <property name="expand">False</property>
|
|
| 187 |
+ <property name="fill">True</property>
|
|
| 188 |
+ <property name="position">0</property>
|
|
| 189 |
+ </packing>
|
|
| 190 |
+ </child>
|
|
| 191 |
+ <child>
|
|
| 192 |
+ <object class="GtkLabel" id="error_label">
|
|
| 193 |
+ <property name="visible">True</property>
|
|
| 194 |
+ <property name="can_focus">False</property>
|
|
| 195 |
+ <property name="valign">start</property>
|
|
| 196 |
+ <property name="justify">center</property>
|
|
| 197 |
+ <property name="wrap">True</property>
|
|
| 198 |
+ <style>
|
|
| 199 |
+ <class name="bold16"/>
|
|
| 200 |
+ </style>
|
|
| 201 |
+ </object>
|
|
| 202 |
+ <packing>
|
|
| 203 |
+ <property name="expand">False</property>
|
|
| 204 |
+ <property name="fill">True</property>
|
|
| 205 |
+ <property name="position">1</property>
|
|
| 206 |
+ </packing>
|
|
| 207 |
+ </child>
|
|
| 208 |
+ </object>
|
|
| 209 |
+ <packing>
|
|
| 210 |
+ <property name="expand">True</property>
|
|
| 211 |
+ <property name="fill">True</property>
|
|
| 212 |
+ <property name="position">0</property>
|
|
| 213 |
+ </packing>
|
|
| 214 |
+ </child>
|
|
| 215 |
+ <child>
|
|
| 216 |
+ <object class="GtkButton">
|
|
| 217 |
+ <property name="label" translatable="yes">_Back</property>
|
|
| 218 |
+ <property name="visible">True</property>
|
|
| 219 |
+ <property name="can_focus">True</property>
|
|
| 220 |
+ <property name="receives_default">True</property>
|
|
| 221 |
+ <property name="halign">start</property>
|
|
| 222 |
+ <property name="use_underline">True</property>
|
|
| 223 |
+ <signal name="clicked" handler="_on_back_clicked" swapped="no"/>
|
|
| 224 |
+ </object>
|
|
| 225 |
+ <packing>
|
|
| 226 |
+ <property name="expand">False</property>
|
|
| 227 |
+ <property name="fill">True</property>
|
|
| 228 |
+ <property name="pack_type">end</property>
|
|
| 229 |
+ <property name="position">1</property>
|
|
| 230 |
+ </packing>
|
|
| 231 |
+ </child>
|
|
| 232 |
+ <style>
|
|
| 233 |
+ <class name="margin-18"/>
|
|
| 234 |
+ </style>
|
|
| 235 |
+ </object>
|
|
| 236 |
+ <packing>
|
|
| 237 |
+ <property name="name">error</property>
|
|
| 238 |
+ <property name="position">2</property>
|
|
| 239 |
+ </packing>
|
|
| 240 |
+ </child>
|
|
| 241 |
+ <child>
|
|
| 242 |
+ <object class="GtkBox" id="info_box">
|
|
| 243 |
+ <property name="visible">True</property>
|
|
| 244 |
+ <property name="can_focus">False</property>
|
|
| 245 |
+ <property name="orientation">vertical</property>
|
|
| 246 |
+ <property name="spacing">6</property>
|
|
| 247 |
+ <child>
|
|
| 248 |
+ <placeholder/>
|
|
| 249 |
+ </child>
|
|
| 250 |
+ <child>
|
|
| 251 |
+ <object class="GtkBox">
|
|
| 252 |
+ <property name="visible">True</property>
|
|
| 253 |
+ <property name="can_focus">False</property>
|
|
| 254 |
+ <property name="homogeneous">True</property>
|
|
| 255 |
+ <child>
|
|
| 256 |
+ <object class="GtkButton">
|
|
| 257 |
+ <property name="label" translatable="yes">_Back</property>
|
|
| 258 |
+ <property name="visible">True</property>
|
|
| 259 |
+ <property name="can_focus">True</property>
|
|
| 260 |
+ <property name="receives_default">True</property>
|
|
| 261 |
+ <property name="halign">start</property>
|
|
| 262 |
+ <property name="use_underline">True</property>
|
|
| 263 |
+ <signal name="clicked" handler="_on_back_clicked" swapped="no"/>
|
|
| 264 |
+ </object>
|
|
| 265 |
+ <packing>
|
|
| 266 |
+ <property name="expand">False</property>
|
|
| 267 |
+ <property name="fill">True</property>
|
|
| 268 |
+ <property name="position">0</property>
|
|
| 269 |
+ </packing>
|
|
| 270 |
+ </child>
|
|
| 271 |
+ <child>
|
|
| 272 |
+ <object class="GtkButton">
|
|
| 273 |
+ <property name="label" translatable="yes">_Join</property>
|
|
| 274 |
+ <property name="visible">True</property>
|
|
| 275 |
+ <property name="can_focus">True</property>
|
|
| 276 |
+ <property name="receives_default">True</property>
|
|
| 277 |
+ <property name="halign">end</property>
|
|
| 278 |
+ <property name="use_underline">True</property>
|
|
| 279 |
+ <signal name="clicked" handler="_on_join_clicked" swapped="no"/>
|
|
| 280 |
+ <style>
|
|
| 281 |
+ <class name="suggested-action"/>
|
|
| 282 |
+ </style>
|
|
| 283 |
+ </object>
|
|
| 284 |
+ <packing>
|
|
| 285 |
+ <property name="expand">False</property>
|
|
| 286 |
+ <property name="fill">True</property>
|
|
| 287 |
+ <property name="position">1</property>
|
|
| 288 |
+ </packing>
|
|
| 289 |
+ </child>
|
|
| 290 |
+ </object>
|
|
| 291 |
+ <packing>
|
|
| 292 |
+ <property name="expand">False</property>
|
|
| 293 |
+ <property name="fill">True</property>
|
|
| 294 |
+ <property name="pack_type">end</property>
|
|
| 295 |
+ <property name="position">1</property>
|
|
| 296 |
+ </packing>
|
|
| 297 |
+ </child>
|
|
| 298 |
+ <style>
|
|
| 299 |
+ <class name="margin-18"/>
|
|
| 300 |
+ </style>
|
|
| 301 |
+ </object>
|
|
| 302 |
+ <packing>
|
|
| 303 |
+ <property name="name">info</property>
|
|
| 304 |
+ <property name="position">3</property>
|
|
| 305 |
+ </packing>
|
|
| 306 |
+ </child>
|
|
| 307 |
+ </object>
|
|
| 131 | 308 |
<object class="GtkGrid" id="tooltip">
|
| 132 | 309 |
<property name="visible">True</property>
|
| 133 | 310 |
<property name="can_focus">False</property>
|
| ... | ... | @@ -227,6 +227,7 @@ list.settings > row > box { |
| 227 | 227 |
/* Padding/Margins */
|
| 228 | 228 |
.margin-top6 { margin-top: 6px; }
|
| 229 | 229 |
.margin-12 { margin: 12px; }
|
| 230 |
+.margin-18 { margin: 18px; }
|
|
| 230 | 231 |
|
| 231 | 232 |
/* Treeview */
|
| 232 | 233 |
treeview.space { padding: 6px; }
|
| ... | ... | @@ -27,11 +27,6 @@ from gajim.gtk.dialogs import InformationDialog |
| 27 | 27 |
Message = namedtuple('Message', ['title', 'text', 'dialog'])
|
| 28 | 28 |
|
| 29 | 29 |
messages = {
|
| 30 |
- 'start-chat-not-connected': Message(
|
|
| 31 |
- _('You are not connected to the server'),
|
|
| 32 |
- _('You can not start a new conversation unless you are connected.'),
|
|
| 33 |
- ErrorDialog),
|
|
| 34 |
- |
|
| 35 | 30 |
'invalid-jid-with-error': Message(
|
| 36 | 31 |
_('Invalid JID'),
|
| 37 | 32 |
'%s',
|
| ... | ... | @@ -93,9 +93,10 @@ MUC_FEATURES = { |
| 93 | 93 |
|
| 94 | 94 |
|
| 95 | 95 |
class GroupChatInfoScrolled(Gtk.ScrolledWindow):
|
| 96 |
- def __init__(self, account):
|
|
| 96 |
+ def __init__(self, account=None):
|
|
| 97 | 97 |
Gtk.ScrolledWindow.__init__(self)
|
| 98 | 98 |
self.set_size_request(400, -1)
|
| 99 |
+ self.set_vexpand(True)
|
|
| 99 | 100 |
self.set_min_content_height(400)
|
| 100 | 101 |
self.set_policy(Gtk.PolicyType.NEVER,
|
| 101 | 102 |
Gtk.PolicyType.AUTOMATIC)
|
| ... | ... | @@ -105,6 +106,9 @@ class GroupChatInfoScrolled(Gtk.ScrolledWindow): |
| 105 | 106 |
self._ui.connect_signals(self)
|
| 106 | 107 |
self.show_all()
|
| 107 | 108 |
|
| 109 |
+ def set_account(self, account):
|
|
| 110 |
+ self._account = account
|
|
| 111 |
+ |
|
| 108 | 112 |
def set_author(self, author, epoch_timestamp=None):
|
| 109 | 113 |
if not author:
|
| 110 | 114 |
return
|
| ... | ... | @@ -181,6 +185,11 @@ class GroupChatInfoScrolled(Gtk.ScrolledWindow): |
| 181 | 185 |
|
| 182 | 186 |
def _add_features(self, features):
|
| 183 | 187 |
grid = self._ui.info_grid
|
| 188 |
+ for row in range(30, 9, -1):
|
|
| 189 |
+ # Remove everything from row 30 to 10
|
|
| 190 |
+ # We probably will never have 30 rows and
|
|
| 191 |
+ # there is no method to count grid rows
|
|
| 192 |
+ grid.remove_row(row)
|
|
| 184 | 193 |
features = list(features)
|
| 185 | 194 |
|
| 186 | 195 |
has_mam = NS_MAM_2 in features or NS_MAM_1 in features
|
| ... | ... | @@ -20,6 +20,8 @@ from gi.repository import Gtk |
| 20 | 20 |
from gi.repository import GLib
|
| 21 | 21 |
from gi.repository import Pango
|
| 22 | 22 |
|
| 23 |
+from nbxmpp.protocol import InvalidJid
|
|
| 24 |
+from nbxmpp.protocol import JID
|
|
| 23 | 25 |
from nbxmpp.util import is_error_result
|
| 24 | 26 |
from nbxmpp.const import AnonymityMode
|
| 25 | 27 |
|
| ... | ... | @@ -27,7 +29,9 @@ from gajim.common import app |
| 27 | 29 |
from gajim.common import helpers
|
| 28 | 30 |
from gajim.common.i18n import _
|
| 29 | 31 |
from gajim.common.const import AvatarSize
|
| 32 |
+from gajim.common.const import MUC_DISCO_ERRORS
|
|
| 30 | 33 |
|
| 34 |
+from gajim.gtk.groupchat_info import GroupChatInfoScrolled
|
|
| 31 | 35 |
from gajim.gtk.util import get_icon_name
|
| 32 | 36 |
from gajim.gtk.util import get_builder
|
| 33 | 37 |
from gajim.gtk.util import ensure_not_destroyed
|
| ... | ... | @@ -56,7 +60,7 @@ class StartChatDialog(Gtk.ApplicationWindow): |
| 56 | 60 |
self._search_stopped = False
|
| 57 | 61 |
|
| 58 | 62 |
self._ui = get_builder('start_chat_dialog.ui')
|
| 59 |
- self.add(self._ui.box)
|
|
| 63 |
+ self.add(self._ui.stack)
|
|
| 60 | 64 |
|
| 61 | 65 |
self.new_contact_row_visible = False
|
| 62 | 66 |
self.new_contact_rows = {}
|
| ... | ... | @@ -81,10 +85,14 @@ class StartChatDialog(Gtk.ApplicationWindow): |
| 81 | 85 |
self._muc_search_listbox = MUCSearch()
|
| 82 | 86 |
self._current_listbox = self._ui.listbox
|
| 83 | 87 |
|
| 88 |
+ self._muc_info_box = GroupChatInfoScrolled()
|
|
| 89 |
+ self._ui.info_box.add(self._muc_info_box)
|
|
| 90 |
+ |
|
| 84 | 91 |
self.connect('key-press-event', self._on_key_press)
|
| 85 | 92 |
self.connect('destroy', self._destroy)
|
| 86 | 93 |
|
| 87 | 94 |
self.select_first_row()
|
| 95 |
+ self._ui.connect_signals(self)
|
|
| 88 | 96 |
self.show_all()
|
| 89 | 97 |
|
| 90 | 98 |
def set_search_text(self, text):
|
| ... | ... | @@ -126,64 +134,131 @@ class StartChatDialog(Gtk.ApplicationWindow): |
| 126 | 134 |
show_account, True)
|
| 127 | 135 |
self._ui.listbox.add(row)
|
| 128 | 136 |
|
| 129 |
- def _on_row_activated(self, listbox, row):
|
|
| 137 |
+ def _on_row_activated(self, _listbox, row):
|
|
| 130 | 138 |
row = row.get_child()
|
| 131 | 139 |
self._start_new_chat(row)
|
| 132 | 140 |
|
| 133 |
- def _on_key_press(self, widget, event):
|
|
| 141 |
+ def _on_key_press(self, _widget, event):
|
|
| 142 |
+ is_search = self._ui.stack.get_visible_child_name() == 'search'
|
|
| 134 | 143 |
if event.keyval in (Gdk.KEY_Down, Gdk.KEY_Tab):
|
| 135 |
- self._ui.search_entry.emit('next-match')
|
|
| 136 |
- return True
|
|
| 144 |
+ if is_search:
|
|
| 145 |
+ self._ui.search_entry.emit('next-match')
|
|
| 146 |
+ return Gdk.EVENT_STOP
|
|
| 147 |
+ return Gdk.EVENT_PROPAGATE
|
|
| 137 | 148 |
|
| 138 | 149 |
if (event.state == Gdk.ModifierType.SHIFT_MASK and
|
| 139 | 150 |
event.keyval == Gdk.KEY_ISO_Left_Tab):
|
| 140 |
- self._ui.search_entry.emit('previous-match')
|
|
| 141 |
- return True
|
|
| 151 |
+ if is_search:
|
|
| 152 |
+ self._ui.search_entry.emit('previous-match')
|
|
| 153 |
+ return Gdk.EVENT_STOP
|
|
| 154 |
+ return Gdk.EVENT_PROPAGATE
|
|
| 142 | 155 |
|
| 143 | 156 |
if event.keyval == Gdk.KEY_Up:
|
| 144 |
- self._ui.search_entry.emit('previous-match')
|
|
| 145 |
- return True
|
|
| 157 |
+ if is_search:
|
|
| 158 |
+ self._ui.search_entry.emit('previous-match')
|
|
| 159 |
+ return Gdk.EVENT_STOP
|
|
| 160 |
+ return Gdk.EVENT_PROPAGATE
|
|
| 146 | 161 |
|
| 147 | 162 |
if event.keyval == Gdk.KEY_Escape:
|
| 163 |
+ if self._ui.stack.get_visible_child_name() == 'progress':
|
|
| 164 |
+ self.destroy()
|
|
| 165 |
+ return Gdk.EVENT_STOP
|
|
| 166 |
+ |
|
| 167 |
+ if self._ui.stack.get_visible_child_name() in ('error', 'info'):
|
|
| 168 |
+ self._ui.stack.set_visible_child_name('search')
|
|
| 169 |
+ return Gdk.EVENT_STOP
|
|
| 170 |
+ |
|
| 148 | 171 |
self._search_stopped = True
|
| 149 | 172 |
self._muc_search_listbox.remove_all()
|
| 150 | 173 |
if self._ui.search_entry.get_text() != '':
|
| 151 | 174 |
self._ui.search_entry.emit('stop-search')
|
| 152 | 175 |
else:
|
| 153 | 176 |
self.destroy()
|
| 154 |
- return True
|
|
| 177 |
+ return Gdk.EVENT_STOP
|
|
| 155 | 178 |
|
| 156 | 179 |
if event.keyval == Gdk.KEY_Return:
|
| 180 |
+ if self._ui.stack.get_visible_child_name() == 'progress':
|
|
| 181 |
+ return Gdk.EVENT_STOP
|
|
| 182 |
+ |
|
| 183 |
+ if self._ui.stack.get_visible_child_name() == 'error':
|
|
| 184 |
+ self._ui.stack.set_visible_child_name('search')
|
|
| 185 |
+ return Gdk.EVENT_STOP
|
|
| 186 |
+ |
|
| 187 |
+ if self._ui.stack.get_visible_child_name() == 'info':
|
|
| 188 |
+ self._on_join_clicked()
|
|
| 189 |
+ return Gdk.EVENT_STOP
|
|
| 190 |
+ |
|
| 157 | 191 |
if self._current_listbox_is(Search.MUC):
|
| 158 | 192 |
self._muc_search_listbox.remove_all()
|
| 159 | 193 |
self._start_search()
|
| 160 |
- return True
|
|
| 194 |
+ return Gdk.EVENT_STOP
|
|
| 161 | 195 |
|
| 162 | 196 |
row = self._ui.listbox.get_selected_row()
|
| 163 | 197 |
if row is not None:
|
| 164 | 198 |
row.emit('activate')
|
| 165 |
- return True
|
|
| 199 |
+ return Gdk.EVENT_STOP
|
|
| 166 | 200 |
|
| 167 |
- self._ui.search_entry.grab_focus_without_selecting()
|
|
| 201 |
+ if is_search:
|
|
| 202 |
+ self._ui.search_entry.grab_focus_without_selecting()
|
|
| 203 |
+ return Gdk.EVENT_PROPAGATE
|
|
| 168 | 204 |
|
| 169 | 205 |
def _start_new_chat(self, row):
|
| 170 | 206 |
if row.new:
|
| 171 |
- if not app.account_is_connected(row.account):
|
|
| 172 |
- app.interface.raise_dialog('start-chat-not-connected')
|
|
| 173 |
- return
|
|
| 174 | 207 |
try:
|
| 175 |
- helpers.parse_jid(row.jid)
|
|
| 176 |
- except helpers.InvalidFormat as e:
|
|
| 177 |
- app.interface.raise_dialog('invalid-jid-with-error', str(e))
|
|
| 208 |
+ JID(row.jid)
|
|
| 209 |
+ except InvalidJid as error:
|
|
| 210 |
+ self._show_error_page(str(error))
|
|
| 178 | 211 |
return
|
| 179 | 212 |
|
| 180 | 213 |
if row.groupchat:
|
| 181 |
- app.interface.join_gc_minimal(row.account, row.jid)
|
|
| 214 |
+ if not app.account_is_connected(row.account):
|
|
| 215 |
+ self._show_error_page(_('You can not join a group chat '
|
|
| 216 |
+ 'unless you are connected.'))
|
|
| 217 |
+ return
|
|
| 218 |
+ self._disco_muc(row.account, row.jid)
|
|
| 182 | 219 |
else:
|
| 183 | 220 |
app.interface.new_chat_from_jid(row.account, row.jid)
|
| 184 | 221 |
|
| 185 | 222 |
self.ready_to_destroy = True
|
| 186 | 223 |
|
| 224 |
+ def _disco_muc(self, account, jid):
|
|
| 225 |
+ self._ui.stack.set_visible_child_name('progress')
|
|
| 226 |
+ con = app.connections[account]
|
|
| 227 |
+ con.get_module('Discovery').disco_info(
|
|
| 228 |
+ jid, callback=self._disco_info_received, user_data=account)
|
|
| 229 |
+ |
|
| 230 |
+ @ensure_not_destroyed
|
|
| 231 |
+ def _disco_info_received(self, result, account):
|
|
| 232 |
+ if is_error_result(result):
|
|
| 233 |
+ self._set_error(result)
|
|
| 234 |
+ |
|
| 235 |
+ elif result.is_muc:
|
|
| 236 |
+ self._muc_info_box.set_account(account)
|
|
| 237 |
+ self._muc_info_box.set_from_disco_info(result)
|
|
| 238 |
+ self._ui.stack.set_visible_child_name('info')
|
|
| 239 |
+ |
|
| 240 |
+ else:
|
|
| 241 |
+ self._set_error_from_code('not-muc-service')
|
|
| 242 |
+ |
|
| 243 |
+ def _set_error(self, error):
|
|
| 244 |
+ text = MUC_DISCO_ERRORS.get(error.type, str(error))
|
|
| 245 |
+ self._show_error_page(text)
|
|
| 246 |
+ |
|
| 247 |
+ def _set_error_from_code(self, error_code):
|
|
| 248 |
+ self._show_error_page(MUC_DISCO_ERRORS[error_code])
|
|
| 249 |
+ |
|
| 250 |
+ def _show_error_page(self, text):
|
|
| 251 |
+ self._ui.error_label.set_text(text)
|
|
| 252 |
+ self._ui.stack.set_visible_child_name('error')
|
|
| 253 |
+ |
|
| 254 |
+ def _on_join_clicked(self, _button=None):
|
|
| 255 |
+ row = self._ui.listbox.get_selected_row().get_child()
|
|
| 256 |
+ app.interface.join_gc_minimal(row.account, row.jid)
|
|
| 257 |
+ self.ready_to_destroy = True
|
|
| 258 |
+ |
|
| 259 |
+ def _on_back_clicked(self, _button):
|
|
| 260 |
+ self._ui.stack.set_visible_child_name('search')
|
|
| 261 |
+ |
|
| 187 | 262 |
def _set_listbox(self, listbox):
|
| 188 | 263 |
if self._current_listbox == listbox:
|
| 189 | 264 |
return
|
| ... | ... | @@ -241,7 +316,7 @@ class StartChatDialog(Gtk.ApplicationWindow): |
| 241 | 316 |
self.new_contact_rows[account].update_jid(search_text)
|
| 242 | 317 |
self.new_groupchat_rows[account].update_jid(search_text)
|
| 243 | 318 |
|
| 244 |
- def _select_new_match(self, entry, direction):
|
|
| 319 |
+ def _select_new_match(self, _entry, direction):
|
|
| 245 | 320 |
selected_row = self._ui.listbox.get_selected_row()
|
| 246 | 321 |
if selected_row is None:
|
| 247 | 322 |
return
|
| ... | ... | @@ -270,19 +345,19 @@ class StartChatDialog(Gtk.ApplicationWindow): |
| 270 | 345 |
first_row = self._ui.listbox.get_row_at_y(0)
|
| 271 | 346 |
self._ui.listbox.select_row(first_row)
|
| 272 | 347 |
|
| 273 |
- def _filter_func(self, row, user_data):
|
|
| 348 |
+ def _filter_func(self, row, _user_data):
|
|
| 274 | 349 |
search_text = self._ui.search_entry.get_text().lower()
|
| 275 | 350 |
search_text_list = search_text.split()
|
| 276 | 351 |
row_text = row.get_child().get_search_text().lower()
|
| 277 | 352 |
for text in search_text_list:
|
| 278 | 353 |
if text not in row_text:
|
| 279 | 354 |
GLib.timeout_add(50, self.select_first_row)
|
| 280 |
- return
|
|
| 355 |
+ return None
|
|
| 281 | 356 |
GLib.timeout_add(50, self.select_first_row)
|
| 282 | 357 |
return True
|
| 283 | 358 |
|
| 284 | 359 |
@staticmethod
|
| 285 |
- def _sort_func(row1, row2, user_data):
|
|
| 360 |
+ def _sort_func(row1, row2, _user_data):
|
|
| 286 | 361 |
name1 = row1.get_child().get_search_text()
|
| 287 | 362 |
name2 = row2.get_child().get_search_text()
|
| 288 | 363 |
account1 = row1.get_child().account
|
| ... | ... | @@ -539,7 +614,8 @@ class MUCSearch(Gtk.ListBox): |
| 539 | 614 |
self._ui.tooltip_name.hide()
|
| 540 | 615 |
self._ui.tooltip_name_label.hide()
|
| 541 | 616 |
|
| 542 |
- def _on_row_activated(self, _listbox, row):
|
|
| 617 |
+ @staticmethod
|
|
| 618 |
+ def _on_row_activated(_listbox, row):
|
|
| 543 | 619 |
app.interface.join_gc_minimal(None, row.item.jid)
|
| 544 | 620 |
|
| 545 | 621 |
|
| ... | ... | @@ -1441,7 +1441,7 @@ class Interface: |
| 1441 | 1441 |
bookmark = con.get_module('Bookmarks').get_bookmark_from_jid(room_jid)
|
| 1442 | 1442 |
if bookmark is not None:
|
| 1443 | 1443 |
app.interface.join_gc_room(
|
| 1444 |
- account, bookmark.jid, bookmark.nick, bookmark.password)
|
|
| 1444 |
+ account, str(bookmark.jid), bookmark.nick, bookmark.password)
|
|
| 1445 | 1445 |
return
|
| 1446 | 1446 |
|
| 1447 | 1447 |
try:
|
| ... | ... | @@ -221,7 +221,7 @@ class GajimRemote(Server): |
| 221 | 221 |
<method name='show_next_pending_event' />
|
| 222 | 222 |
<method name='show_roster' />
|
| 223 | 223 |
<method name='start_chat'>
|
| 224 |
- <arg name='account' type='s' />
|
|
| 224 |
+ <arg name='jid' type='s' />
|
|
| 225 | 225 |
<arg direction='out' type='b' />
|
| 226 | 226 |
</method>
|
| 227 | 227 |
<method name='toggle_ipython' />
|
| ... | ... | @@ -884,11 +884,8 @@ class GajimRemote(Server): |
| 884 | 884 |
unread -= 1
|
| 885 | 885 |
return str(unread)
|
| 886 | 886 |
|
| 887 |
- def start_chat(self, account):
|
|
| 888 |
- if not account:
|
|
| 889 |
- # error is shown in gajim-remote check_arguments(..)
|
|
| 890 |
- return False
|
|
| 891 |
- app.app.activate_action('start-chat', GLib.Variant('s', ''))
|
|
| 887 |
+ def start_chat(self, jid=''):
|
|
| 888 |
+ app.app.activate_action('start-chat', GLib.Variant('s', jid))
|
|
| 892 | 889 |
return True
|
| 893 | 890 |
|
| 894 | 891 |
def send_xml(self, xml, account):
|