Status: | Merged |
---|---|
Merged at revision: | 139 |
Proposed branch: | lp:~julien-spautz/cable/pm |
Merge into: | lp:cable |
Diff against target: |
1358 lines (+509/-388) 16 files modified
CMakeLists.txt (+2/-0) src/Controller/Channel.vala (+18/-17) src/Controller/PrivateChat.vala (+85/-0) src/Controller/Server.vala (+32/-12) src/Controller/Window.vala (+28/-38) src/Utils/HostMask.vala (+31/-0) src/View/Channel.vala (+22/-22) src/View/Server.vala (+21/-54) src/View/Window.vala (+2/-2) src/Widgets/Channel.vala (+68/-61) src/Widgets/ChatDisplay.vala (+1/-24) src/Widgets/Room.vala (+38/-118) src/Widgets/Server.vala (+26/-35) src/Widgets/User.vala (+8/-0) src/Widgets/UserList.vala (+122/-0) src/Widgets/Window.vala (+5/-5) |
To merge this branch: | bzr merge lp:~julien-spautz/cable/pm |
Related bugs: | |
Related blueprints: |
Private Chats
(High)
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Julien Spautz | Approve | ||
Review via email: mp+186069@code.launchpad.net |
Commit message
Description of the change
This branch implements basic private chat features.
A chat will be opened when you receive a /msg or when you double click on a name in the user list.
To post a comment you must log in.
Revision history for this message
Julien Spautz (julien-spautz) wrote : | # |
Revision history for this message
982c80311320c1b (alexander-wilms) wrote : | # |
Compiles and works as expected
Revision history for this message
Daniele "OpenNingia" Simonetti (oppifjellet) wrote : | # |
Compiles and works with some quirks:
* You can have a private chat with yourself that is quite confusing.
* IRC commands ( e.g. /join ) don't work in the private chat window.
lp:~julien-spautz/cable/pm
updated
- 146. By Julien Spautz
-
don't allow talking to yourself (you weirdo)
Revision history for this message
Julien Spautz (julien-spautz) wrote : | # |
Private chats with yourself have been fixed.
IRC commands will need some more code shifting, but I don't want to unnecessarily bloat the diff, so that's for another merge.
This branch should allow basic private chat functionality including opening chats by double clicking a name and when receiving a /msg.
Revision history for this message
Julien Spautz (julien-spautz) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'CMakeLists.txt' |
2 | --- CMakeLists.txt 2013-09-14 18:12:05 +0000 |
3 | +++ CMakeLists.txt 2013-09-22 16:58:59 +0000 |
4 | @@ -69,6 +69,7 @@ |
5 | src/Controller/Window.vala |
6 | src/Controller/Server.vala |
7 | src/Controller/Channel.vala |
8 | + src/Controller/PrivateChat.vala |
9 | |
10 | src/View/Server.vala |
11 | src/View/Channel.vala |
12 | @@ -89,6 +90,7 @@ |
13 | src/Widgets/Room.vala |
14 | src/Widgets/ChatDisplay.vala |
15 | src/Widgets/User.vala |
16 | + src/Widgets/UserList.vala |
17 | src/Widgets/TopicBar.vala |
18 | |
19 | src/Dialogs/JoinChannel.vala |
20 | |
21 | === modified file 'src/Controller/Channel.vala' |
22 | --- src/Controller/Channel.vala 2013-09-14 12:55:26 +0000 |
23 | +++ src/Controller/Channel.vala 2013-09-22 16:58:59 +0000 |
24 | @@ -17,24 +17,22 @@ |
25 | Boston, MA 02110-1301 USA. |
26 | ***/ |
27 | |
28 | -internal class Cable.Controller.Channel : GLib.Object { |
29 | - |
30 | - internal weak Server server; |
31 | - internal View.Channel view; |
32 | - internal Irc.Channel backend; |
33 | - |
34 | - internal string name; //TODO id |
35 | - |
36 | - internal Channel (Server server, string name) { |
37 | - debug (@"+ CONTROLLER CHANNEL $name"); |
38 | - |
39 | +public class Cable.Controller.Channel : GLib.Object { |
40 | + |
41 | + public weak Server server; |
42 | + public View.Channel view; |
43 | + public Irc.Channel backend; |
44 | + |
45 | + public string name; //TODO id |
46 | + |
47 | + public Channel (Server server, string name) { |
48 | this.server = server; |
49 | this.name = name; |
50 | |
51 | - if (server.view.has_channel (name) == false) |
52 | + if (server.view.has_chat (name) == false) |
53 | server.view.add_channel (name, name); |
54 | |
55 | - view = server.view.get_channel_by_id (name); |
56 | + view = server.view.get_chat (name) as View.Channel; |
57 | view.nick = server.nick; |
58 | backend = new Irc.Channel (name, server.backend); |
59 | |
60 | @@ -44,8 +42,6 @@ |
61 | load_state (); |
62 | } |
63 | |
64 | - ~Channel () { debug (@"- CONTROLLER CHANNEL $name"); } |
65 | - |
66 | void load_state () { |
67 | /*if (backend.joined) { |
68 | view.room.state = Widgets.Room.State.CHAT; |
69 | @@ -102,12 +98,17 @@ |
70 | return false; |
71 | }); |
72 | |
73 | + view.private_chat_requested.connect ((name) => { |
74 | + server.open_new_chat_with (name); |
75 | + if (server.private_chats.has_key (name)) |
76 | + server.window.view.current_chat = server.private_chats [name].view; |
77 | + }); |
78 | } |
79 | |
80 | // IRC signals |
81 | void connect_backend_signals () { |
82 | backend.event_message.connect ((from, message) => { |
83 | - if (server.window.view.current_channel != view) |
84 | + if (server.window.view.current_chat != view) |
85 | view.unread_messages++; |
86 | }); |
87 | |
88 | @@ -207,7 +208,7 @@ |
89 | } |
90 | var channel = new Channel (server, channel_with_hash); |
91 | server.channels[channel_with_hash] = channel; |
92 | - server.window.view.current_channel = channel.view; |
93 | + server.window.view.current_chat = channel.view; |
94 | break; |
95 | |
96 | case "part": |
97 | |
98 | === added file 'src/Controller/PrivateChat.vala' |
99 | --- src/Controller/PrivateChat.vala 1970-01-01 00:00:00 +0000 |
100 | +++ src/Controller/PrivateChat.vala 2013-09-22 16:58:59 +0000 |
101 | @@ -0,0 +1,85 @@ |
102 | +/*** |
103 | + Copyright (C) 2013 Cable Developers |
104 | + |
105 | + This program or library is free software; you can redistribute it |
106 | + and/or modify it under the terms of the GNU Lesser General Public |
107 | + License as published by the Free Software Foundation; either |
108 | + version 3 of the License, or (at your option) any later version. |
109 | + |
110 | + This library is distributed in the hope that it will be useful, |
111 | + but WITHOUT ANY WARRANTY; without even the implied warranty of |
112 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
113 | + Lesser General Public License for more details. |
114 | + |
115 | + You should have received a copy of the GNU Lesser General |
116 | + Public License along with this library; if not, write to the |
117 | + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
118 | + Boston, MA 02110-1301 USA. |
119 | +***/ |
120 | + |
121 | +public class Cable.Controller.PrivateChat : GLib.Object { |
122 | + |
123 | + public weak Server server; |
124 | + public View.PrivateChat view; |
125 | + string id; |
126 | + |
127 | + public PrivateChat (Server server, string id, string? message = null) { |
128 | + this.id = id; |
129 | + this.server = server; |
130 | + |
131 | + server.view.add_private_chat (id, id); |
132 | + view = server.view.get_chat (id) as View.PrivateChat; |
133 | + view.nick = server.nick; |
134 | + |
135 | + if (message != null) |
136 | + on_backend_message (id, server.nick, message); |
137 | + |
138 | + connect_signals (); |
139 | + } |
140 | + |
141 | + void connect_signals () { |
142 | + server.backend.event_message.connect (on_backend_message); |
143 | + view.send_message.connect (on_frontend_message); |
144 | + server.window.view.selected.connect (on_chat_selected); |
145 | + } |
146 | + |
147 | + void on_backend_message (string from, string target, string message) { |
148 | + if (is_not_me (target)) |
149 | + return; |
150 | + |
151 | + if (is_not_correspondent (from)) |
152 | + return; |
153 | + |
154 | + var nick_from = from.split ("!")[0]; |
155 | + |
156 | + view.message (nick_from, message); |
157 | + |
158 | + if (view.has_focus == false) { |
159 | + Services.Notify.send (nick_from, message); |
160 | + Services.Launcher.jobs++; |
161 | + Services.Launcher.urgent = true; |
162 | + } |
163 | + |
164 | + if (server.window.view.current_chat != view) |
165 | + view.unread_messages++; |
166 | + } |
167 | + |
168 | + void on_frontend_message (string message) { |
169 | + server.backend.send_message (id.split("!")[0], message); |
170 | + view.message (server.nick, message); |
171 | + view.entry = ""; |
172 | + } |
173 | + |
174 | + void on_chat_selected (View.Chat chat) { |
175 | + if (chat == view) |
176 | + view.unread_messages = 0; |
177 | + } |
178 | + |
179 | + bool is_not_me (string nick) { |
180 | + return nick != server.nick; |
181 | + } |
182 | + |
183 | + bool is_not_correspondent (string from) { |
184 | + return from.split ("!")[0] != id; |
185 | + } |
186 | +} |
187 | |
188 | === modified file 'src/Controller/Server.vala' |
189 | --- src/Controller/Server.vala 2013-08-25 18:02:19 +0000 |
190 | +++ src/Controller/Server.vala 2013-09-22 16:58:59 +0000 |
191 | @@ -17,22 +17,25 @@ |
192 | Boston, MA 02110-1301 USA. |
193 | ***/ |
194 | |
195 | -internal class Cable.Controller.Server : GLib.Object { |
196 | +public class Cable.Controller.Server : GLib.Object { |
197 | |
198 | - internal weak Window window; |
199 | - internal View.Server view; |
200 | - internal Irc.Server backend; |
201 | + public weak Window window; |
202 | + public View.Server view; |
203 | + public Irc.Server backend; |
204 | |
205 | - internal string nick; // FIXME not reliable |
206 | - internal string address; // FIXME not reliable |
207 | - internal string name; |
208 | + public string nick; // FIXME not reliable |
209 | + public string address; // FIXME not reliable |
210 | + public string name; |
211 | |
212 | - internal Gee.HashMap <string, Channel> channels { |
213 | + public Gee.HashMap <string, Channel> channels { |
214 | get; set; default = new Gee.HashMap <string, Channel> (); |
215 | } |
216 | + |
217 | + public Gee.HashMap <string, PrivateChat> private_chats { |
218 | + get; set; default = new Gee.HashMap <string, PrivateChat> (); |
219 | + } |
220 | |
221 | - internal Server (string address, string nick, Window window) { |
222 | - debug (@"+ CONTROLLER SERVER $address"); |
223 | + public Server (string address, string nick, Window window) { |
224 | this.backend = Irc.Server.get_or_create (address, nick); |
225 | |
226 | this.name = backend.name; |
227 | @@ -49,8 +52,6 @@ |
228 | connect_backend_signals (); |
229 | } |
230 | |
231 | - ~Server () { debug (@"- CONTROLLER SERVER $address"); } |
232 | - |
233 | void connect_frontend_signals () { |
234 | view.toggle_away.connect (() => { |
235 | if (backend.away) { |
236 | @@ -85,5 +86,24 @@ |
237 | foreach (var channel in channels.values) |
238 | channel.view.remove_user (nick, message); |
239 | }); |
240 | + |
241 | + backend.event_message.connect ((from, target, message) => { |
242 | + if (target != nick) |
243 | + return; |
244 | + |
245 | + var from_nick = from.split ("!")[0]; |
246 | + |
247 | + open_new_chat_with (from_nick, message); |
248 | + }); |
249 | + } |
250 | + |
251 | + public void open_new_chat_with (string from_nick, string message = "") { |
252 | + if (from_nick == backend.nick) |
253 | + return; |
254 | + |
255 | + if (!private_chats.has_key (from_nick)) { |
256 | + var chat = new PrivateChat (this, from_nick, message); |
257 | + private_chats [from_nick] = chat; |
258 | + } |
259 | } |
260 | } |
261 | |
262 | === modified file 'src/Controller/Window.vala' |
263 | --- src/Controller/Window.vala 2013-09-12 20:26:19 +0000 |
264 | +++ src/Controller/Window.vala 2013-09-22 16:58:59 +0000 |
265 | @@ -17,16 +17,16 @@ |
266 | Boston, MA 02110-1301 USA. |
267 | ***/ |
268 | |
269 | -internal class Cable.Controller.Window : GLib.Object { |
270 | - |
271 | - internal View.Window view { get; set; } |
272 | - |
273 | - internal Gee.HashMap <string, Server> servers { |
274 | +public class Cable.Controller.Window : GLib.Object { |
275 | + |
276 | + public View.Window view { get; set; } |
277 | + |
278 | + public Gee.HashMap <string, Server> servers { |
279 | get; set; |
280 | default = new Gee.HashMap <string, Server> (); |
281 | } |
282 | |
283 | - internal Window (View.Window window) { |
284 | + public Window (View.Window window) { |
285 | GLib.Object (view: window); |
286 | |
287 | connect_frontend_signals (); |
288 | @@ -61,11 +61,11 @@ |
289 | // backend events that affect the window's state |
290 | void connect_backend_signals () { |
291 | Irc.client.event_nick.connect ((time, server, from, nick) => { |
292 | - var current_channel = view.current_channel; |
293 | + var current_chat = view.current_chat; |
294 | var current_server = view.current_server; |
295 | |
296 | if (server == current_server.id) |
297 | - view.title = string.join (" — ", current_channel.name, nick); |
298 | + view.title = string.join (" — ", current_chat.name, nick); |
299 | }); |
300 | } |
301 | |
302 | @@ -84,13 +84,26 @@ |
303 | }); |
304 | |
305 | view.remove_channel.connect (() => { |
306 | - var channel_id = view.current_channel.id; |
307 | + var channel_id = view.current_chat.id; |
308 | var server_id = view.current_server.id; |
309 | |
310 | - if (view.current_channel != null) { |
311 | + if (view.current_chat == null) { |
312 | + warning ("No channel selected, cannot leave."); |
313 | + } else if (view.current_chat is View.Channel) { |
314 | part_channel (servers[server_id].channels[channel_id]); |
315 | - } else { |
316 | - warning ("No channel selected, cannot leave."); |
317 | + } else if (view.current_chat is View.PrivateChat) { |
318 | + var channel = servers[server_id].private_chats[channel_id]; |
319 | + var server = channel.server; |
320 | + server.view.remove_chat (channel.view.id); |
321 | + server.private_chats.unset (channel.view.id); |
322 | + |
323 | + if (server.channels.size == 0) |
324 | + servers.unset (server.view.id); |
325 | + |
326 | + if (servers.size == 0) { |
327 | + view.title = App.TITLE; |
328 | + view.welcome_shown = true; |
329 | + } |
330 | } |
331 | }); |
332 | |
333 | @@ -130,7 +143,7 @@ |
334 | servers[server.backend.name] = server; |
335 | } |
336 | |
337 | - if (server.view.has_channel (channel_name)) { |
338 | + if (server.view.has_chat (channel_name)) { |
339 | warning ("Channel is already joined"); |
340 | return; |
341 | } |
342 | @@ -138,7 +151,7 @@ |
343 | var channel = new Channel (server, channel_name); |
344 | server.channels[channel_name] = channel; |
345 | |
346 | - view.current_channel = channel.view; |
347 | + view.current_chat = channel.view; |
348 | view.welcome_shown = false; |
349 | } |
350 | |
351 | @@ -146,7 +159,7 @@ |
352 | var server = channel.server; |
353 | |
354 | channel.backend.send_part (); |
355 | - server.view.remove_channel (channel.view.id); |
356 | + server.view.remove_chat (channel.view.id); |
357 | server.channels.unset (channel.view.id); |
358 | |
359 | if (server.channels.size == 0) |
360 | @@ -157,27 +170,4 @@ |
361 | view.welcome_shown = true; |
362 | } |
363 | } |
364 | - |
365 | - /*void leave_channel (Settings.Network network, Settings.Identity identity, string channel_name) { |
366 | - var server_backend = Irc.Server.search (network.address, identity.nick_name); |
367 | - |
368 | - var server_view = servers[server_backend.name].view; |
369 | - |
370 | - if (server_view == null) { |
371 | - warning ("Cannot leave channel: server does not exist (%s - %s)", network.address, identity.nick_name); |
372 | - return; |
373 | - } |
374 | - if (!server_view.has_channel (channel_name)) { |
375 | - warning ("Cannot leave channel: channel not joined (%s)", channel_name); |
376 | - return; |
377 | - } |
378 | - |
379 | - server_view.remove_channel (channel_name); |
380 | - server_backend.send_part (channel_name); |
381 | - |
382 | - if (view.n_servers == 0) { |
383 | - view.title = App.TITLE; |
384 | - view.welcome_shown = true; |
385 | - } |
386 | - }*/ |
387 | } |
388 | |
389 | === added file 'src/Utils/HostMask.vala' |
390 | --- src/Utils/HostMask.vala 1970-01-01 00:00:00 +0000 |
391 | +++ src/Utils/HostMask.vala 2013-09-22 16:58:59 +0000 |
392 | @@ -0,0 +1,31 @@ |
393 | +// parses a hostmask in form of <nick>!<user>@<host> |
394 | +/*public class Cable.Utils.HostMask : GLib.Object { // TODO use this |
395 | + |
396 | + string nick { get; private set; } |
397 | + string user { get; private set; } |
398 | + string host { get; private set; } |
399 | + |
400 | + public HostMask (string hostmask) |
401 | + requires (is_well_formed (hostmask)) { |
402 | + |
403 | + var first_split = hostmask.split ("!", 2); |
404 | + var user_and_host = first_split[1]; |
405 | + var second_split = user_and_host.split ("@", 2); |
406 | + |
407 | + this.nick = first_split[0]; |
408 | + this.user = second_split[0]; |
409 | + this.host = second_split[1]; |
410 | + } |
411 | + |
412 | + bool is_well_formed (string hostmask) { |
413 | + if ("!" in hostmask == false) |
414 | + return false; |
415 | + |
416 | + var remainder = hostmask.split ("!", 2)[-1]; |
417 | + |
418 | + if ("@" in remainder == false); |
419 | + return false; |
420 | + |
421 | + return true; |
422 | + } |
423 | +}*/ |
424 | \ No newline at end of file |
425 | |
426 | === modified file 'src/View/Channel.vala' |
427 | --- src/View/Channel.vala 2013-08-16 15:31:17 +0000 |
428 | +++ src/View/Channel.vala 2013-09-22 16:58:59 +0000 |
429 | @@ -17,42 +17,42 @@ |
430 | Boston, MA 02110-1301 USA. |
431 | ***/ |
432 | |
433 | -public interface Cable.View.Channel : GLib.Object { |
434 | +public interface Cable.View.Chat : GLib.Object { |
435 | |
436 | public abstract int unread_messages { get; set; } |
437 | - |
438 | public abstract string nick { get; set; } |
439 | - |
440 | public abstract string name { get; set; } |
441 | - |
442 | - public abstract State state { get; set; } |
443 | - |
444 | - public abstract string topic { get; set; } |
445 | - |
446 | public abstract string id { get; set; } |
447 | - |
448 | public abstract string entry { get; set; } |
449 | - |
450 | public abstract bool has_focus { get; } |
451 | + |
452 | + public signal void send_message (string message); |
453 | + public signal bool focused (); |
454 | + |
455 | + public abstract void rename_user (string? old_nick, string new_nick, UserType type, bool silent = false); |
456 | + public abstract void set_away_status (string nick, bool is_away); |
457 | + public abstract void message (owned string from, string message, MessageType type = MessageType.NORMAL); |
458 | +} |
459 | + |
460 | +public interface Cable.View.Channel : GLib.Object, View.Chat { |
461 | + |
462 | + public abstract State state { get; set; } |
463 | + public abstract string topic { get; set; } |
464 | |
465 | public signal void join (); |
466 | - |
467 | public signal void part (); |
468 | - |
469 | public signal void send_message (string message); |
470 | - |
471 | public signal bool focused (); |
472 | + public signal void private_chat_requested (string name); |
473 | |
474 | public abstract bool has_user (string nick); |
475 | - |
476 | public abstract void list_users (string[] nicks, string[] prefixes); |
477 | - |
478 | public abstract void add_user (string nick, UserType type, bool silent = false); |
479 | - |
480 | - public abstract bool remove_user (string nick, string message, bool silent = false); |
481 | - |
482 | - public abstract void rename_user (string? old_nick, string new_nick, UserType type, bool silent = false); |
483 | - public abstract void set_away_status (string nick, bool is_away); |
484 | - |
485 | - public abstract void message (owned string from, string message, MessageType type = MessageType.NORMAL); |
486 | + public abstract void remove_user (string nick, string message, bool silent = false); |
487 | +} |
488 | + |
489 | +public interface Cable.View.PrivateChat : GLib.Object, View.Chat { |
490 | + |
491 | + public signal void send_message (string message); |
492 | + public signal bool focused (); |
493 | } |
494 | |
495 | === modified file 'src/View/Server.vala' |
496 | --- src/View/Server.vala 2013-08-16 15:31:17 +0000 |
497 | +++ src/View/Server.vala 2013-09-22 16:58:59 +0000 |
498 | @@ -19,70 +19,37 @@ |
499 | |
500 | public interface Cable.View.Server : GLib.Object { |
501 | |
502 | - // TODO parent-tier reference (i.e. window tier) |
503 | - |
504 | - /** |
505 | - * Change the away status of this server. Set-only. |
506 | - */ |
507 | public abstract bool away { set; } |
508 | - |
509 | public abstract string name { get; set; } |
510 | - |
511 | public abstract string id { get; set; } |
512 | |
513 | - /** |
514 | - * List of all channels of this server. |
515 | - */ |
516 | - public abstract Gee.ArrayList <Channel> channels { owned get; } |
517 | - |
518 | - public abstract signal void toggle_away (); |
519 | - |
520 | - public abstract signal void part_all (); |
521 | - |
522 | - /** |
523 | - * Create and add a new channel to this server. |
524 | - * @param channel_name Name of the new channel. |
525 | - */ |
526 | - public abstract void add_channel (string channel_name, string channel_id); |
527 | - |
528 | - /** |
529 | - * Remove a channel from this server. |
530 | - * @param channel_name Name of the channel to be removed. |
531 | - */ |
532 | - public abstract void remove_channel (string channel_id); |
533 | - |
534 | - /** |
535 | - * Names of all owned channels. |
536 | - */ |
537 | - public string[] channel_ids { |
538 | + public abstract Gee.ArrayList <Chat> chats { owned get; } |
539 | + |
540 | + public string[] chat_ids { |
541 | owned get { |
542 | string[] result = {}; |
543 | - foreach (var channel in channels) |
544 | - result += channel.id; |
545 | + foreach (var chat in chats) |
546 | + result += chat.id; |
547 | return result; |
548 | } |
549 | } |
550 | |
551 | - /** |
552 | - * Check whether this server has a given channel. |
553 | - * @param channel_name Name of the channel you are looking for. |
554 | - * @return True if the channel exists, else false. |
555 | - */ |
556 | - public bool has_channel (string channel_id) { |
557 | - return channel_id in channel_ids; |
558 | - } |
559 | + public abstract signal void toggle_away (); |
560 | + public abstract signal void part_all (); |
561 | + |
562 | + public abstract void add_channel (string chat_name, string chat_id); |
563 | + public abstract void add_private_chat (string chat_name, string chat_id); |
564 | + public abstract void remove_chat (string chat_id); |
565 | |
566 | - /** |
567 | - * Retrieve a channel by its name. |
568 | - * |
569 | - * @param channel_name Name of the channel you are looking for. |
570 | - * @return The channel or null if not found. |
571 | - */ |
572 | - public Channel? get_channel_by_id (string channel_id) { |
573 | - foreach (var channel in channels) |
574 | - if (channel.id == channel_id) |
575 | - return channel; |
576 | - |
577 | - return (Channel) null; |
578 | + public bool has_chat (string chat_id) { |
579 | + return chat_id in chat_ids; |
580 | + } |
581 | + |
582 | + public Chat? get_chat (string chat_id) { |
583 | + foreach (var chat in chats) |
584 | + if (chat.id == chat_id) |
585 | + return chat; |
586 | + |
587 | + return (Chat) null; |
588 | } |
589 | } |
590 | |
591 | === modified file 'src/View/Window.vala' |
592 | --- src/View/Window.vala 2013-08-16 15:31:17 +0000 |
593 | +++ src/View/Window.vala 2013-09-22 16:58:59 +0000 |
594 | @@ -46,7 +46,7 @@ |
595 | /** |
596 | * Get the currently selected channel. |
597 | */ |
598 | - public abstract Channel? current_channel { get; set; } |
599 | + public abstract Chat? current_chat { get; set; } |
600 | |
601 | /** |
602 | * Amount of opened servers. |
603 | @@ -65,7 +65,7 @@ |
604 | |
605 | public signal void add_channel (); |
606 | |
607 | - public signal void selected (Channel channel); |
608 | + public signal void selected (Chat chat); |
609 | |
610 | public signal void show_preferences (); |
611 | |
612 | |
613 | === modified file 'src/Widgets/Channel.vala' |
614 | --- src/Widgets/Channel.vala 2013-08-12 22:09:44 +0000 |
615 | +++ src/Widgets/Channel.vala 2013-09-22 16:58:59 +0000 |
616 | @@ -17,62 +17,84 @@ |
617 | Boston, MA 02110-1301 USA. |
618 | ***/ |
619 | |
620 | -/** |
621 | - * An implementation of the View.Channel interface. |
622 | - */ |
623 | -public class Cable.Widgets.Channel : Granite.Widgets.SourceList.Item, View.Channel { |
624 | - |
625 | - Gtk.Menu menu; |
626 | - Gtk.MenuItem leave_menu_item; |
627 | - internal Room room; |
628 | - |
629 | - /** |
630 | - * Amount of unread messages. Displayed in a badge. |
631 | - */ |
632 | +public class Cable.Widgets.Chat : Granite.Widgets.SourceList.Item { |
633 | + |
634 | + public Room room; |
635 | + |
636 | + public string nick { get; set; } |
637 | + public string id { get; set; } |
638 | + public string entry { get; set; } |
639 | + |
640 | public int unread_messages { |
641 | get { return int.parse (badge); } |
642 | set { badge = (value <= 0) ? "" : value.to_string (); } |
643 | } |
644 | - |
645 | + |
646 | + public bool has_focus { |
647 | + get { return room.text_entry.has_focus; } |
648 | + } |
649 | + |
650 | + public void rename_user (string? old_name, string new_name, UserType type, bool silent = false) { |
651 | + room.rename_user (old_name, new_name, type, silent); |
652 | + } |
653 | + |
654 | + public void set_away_status (string nick, bool away) { |
655 | + room.chat.message_away (nick, away); |
656 | + } |
657 | + |
658 | + public void message (owned string from, string message, MessageType type = MessageType.NORMAL) { |
659 | + room.chat.add_message (from, message, type); |
660 | + } |
661 | +} |
662 | + |
663 | +public class Cable.Widgets.PrivateChat : Widgets.Chat, View.Chat, View.PrivateChat { |
664 | + public PrivateChat (string name, string id) { |
665 | + GLib.Object (name: name, id: id); |
666 | + this.room = new Room (name); |
667 | + |
668 | + room.send_message.connect ((msg) => send_message (msg)); |
669 | + room.text_entry.grab_focus.connect (() => { focused (); }); |
670 | + |
671 | + // bind properties |
672 | + bind_property ("nick", room, "nick", GLib.BindingFlags.BIDIRECTIONAL); |
673 | + bind_property ("name", room, "name", GLib.BindingFlags.BIDIRECTIONAL); |
674 | + bind_property ("entry", room, "entry", GLib.BindingFlags.BIDIRECTIONAL); |
675 | + } |
676 | +} |
677 | + |
678 | +public class Cable.Widgets.Channel : Widgets.Chat, View.Chat, View.Channel { |
679 | + |
680 | + Gtk.Menu menu; |
681 | + Gtk.MenuItem leave_menu_item; |
682 | + |
683 | public State state { get; set; } |
684 | - |
685 | - public string nick { get; set; } |
686 | - |
687 | public string topic { get; set; } |
688 | |
689 | - public string id { get; set; } |
690 | - |
691 | - public string entry { get; set; } |
692 | - |
693 | - public bool has_focus { |
694 | - get { return room.text_entry.has_focus; } |
695 | - } |
696 | - |
697 | - /* |
698 | - signal void autocomplete (int pos) |
699 | - */ |
700 | - |
701 | - /** |
702 | - * Create a new channel item for the source list. |
703 | - * @param channel_name Displayed name and id. |
704 | - */ |
705 | - internal Channel (string name, string id) { |
706 | - debug (@"+ VIEW CHANNEL $name"); |
707 | - |
708 | + public Channel (string name, string id) { |
709 | GLib.Object (name: name, id: id); |
710 | this.room = new Room (name); |
711 | - |
712 | + |
713 | this.menu = new Gtk.Menu (); |
714 | this.leave_menu_item = new Gtk.MenuItem.with_label (_("Leave Channel")); |
715 | menu.append (leave_menu_item); |
716 | menu.show_all (); |
717 | - |
718 | + |
719 | // setup signals |
720 | - leave_menu_item.activate.connect (() => part ()); |
721 | - room.send_message.connect ((msg) => send_message (msg)); |
722 | - room.rejoin.connect (() => join ()); |
723 | - room.text_entry.grab_focus.connect (() => { focused (); }); |
724 | + leave_menu_item.activate.connect (() |
725 | + => part ()); |
726 | + |
727 | + room.send_message.connect ((msg) |
728 | + => send_message (msg)); |
729 | + |
730 | + room.rejoin.connect (() |
731 | + => join ()); |
732 | + |
733 | + room.text_entry.grab_focus.connect (() |
734 | + => { focused (); }); |
735 | |
736 | + room.user_list.private_chat_requested.connect ((name) |
737 | + => private_chat_requested (name)); |
738 | + |
739 | // bind properties |
740 | bind_property ("state", room, "state", GLib.BindingFlags.BIDIRECTIONAL); |
741 | bind_property ("nick", room, "nick", GLib.BindingFlags.BIDIRECTIONAL); |
742 | @@ -80,17 +102,13 @@ |
743 | bind_property ("topic", room.topic_bar, "topic", GLib.BindingFlags.BIDIRECTIONAL); |
744 | bind_property ("entry", room, "entry", GLib.BindingFlags.BIDIRECTIONAL); |
745 | } |
746 | - |
747 | - ~Channel () { |
748 | - debug (@"- VIEW CHANNEL $name"); |
749 | - } |
750 | |
751 | public override Gtk.Menu? get_context_menu () { |
752 | if (menu != null && menu.get_attach_widget () != null) |
753 | menu.detach (); |
754 | return menu; |
755 | } |
756 | - |
757 | + |
758 | public bool has_user (string nick) { |
759 | return room.has_user (nick); |
760 | } |
761 | @@ -103,19 +121,8 @@ |
762 | room.add_user (name, type, silent); |
763 | } |
764 | |
765 | - public bool remove_user (string name, string message, bool silent = false) { |
766 | - return room.remove_user (name, message, silent); |
767 | - } |
768 | - |
769 | - public void rename_user (string? old_name, string new_name, UserType type, bool silent = false) { |
770 | - room.rename_user (old_name, new_name, type, silent); |
771 | - } |
772 | - |
773 | - public void set_away_status (string nick, bool away) { |
774 | - room.chat.message_away (nick, away); |
775 | - } |
776 | - |
777 | - public void message (owned string from, string message, MessageType type = MessageType.NORMAL) { |
778 | - room.chat.add_message (from, message, type); |
779 | - } |
780 | + public void remove_user (string name, string message, bool silent = false) { |
781 | + room.remove_user (name, message, silent); |
782 | + } |
783 | + |
784 | } |
785 | |
786 | === modified file 'src/Widgets/ChatDisplay.vala' |
787 | --- src/Widgets/ChatDisplay.vala 2013-08-25 21:01:06 +0000 |
788 | +++ src/Widgets/ChatDisplay.vala 2013-09-22 16:58:59 +0000 |
789 | @@ -39,9 +39,7 @@ |
790 | case LEAVE: |
791 | return "#a99"; |
792 | case SUGGESTION: |
793 | - return "#999"; |
794 | case NICK: |
795 | - return "#999"; |
796 | case AWAY: |
797 | return "#999"; |
798 | case PING: |
799 | @@ -152,25 +150,4 @@ |
800 | |
801 | return color_map[nick]; |
802 | } |
803 | -} |
804 | - |
805 | - |
806 | - |
807 | - |
808 | - |
809 | - |
810 | - |
811 | - |
812 | - |
813 | - |
814 | - |
815 | - |
816 | - |
817 | - |
818 | - |
819 | - |
820 | - |
821 | - |
822 | - |
823 | - |
824 | - |
825 | +} |
826 | \ No newline at end of file |
827 | |
828 | === modified file 'src/Widgets/Room.vala' |
829 | --- src/Widgets/Room.vala 2013-09-12 15:16:56 +0000 |
830 | +++ src/Widgets/Room.vala 2013-09-22 16:58:59 +0000 |
831 | @@ -37,25 +37,20 @@ |
832 | */ |
833 | public class Cable.Widgets.Room : Gtk.Grid { |
834 | |
835 | - Granite.Widgets.SourceList.ExpandableItem operators; |
836 | - Granite.Widgets.SourceList.ExpandableItem voiced; |
837 | - Granite.Widgets.SourceList.ExpandableItem regular; |
838 | - |
839 | - Granite.Widgets.SourceList users; |
840 | + public UserList user_list; |
841 | public ChatDisplay chat; |
842 | + public Gtk.Entry text_entry; |
843 | + public Widgets.Topic topic_bar; |
844 | + public Gtk.Label pseudo_label; |
845 | + |
846 | Granite.Widgets.EmbeddedAlert not_joined_alert; |
847 | Granite.Widgets.EmbeddedAlert no_such_alert; |
848 | Granite.Widgets.EmbeddedAlert loading_screen; |
849 | Granite.Widgets.ThinPaned paned; |
850 | |
851 | - internal Gtk.Entry text_entry; |
852 | Utils.AutoScrolled left_scrolled; |
853 | |
854 | - Gtk.Box user_box; |
855 | - |
856 | - public Widgets.Topic topic_bar; |
857 | Gtk.Action action_join; |
858 | - public Gtk.Label pseudo_label; |
859 | |
860 | public signal void send_message (string message); |
861 | // public signal void request_complete (); |
862 | @@ -107,18 +102,7 @@ |
863 | } |
864 | } |
865 | |
866 | - private Gee.Set <string> nicks { |
867 | - owned get { |
868 | - var _nicks = new Gee.HashSet <string> (); |
869 | - Granite.Widgets.SourceList.ExpandableItem[] lists = {voiced, operators, regular}; |
870 | - foreach (var list in lists) |
871 | - foreach (var child in list.children) |
872 | - _nicks.add (child.name); |
873 | - return _nicks as Gee.Set; |
874 | - } |
875 | - } |
876 | - |
877 | - public Room (string channel, string nick="") { |
878 | + public Room (string channel, string nick = "") { |
879 | this.channel = channel; |
880 | |
881 | history = new Utils.MessageHistory (); |
882 | @@ -128,31 +112,13 @@ |
883 | } |
884 | |
885 | void init_layout () { |
886 | + user_list = new UserList (); |
887 | + |
888 | paned = new Granite.Widgets.ThinPaned (); |
889 | var box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); |
890 | |
891 | - operators = new Granite.Widgets.SourceList.ExpandableItem (_("Operators")); |
892 | - operators.expanded = true; |
893 | - |
894 | - regular = new Granite.Widgets.SourceList.ExpandableItem (_("Regular")); |
895 | - regular.expanded = true; |
896 | - |
897 | - voiced = new Granite.Widgets.SourceList.ExpandableItem (_("Voiced")); |
898 | - voiced.expanded = true; |
899 | - |
900 | - users = new Granite.Widgets.SourceList (); |
901 | - users.hscrollbar_policy = Gtk.PolicyType.NEVER; |
902 | - users.width_request = 150; |
903 | - users.set_sort_func ((a,b) => {return a.name.collate (b.name);}); |
904 | - |
905 | - users.root.add (operators); |
906 | - users.root.add (voiced); |
907 | - users.root.add (regular); |
908 | - |
909 | - user_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); |
910 | - user_box.pack_start (users); |
911 | paned.pack1 (box, true, false); |
912 | - paned.pack2 (user_box, false, false); |
913 | + paned.pack2 (user_list, false, false); |
914 | |
915 | text_entry = new Gtk.Entry (); |
916 | text_entry.hexpand = true; |
917 | @@ -165,7 +131,7 @@ |
918 | topic_bar = new Widgets.Topic (); |
919 | |
920 | pseudo_label = new Gtk.Label (""); |
921 | - pseudo_label.set_alignment (1, (float)0.5); |
922 | + pseudo_label.set_alignment (1, (float) 0.5); |
923 | pseudo_label.width_request = 80; |
924 | |
925 | var entry_eventbox = new Gtk.EventBox (); |
926 | @@ -177,14 +143,14 @@ |
927 | |
928 | entry_grid.attach (pseudo_label, 0, 0, 1, 1); |
929 | entry_grid.attach (text_entry, 1, 0, 1, 1); |
930 | - left_scrolled.add_with_viewport(chat); |
931 | + left_scrolled.add_with_viewport (chat); |
932 | |
933 | box.pack_start (topic_bar, false); |
934 | box.pack_start (left_scrolled); |
935 | box.pack_start (entry_eventbox, false); |
936 | |
937 | loading_screen = new Granite.Widgets.EmbeddedAlert (); |
938 | - loading_screen.primary_text = _("Joining channel %s").printf(channel); |
939 | + loading_screen.primary_text = _("Joining channel %s").printf (channel); |
940 | loading_screen.working = true; |
941 | |
942 | action_join = new Gtk.Action ("join", "Join Channel", "Join this channel", null); |
943 | @@ -201,6 +167,8 @@ |
944 | no_such_alert.message_type = Gtk.MessageType.WARNING; |
945 | no_such_alert.show_icon= true; |
946 | |
947 | + state = State.CHAT; |
948 | + |
949 | this.show_all (); |
950 | } |
951 | |
952 | @@ -219,7 +187,7 @@ |
953 | return false; |
954 | |
955 | string[] completion = null; |
956 | - foreach (var nick in nicks) |
957 | + foreach (var nick in user_list.nicks) |
958 | if (word.down () == nick[0:word.length].down ()) |
959 | completion += nick; |
960 | |
961 | @@ -232,7 +200,7 @@ |
962 | } else { |
963 | text_entry.buffer.delete_text (text_entry.cursor_position - word.length, word.length); |
964 | |
965 | - if( text_entry.text != "" ){ |
966 | + if (text_entry.text != "") { |
967 | text_entry.insert_at_cursor (completion[0] + " "); |
968 | } else { |
969 | text_entry.insert_at_cursor (completion[0] + ": "); |
970 | @@ -264,100 +232,52 @@ |
971 | }); |
972 | } |
973 | |
974 | - public bool has_user (string nick) { |
975 | - Granite.Widgets.SourceList.ExpandableItem[] lists = {voiced, operators, regular}; |
976 | - foreach (var list in lists) |
977 | - foreach (var child in list.children) |
978 | - if (child.name == nick) |
979 | - return true; |
980 | - return false; |
981 | - } |
982 | - |
983 | public void list_users (string[] nicks, string[] prefixes) |
984 | requires (nicks.length == prefixes.length) { |
985 | |
986 | for (int i = 0; i < nicks.length; i++) { |
987 | switch (prefixes[i]) { |
988 | case "@": |
989 | - add_user (nicks[i], UserType.OPERATOR, true); |
990 | + user_list.add_user (nicks[i], UserType.OPERATOR); |
991 | break; |
992 | case "+": |
993 | - add_user (nicks[i], UserType.VOICED, true); |
994 | + user_list.add_user (nicks[i], UserType.VOICED); |
995 | break; |
996 | default: |
997 | - add_user (nicks[i], UserType.REGULAR, true); |
998 | + user_list.add_user (nicks[i], UserType.REGULAR); |
999 | break; |
1000 | } |
1001 | } |
1002 | -} |
1003 | - |
1004 | - public void rename_user (string? old_name, string new_name, UserType type, bool silent = false) |
1005 | - requires (has_user (old_name)) |
1006 | - requires (!has_user (new_name)) |
1007 | - ensures (!has_user (old_name)) |
1008 | - ensures (has_user (new_name)) { |
1009 | + } |
1010 | + |
1011 | + public bool has_user (string name) { |
1012 | + return user_list.has_user (name); |
1013 | + } |
1014 | + |
1015 | + public void rename_user (string? old_name, string new_name, |
1016 | + UserType type, bool silent = false) { |
1017 | |
1018 | if (old_name == null) { |
1019 | add_user (new_name, type, true); |
1020 | return; |
1021 | } |
1022 | |
1023 | - if (remove_user (old_name, "", true)) { |
1024 | - add_user (new_name, type, true); |
1025 | - if (!silent) |
1026 | - chat.message_nick (old_name, new_name); |
1027 | - } |
1028 | + remove_user (old_name, "", true); |
1029 | + add_user (new_name, type, true); |
1030 | + |
1031 | + if (!silent) |
1032 | + chat.message_nick (old_name, new_name); |
1033 | } |
1034 | |
1035 | - public void add_user (string name, UserType type, bool silent = false) |
1036 | - requires (!has_user (name)) |
1037 | - ensures (has_user (name)) { |
1038 | - |
1039 | - var user = new User (name); |
1040 | - user.selectable = false; |
1041 | - |
1042 | - switch (type) { |
1043 | - case UserType.OPERATOR: |
1044 | - operators.add (user); |
1045 | - break; |
1046 | - case UserType.VOICED: |
1047 | - voiced.add (user); |
1048 | - break; |
1049 | - default: |
1050 | - regular.add (user); |
1051 | - break; |
1052 | - } |
1053 | - |
1054 | + public void add_user (string name, UserType type, bool silent = false) { |
1055 | + user_list.add_user (name, type); |
1056 | if (!silent) |
1057 | chat.message_join (name); |
1058 | - |
1059 | - regular.name = _("Regular") + " (" + regular.n_children.to_string () + ")"; |
1060 | - operators.name = _("Operators") + " (" + operators.n_children.to_string () + ")"; |
1061 | - voiced.name = _("Voiced") + " (" + voiced.n_children.to_string () + ")"; |
1062 | } |
1063 | |
1064 | - public bool remove_user (string name, string message, bool silent = false) |
1065 | - requires (has_user (name)) |
1066 | - ensures (!has_user (name)) { |
1067 | - |
1068 | - Granite.Widgets.SourceList.ExpandableItem[] lists = {voiced, operators, regular}; |
1069 | - foreach (var list in lists) { |
1070 | - foreach (var child in list.children) { |
1071 | - if (child.name == name) { |
1072 | - list.remove (child); |
1073 | - |
1074 | - if (!silent) |
1075 | - chat.message_part (child.name, message); |
1076 | - |
1077 | - regular.name = _("Regular") + " (" + regular.n_children.to_string () + ")"; |
1078 | - operators.name = _("Operators") + " (" + operators.n_children.to_string () + ")"; |
1079 | - voiced.name = _("Voiced") + " (" + voiced.n_children.to_string () + ")"; |
1080 | - |
1081 | - return true; |
1082 | - } |
1083 | - } |
1084 | - } |
1085 | - return false; |
1086 | + public void remove_user (string name, string message, bool silent = false) { |
1087 | + user_list.remove_user (name); |
1088 | + if (!silent) |
1089 | + chat.message_part (name, message); |
1090 | } |
1091 | } |
1092 | - |
1093 | |
1094 | === modified file 'src/Widgets/Server.vala' |
1095 | --- src/Widgets/Server.vala 2013-08-12 21:04:54 +0000 |
1096 | +++ src/Widgets/Server.vala 2013-09-22 16:58:59 +0000 |
1097 | @@ -23,15 +23,12 @@ |
1098 | */ |
1099 | public class Cable.Widgets.Server : Granite.Widgets.SourceList.ExpandableItem, View.Server { |
1100 | |
1101 | - /** |
1102 | - * List of all channels. |
1103 | - */ |
1104 | - public Gee.ArrayList <View.Channel> channels { |
1105 | + public Gee.ArrayList <View.Chat> chats { |
1106 | owned get { |
1107 | - var _channels = new Gee.ArrayList <View.Channel> (); |
1108 | + var _chats = new Gee.ArrayList <View.Chat> (); |
1109 | foreach (var child in children) |
1110 | - _channels.add (child as View.Channel); |
1111 | - return _channels; |
1112 | + _chats.add (child as View.Chat); |
1113 | + return _chats; |
1114 | } |
1115 | } |
1116 | |
1117 | @@ -49,15 +46,10 @@ |
1118 | Gtk.MenuItem part_menu_item; |
1119 | |
1120 | internal Server (string name, string id) { |
1121 | - debug (@"+ VIEW SERVER $name"); |
1122 | GLib.Object (name: name, id: id); |
1123 | setup_contextmenu (); |
1124 | } |
1125 | |
1126 | - ~Server () { |
1127 | - debug (@"- VIEW SERVER $name"); |
1128 | - } |
1129 | - |
1130 | void setup_contextmenu () |
1131 | requires (menu == null) |
1132 | ensures (menu != null) { |
1133 | @@ -82,28 +74,27 @@ |
1134 | return menu; |
1135 | } |
1136 | |
1137 | - /** |
1138 | - * Create and add a new channel to this server. |
1139 | - * @param channel_name Name of the new channel. |
1140 | - */ |
1141 | - public void add_channel (string channel_name, string channel_id) |
1142 | - requires (!has_channel (channel_name)) |
1143 | - ensures (has_channel (channel_name)) { |
1144 | - |
1145 | - var channel = new Channel (channel_name, channel_id); |
1146 | - add (channel); |
1147 | - } |
1148 | - |
1149 | - /** |
1150 | - * Remove a channel from this server. |
1151 | - * @param channel_name Name of the channel to be removed. |
1152 | - */ |
1153 | - public void remove_channel (string channel_name) |
1154 | - requires (has_channel (channel_name)) |
1155 | - ensures (!has_channel (channel_name)) { |
1156 | - |
1157 | - var channel = get_channel_by_id (channel_name) as Widgets.Channel; |
1158 | - return_if_fail (channel != null); |
1159 | - remove (channel); |
1160 | + public void add_channel (string chat_name, string chat_id) |
1161 | + requires (!has_chat (chat_name)) |
1162 | + ensures (has_chat (chat_name)) { |
1163 | + |
1164 | + var chat = new Channel (chat_name, chat_id); |
1165 | + add (chat); |
1166 | + } |
1167 | + |
1168 | + public void add_private_chat (string chat_name, string chat_id) |
1169 | + requires (!has_chat (chat_name)) |
1170 | + ensures (has_chat (chat_name)) { |
1171 | + |
1172 | + var chat = new PrivateChat (chat_name, chat_id); |
1173 | + add (chat); |
1174 | + } |
1175 | + |
1176 | + public void remove_chat (string chat_name) |
1177 | + requires (has_chat (chat_name)) |
1178 | + ensures (!has_chat (chat_name)) { |
1179 | + |
1180 | + var chat = get_chat (chat_name) as Widgets.Chat; |
1181 | + remove (chat); |
1182 | } |
1183 | } |
1184 | |
1185 | === modified file 'src/Widgets/User.vala' |
1186 | --- src/Widgets/User.vala 2013-07-26 13:16:58 +0000 |
1187 | +++ src/Widgets/User.vala 2013-09-22 16:58:59 +0000 |
1188 | @@ -21,8 +21,16 @@ |
1189 | /*Gtk.MenuItem kick_item; |
1190 | Gtk.MenuItem ban_item; |
1191 | Gtk.MenuItem ignore_item;*/ |
1192 | + |
1193 | public class Cable.Widgets.User : Granite.Widgets.SourceList.Item { |
1194 | + |
1195 | + public signal void private_chat_requested (); |
1196 | + |
1197 | public User (string name) { |
1198 | base (name); |
1199 | + |
1200 | + activated.connect (() => { |
1201 | + private_chat_requested (); // signal |
1202 | + }); |
1203 | } |
1204 | } |
1205 | |
1206 | === added file 'src/Widgets/UserList.vala' |
1207 | --- src/Widgets/UserList.vala 1970-01-01 00:00:00 +0000 |
1208 | +++ src/Widgets/UserList.vala 2013-09-22 16:58:59 +0000 |
1209 | @@ -0,0 +1,122 @@ |
1210 | +/*** |
1211 | + Copyright (C) 2013 Cable Developers |
1212 | + |
1213 | + This program or library is free software; you can redistribute it |
1214 | + and/or modify it under the terms of the GNU Lesser General Public |
1215 | + License as published by the Free Software Foundation; either |
1216 | + version 3 of the License, or (at your option) any later version. |
1217 | + |
1218 | + This library is distributed in the hope that it will be useful, |
1219 | + but WITHOUT ANY WARRANTY; without even the implied warranty of |
1220 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
1221 | + Lesser General Public License for more details. |
1222 | + |
1223 | + You should have received a copy of the GNU Lesser General |
1224 | + Public License along with this library; if not, write to the |
1225 | + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
1226 | + Boston, MA 02110-1301 USA. |
1227 | +***/ |
1228 | + |
1229 | +public class Cable.Widgets.UserList : Granite.Widgets.SourceList { |
1230 | + |
1231 | + Granite.Widgets.SourceList.ExpandableItem operators; |
1232 | + Granite.Widgets.SourceList.ExpandableItem voiced; |
1233 | + Granite.Widgets.SourceList.ExpandableItem regular; |
1234 | + |
1235 | + delegate void ForeachFunction (User user); |
1236 | + |
1237 | + public Gee.Set <string> nicks { |
1238 | + owned get { |
1239 | + var _nicks = new Gee.HashSet <string> (); |
1240 | + @foreach ((child) => _nicks.add (child.name)); |
1241 | + return _nicks as Gee.Set; |
1242 | + } |
1243 | + } |
1244 | + |
1245 | + public signal void private_chat_requested (string user_name); |
1246 | + |
1247 | + public UserList () { |
1248 | + operators = new Granite.Widgets.SourceList.ExpandableItem (_("Operators")); |
1249 | + voiced = new Granite.Widgets.SourceList.ExpandableItem (_("Voiced")); |
1250 | + regular = new Granite.Widgets.SourceList.ExpandableItem (_("Regular")); |
1251 | + |
1252 | + regular.expanded = true; |
1253 | + operators.expanded = true; |
1254 | + voiced.expanded = true; |
1255 | + |
1256 | + hscrollbar_policy = Gtk.PolicyType.NEVER; |
1257 | + width_request = 150; |
1258 | + set_sort_func ((a,b) => { |
1259 | + return a.name.collate (b.name); |
1260 | + }); |
1261 | + |
1262 | + root.add (operators); |
1263 | + root.add (voiced); |
1264 | + root.add (regular); |
1265 | + |
1266 | + no_show_all = true; |
1267 | + visible = false; |
1268 | + } |
1269 | + |
1270 | + public bool has_user (string name) { |
1271 | + return name in nicks; |
1272 | + } |
1273 | + |
1274 | + public void add_user (string name, UserType user_type = UserType.REGULAR) { |
1275 | + var user = new User (name); |
1276 | + user.selectable = false; |
1277 | + |
1278 | + switch (user_type) { |
1279 | + case UserType.OPERATOR: |
1280 | + operators.add (user); |
1281 | + break; |
1282 | + case UserType.VOICED: |
1283 | + voiced.add (user); |
1284 | + break; |
1285 | + default: |
1286 | + regular.add (user); |
1287 | + break; |
1288 | + } |
1289 | + |
1290 | + user.private_chat_requested.connect (() => { |
1291 | + private_chat_requested (user.name); |
1292 | + }); |
1293 | + |
1294 | + update_user_counts (); |
1295 | + |
1296 | + if (visible == false) { |
1297 | + no_show_all = false; |
1298 | + visible = true; |
1299 | + } |
1300 | + } |
1301 | + |
1302 | + public void remove_user (string name) { |
1303 | + @foreach ((child) => { |
1304 | + if (child.name != name) |
1305 | + return; |
1306 | + child.parent.remove (child); |
1307 | + update_user_counts (); |
1308 | + }); |
1309 | + |
1310 | + if (nicks.size == 0) { |
1311 | + no_show_all = true; |
1312 | + visible = false; |
1313 | + } |
1314 | + } |
1315 | + |
1316 | + void update_user_counts () { |
1317 | + regular.name = _("Regular") + @" ($(regular.n_children.to_string ()))"; |
1318 | + operators.name = _("Operators") + @" ($(operators.n_children.to_string ()))"; |
1319 | + voiced.name = _("Voiced") + @" ($(voiced.n_children.to_string ()))"; |
1320 | + } |
1321 | + |
1322 | + new void @foreach (ForeachFunction func) { |
1323 | + Granite.Widgets.SourceList.ExpandableItem[] lists = { |
1324 | + voiced, operators, regular |
1325 | + }; |
1326 | + |
1327 | + foreach (var list in lists) |
1328 | + foreach (var child in list.children) |
1329 | + func (child as User); |
1330 | + } |
1331 | +} |
1332 | |
1333 | === modified file 'src/Widgets/Window.vala' |
1334 | --- src/Widgets/Window.vala 2013-08-20 14:28:43 +0000 |
1335 | +++ src/Widgets/Window.vala 2013-09-22 16:58:59 +0000 |
1336 | @@ -112,9 +112,9 @@ |
1337 | /** |
1338 | * Get the currently selected channel. |
1339 | */ |
1340 | - public View.Channel? current_channel { |
1341 | - get { return server_list.selected as View.Channel; } |
1342 | - set { server_list.selected = value as Widgets.Channel; } |
1343 | + public View.Chat? current_chat { |
1344 | + get { return server_list.selected as View.Chat; } |
1345 | + set { server_list.selected = value as Widgets.Chat; } |
1346 | } |
1347 | |
1348 | //public signal void edit_identity (); |
1349 | @@ -126,8 +126,8 @@ |
1350 | |
1351 | server_list.item_selected.connect ((item) => { |
1352 | if (item != null) { |
1353 | - display_widget = (current_channel as Widgets.Channel).room; |
1354 | - selected (current_channel); |
1355 | + display_widget = (current_chat as Widgets.Chat).room; |
1356 | + selected (current_chat); |
1357 | } |
1358 | }); |
1359 |
Now open for review.