Merge lp:~julien-spautz/cable/clean-up into lp:cable
- clean-up
- Merge into trunk
Status: | Merged | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Merged at revision: | 64 | ||||||||||||||||||||
Proposed branch: | lp:~julien-spautz/cable/clean-up | ||||||||||||||||||||
Merge into: | lp:cable | ||||||||||||||||||||
Diff against target: |
4226 lines (+2750/-1267) (has conflicts) 25 files modified
CMakeLists.txt (+26/-4) data/org.pantheon.cable.gschema.xml (+11/-19) po/cable.pot (+57/-75) src/Cable.vala (+85/-248) src/Config.vala.cmake (+7/-7) src/Dialogs/JoinChannel.vala (+97/-0) src/Dialogs/ManageIdentity.vala (+117/-0) src/Dialogs/ManageNetwork.vala (+116/-0) src/Dialogs/Preferences.vala (+214/-0) src/Global.vala (+0/-18) src/Services/Client.vala (+278/-0) src/Services/Identity.vala (+123/-0) src/Services/Network.vala (+103/-0) src/Services/Settings.vala (+146/-0) src/Settings.vala (+0/-23) src/Utils.vala (+69/-0) src/Widgets/Channel.vala (+109/-55) src/Widgets/Room.vala (+276/-63) src/Widgets/Server.vala (+380/-229) src/Widgets/ServerList.vala (+103/-76) src/Widgets/SettingsDialog.vala (+0/-65) src/Widgets/StatusBar.vala (+49/-0) src/Widgets/Welcome.vala (+112/-0) src/Window.vala (+272/-0) src/doodleIRC.vala (+0/-385) Text conflict in src/Widgets/Room.vala |
||||||||||||||||||||
To merge this branch: | bzr merge lp:~julien-spautz/cable/clean-up | ||||||||||||||||||||
Related bugs: |
|
||||||||||||||||||||
Related blueprints: |
GUI Specification
(Essential)
Use Sushi's backend
(High)
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Auroral Xylon (community) | Needs Fixing | ||
Julián Unrrein (community) | Needs Fixing | ||
Eduard Gotwig (community) | Needs Fixing | ||
Review via email: mp+168703@code.launchpad.net |
Commit message
Description of the change
Just testing for conflicts, please don't merge.
Julien Spautz (julien-spautz) wrote : | # |
Julián Unrrein (junrrein) wrote : | # |
If you'd like more people to test this when this is ready, I offer my help. Just shoot me an email.
Julien Spautz (julien-spautz) wrote : | # |
I'll start implementing this: https:/
After this is done, we can start reviewing.
Julien Spautz (julien-spautz) wrote : | # |
Ok, I guess the branch is now kind of working. I need some feedback in case there are any important bugs, else this branch is ready for merging into trunk.
- 56. By Julien Spautz
-
replaced toolber with status bar, entry not yet resizing
- 57. By Julien Spautz
-
added new statusbar file
- 58. By Julien Spautz
-
small fixes
- 59. By Julien Spautz
-
fixed duplicates in user list
Auroral Xylon (avlabs314) wrote : | # |
This branch is looking pretty good now...Small bugs can be fixed later on I guess...Merge time?
- 60. By Julien Spautz
-
entry now expands and is centered correctly, buttons on the right are misaligned
- 61. By Julien Spautz
-
added file
- 62. By Julien Spautz
-
make pot
Eduard Gotwig (gotwig) wrote : | # |
Nickname entry description should tell the user that hes not able to use spaces or special charachters;
The join channel dialog shouldnt autoselect the # charachter as a selection;
when the user enters an alphabetical charachter as the first charachter for a channel, cable IRC Suite should automaticly prepend a "#" charachter before this.
Julián Unrrein (junrrein) wrote : | # |
I can't compile your branch as of rev62:
/clean-
PS: Consider adding me to the reviewer list of this merge proposal, so I get automatically notified of new comments.
Julián Unrrein (junrrein) wrote : | # |
Do you enforce a certain version of valac? I am using 0.16.
Julián Unrrein (junrrein) wrote : | # |
@gotwig
Shouldn't we just focus on checking that this branch solves all the bugs and implements all the blueprints linked? Because everything you mentioned seems to be nonrelated details.
Eduard Gotwig (gotwig) wrote : | # |
@Junrrein
This branch offers a new look, and a new implementation of a design specification. With this, it should not make the UX of Cable IRC Suite worse.
Auroral Xylon (avlabs314) wrote : | # |
I have always had @junrreins problem; I fixed this in trunk but I presums that Julien Spautz's branch is based of an older revsion. To fix the compile error, you need to put '(Gtk.Container)' before topic so it looks like this:
Gtk.Container content = (Gtk.Container)
However, there are also some disagreementtwith the design. Until we can resolve them,' the branch should not be merged.
- 63. By Julien Spautz
-
fixed a few things
Julián Unrrein (junrrein) wrote : | # |
@gotwig
In trunk the identity dialog doesn't check if the input contains spaces or special characters, so the situation is the same here.
As for the other details, they are very minor nuisances which can be taken care of at another moment.
Julián Unrrein (junrrein) wrote : | # |
@xylon
I am aware I can type-cast the compile error away, but that is not the problem.
It is apparent that Julien didn't even try to compile his branch before pushing his latest revisions. I am reluctant to test code that wasn't tested by the developer.
Julien Spautz (julien-spautz) wrote : | # |
@junrrein
I did try the code and it compiled fine for me, the compiler error xylon mentionned existed in trunk but it didn't affect me there either. It's now been fixed, so I hope it now works for you too.
This is the merge request that fixed the bug in trunk, and as you can see, the bug never affected me. https:/
Julián Unrrein (junrrein) wrote : | # |
@Julien
I talked to xylon about this a minute ago, and we concluded this might be pinned down to different versions of valac being used. I'm sorry for the "accusation". If I standed out as rude, it wasn't my intention.
I can now compile rev63 just fine, thanks. I'll be testing this.
Julián Unrrein (junrrein) wrote : | # |
I noticed a couple of issues:
1 - New identities can't join channels in the same session they are created. After closing Cable and restarting it, the new identity works just as expected. I can reproduce this always.
2 - The first time Cable is opened (in a new desktop session) console output reveals it connects every past identity to each correspondent server - even identities that were erased from Cable (and from Dconf). This is related with the previous issue because after connecting sucesfully with an identity, erasing it will not trigger the first bug again.
Julien Spautz (julien-spautz) wrote : | # |
Thanks for testing!
1) I don't (yet) know how to fix this, as there is no documentation for maki, the backend daemon. I'm currently performing some hackish tests which are relatively reliable, but I'm still searching for a way to test if maki is connected to a specific server or not.
2) Shouldn't be too hard to fix, but again, maki really lacks documentation…
( And don't worry, I'm not offended ;) )
Julián Unrrein (junrrein) wrote : | # |
About item 2: This makes impossible to change the current nick to one that was used previously, even if you are not using it right now.
Curiously, changing the current nick to another one which was never used doesn't trigger item 1.
The nick is changed correctly when seen from the outside.
From the inside, the nick shown in the window title only changes when changing to another channel and then back.
The nick shown in the operators/users lists isn't changed in any of the current opened channels. It will stay the same until you leave those channels and join again. New channels will join the nick correctly.
Julián Unrrein (junrrein) wrote : | # |
The last line should read "New channels will show the nick correctly".
Julián Unrrein (junrrein) wrote : | # |
About the linked bugs:
(3) Cable doesn't let me join a channel twice. Console output says "Server.vala:336: Channel '#elementary-apps' already joined. Works as intended. UI feedback would be nice, but it's not necessary right now.
(4) The operators/users lists are expanded by default.
(5) I don't know how to test running with invalid Gschemas. Do I just modify any key with random content?
(6) Toolbar buttons have tooltips now.
(7) I can remove identities that I am currently using from the settings dialog - not good.
Identities created using this dialog exhibit the first bug I outlined earlier (bug (1)).
Maybe identities should be tied to specific networks. See my comment in the blueprint (http://
This is looking pretty well!
Auroral Xylon (avlabs314) wrote : | # |
I am having a problem - cable does not connect to a channel, except it randomly does on a few occasions. Basically, the interface loads - the sidebars and the 'loading topic' text appears but it doesn't actually connect.
Unfortunately, junrrein also had this problem.
- 64. By Julien Spautz
-
joining channels should now be more reliable, some internal changes to how settings are handeled
Preview Diff
1 | === modified file 'CMakeLists.txt' |
2 | --- CMakeLists.txt 2013-05-29 00:24:15 +0000 |
3 | +++ CMakeLists.txt 2013-06-28 19:09:26 +0000 |
4 | @@ -41,22 +41,44 @@ |
5 | |
6 | include(ValaPrecompile) |
7 | vala_precompile(VALA_C |
8 | - src/doodleIRC.vala |
9 | src/Cable.vala |
10 | - src/Global.vala |
11 | - src/Settings.vala |
12 | + src/Window.vala |
13 | + src/Utils.vala |
14 | + |
15 | + src/Services/Client.vala |
16 | + src/Services/Settings.vala |
17 | + src/Services/Identity.vala |
18 | + src/Services/Network.vala |
19 | + |
20 | src/Widgets/Room.vala |
21 | src/Widgets/Server.vala |
22 | src/Widgets/Channel.vala |
23 | src/Widgets/ServerList.vala |
24 | - src/Widgets/SettingsDialog.vala |
25 | + src/Widgets/StatusBar.vala |
26 | + src/Widgets/Welcome.vala |
27 | + |
28 | + src/Dialogs/JoinChannel.vala |
29 | + src/Dialogs/Preferences.vala |
30 | + src/Dialogs/ManageIdentity.vala |
31 | + src/Dialogs/ManageNetwork.vala |
32 | + |
33 | ${CMAKE_BINARY_DIR}/src/Config.vala |
34 | PACKAGES |
35 | + gtk+-3.0 |
36 | granite |
37 | + #WebKit-3.0 |
38 | OPTIONS |
39 | --target-glib=2.32 |
40 | --vapidir=${CMAKE_CURRENT_SOURCE_DIR}/vapi/ |
41 | ) |
42 | + |
43 | +pkg_check_modules(DEPS REQUIRED |
44 | + glib-2.0>=${TARGET_GLIB}.0 |
45 | + gio-2.0>=2.28.0 |
46 | + gtk+-3.0>=3.4.0 |
47 | + gee-0.8>=0.8.0 |
48 | + #webkitgtk-3.0>=1.10.0 |
49 | +) |
50 | |
51 | add_subdirectory (po) |
52 | |
53 | |
54 | === modified file 'data/org.pantheon.cable.gschema.xml' |
55 | --- data/org.pantheon.cable.gschema.xml 2013-05-26 15:42:50 +0000 |
56 | +++ data/org.pantheon.cable.gschema.xml 2013-06-28 19:09:26 +0000 |
57 | @@ -1,27 +1,19 @@ |
58 | <schemalist> |
59 | <schema path="/org/pantheon/cable/" id="org.pantheon.cable" gettext-domain="cable"> |
60 | - <key name="servers" type="as"> |
61 | + <key name="identities" type="as"> |
62 | <default>[]</default> |
63 | - <summary>All the todo items</summary> |
64 | - <description></description> |
65 | - </key> |
66 | - <key name="nick" type="s"> |
67 | - <default>""</default> |
68 | - <summary>Your nick</summary> |
69 | - </key> |
70 | - <key name="real-name" type="s"> |
71 | - <default>""</default> |
72 | - <summary>Your real name</summary> |
73 | - </key> |
74 | - <key name="login-name" type="as"> |
75 | - <default>[]</default> |
76 | - <summary>Your login name for different IRC server</summary> |
77 | - <description>Specify your user accounts in the form "server:loginname"</description> |
78 | + <summary>Your identities that can be used to connect to networks.</summary> |
79 | + <description>The format is ["nickname:realname:partmsg", "...", ...]</description> |
80 | + </key> |
81 | + <key name="networks" type="as"> |
82 | + <default>["irc.freenode.net:Freenode:", "irc.gimp.org:GimpNet:"]</default> |
83 | + <summary>Networks too choose from when joining a channel.</summary> |
84 | + <description>The format is ["address:name:password", "..."]</description> |
85 | </key> |
86 | <key name="channels" type="as"> |
87 | - <default>[]</default> |
88 | - <summary>Channels to be joined on startup, typically from last session</summary> |
89 | - <description>These channels in the form "server:#channel" will be joined on startup</description> |
90 | + <default>[]</default> |
91 | + <summary>Channels to be joined on startup, typically from last session</summary> |
92 | + <description>These channels in the form "network address:nickname:#channel" will be joined on startup</description> |
93 | </key> |
94 | </schema> |
95 | </schemalist> |
96 | |
97 | === modified file 'po/cable.pot' |
98 | --- po/cable.pot 2013-06-04 20:46:10 +0000 |
99 | +++ po/cable.pot 2013-06-28 19:09:26 +0000 |
100 | @@ -3,12 +3,13 @@ |
101 | # This file is distributed under the same license as the PACKAGE package. |
102 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. |
103 | # |
104 | +#: /home/tutebatti/cable/po/../src/Widgets/Server.vala:121 |
105 | #, fuzzy |
106 | msgid "" |
107 | msgstr "" |
108 | "Project-Id-Version: PACKAGE VERSION\n" |
109 | "Report-Msgid-Bugs-To: \n" |
110 | -"POT-Creation-Date: 2013-06-04 22:45+0200\n" |
111 | +"POT-Creation-Date: 2013-06-23 18:12+0200\n" |
112 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
113 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
114 | "Language-Team: LANGUAGE <LL@li.org>\n" |
115 | @@ -17,87 +18,68 @@ |
116 | "Content-Type: text/plain; charset=UTF-8\n" |
117 | "Content-Transfer-Encoding: 8bit\n" |
118 | |
119 | -#: /home/gotwig/cable/po/../src/Cable.vala:63 |
120 | -msgid "Welcome to Cable" |
121 | -msgstr "" |
122 | - |
123 | -#: /home/gotwig/cable/po/../src/Cable.vala:63 |
124 | -msgid "Connect to the IRC world" |
125 | -msgstr "" |
126 | - |
127 | -#: /home/gotwig/cable/po/../src/Cable.vala:65 |
128 | -#: /home/gotwig/cable/po/../src/Cable.vala:70 |
129 | -msgid "Join a Channel" |
130 | -msgstr "" |
131 | - |
132 | -#: /home/gotwig/cable/po/../src/Cable.vala:66 |
133 | -#: /home/gotwig/cable/po/../src/Widgets/Channel.vala:31 |
134 | -msgid "Leave Channel" |
135 | -msgstr "" |
136 | - |
137 | -#: /home/gotwig/cable/po/../src/Cable.vala:67 |
138 | -msgid "Add a Server" |
139 | -msgstr "" |
140 | - |
141 | -#: /home/gotwig/cable/po/../src/Cable.vala:68 |
142 | -msgid "Edit User Settings" |
143 | -msgstr "" |
144 | - |
145 | -#: /home/gotwig/cable/po/../src/Cable.vala:70 |
146 | -msgid "Channel" |
147 | -msgstr "" |
148 | - |
149 | -#: /home/gotwig/cable/po/../src/Cable.vala:71 |
150 | -#: /home/gotwig/cable/po/../src/Cable.vala:202 |
151 | -msgid "Server" |
152 | -msgstr "" |
153 | - |
154 | -#: /home/gotwig/cable/po/../src/Cable.vala:71 |
155 | -msgid "Add a Custom Server" |
156 | -msgstr "" |
157 | - |
158 | -#: /home/gotwig/cable/po/../src/Cable.vala:204 |
159 | -#: /home/gotwig/cable/po/../src/Cable.vala:215 |
160 | +#: /home/tutebatti/cable/po/../src/Widgets/Welcome.vala:8 |
161 | +msgid "Connect to the IRC world." |
162 | +msgstr "" |
163 | + |
164 | +#: /home/tutebatti/cable/po/../src/Widgets/Welcome.vala:8 |
165 | +msgid "Join a Channel." |
166 | +msgstr "" |
167 | + |
168 | +#: /home/tutebatti/cable/po/../src/Widgets/Welcome.vala:16 |
169 | +msgid "Network:" |
170 | +msgstr "" |
171 | + |
172 | +#: /home/tutebatti/cable/po/../src/Widgets/Welcome.vala:20 |
173 | +msgid "Identity:" |
174 | +msgstr "" |
175 | + |
176 | +#: /home/tutebatti/cable/po/../src/Widgets/Welcome.vala:24 |
177 | +msgid "Channel:" |
178 | +msgstr "" |
179 | + |
180 | +#: /home/tutebatti/cable/po/../src/Widgets/Welcome.vala:45 |
181 | msgid "Join Channel" |
182 | msgstr "" |
183 | |
184 | -#: /home/gotwig/cable/po/../src/Widgets/Channel.vala:32 |
185 | -msgid "Mark Away" |
186 | -msgstr "" |
187 | - |
188 | -#: /home/gotwig/cable/po/../src/Widgets/Channel.vala:41 |
189 | -msgid "Away" |
190 | -msgstr "" |
191 | - |
192 | -#: /home/gotwig/cable/po/../src/Widgets/Room.vala:73 |
193 | +#: /home/tutebatti/cable/po/../src/Widgets/Room.vala:57 |
194 | msgid "Loading Topic…" |
195 | msgstr "" |
196 | |
197 | -#: /home/gotwig/cable/po/../src/Widgets/Room.vala:84 |
198 | +#: /home/tutebatti/cable/po/../src/Widgets/Room.vala:94 |
199 | +#: /home/tutebatti/cable/po/../src/Widgets/Room.vala:203 |
200 | +#: /home/tutebatti/cable/po/../src/Widgets/Room.vala:216 |
201 | msgid "Operators" |
202 | msgstr "" |
203 | |
204 | -#: /home/gotwig/cable/po/../src/Widgets/Server.vala:150 |
205 | -#: /home/gotwig/cable/po/../src/Widgets/Server.vala:154 |
206 | -msgid "Add Server" |
207 | -msgstr "" |
208 | - |
209 | -#: /home/gotwig/cable/po/../src/Widgets/Server.vala:162 |
210 | -msgid "Server Name:" |
211 | -msgstr "" |
212 | - |
213 | -#: /home/gotwig/cable/po/../src/Widgets/Server.vala:164 |
214 | -msgid "Server URL:" |
215 | -msgstr "" |
216 | - |
217 | -#: /home/gotwig/cable/po/../src/Widgets/SettingsDialog.vala:32 |
218 | -msgid "Done" |
219 | -msgstr "" |
220 | - |
221 | -#: /home/gotwig/cable/po/../src/Widgets/SettingsDialog.vala:34 |
222 | -msgid "Nick:" |
223 | -msgstr "" |
224 | - |
225 | -#: /home/gotwig/cable/po/../src/Widgets/SettingsDialog.vala:36 |
226 | -msgid "Real Name:" |
227 | +#: /home/tutebatti/cable/po/../src/Widgets/Room.vala:202 |
228 | +#: /home/tutebatti/cable/po/../src/Widgets/Room.vala:215 |
229 | +msgid "Regular" |
230 | +msgstr "" |
231 | + |
232 | +#: /home/tutebatti/cable/po/../src/Widgets/Room.vala:204 |
233 | +#: /home/tutebatti/cable/po/../src/Widgets/Room.vala:217 |
234 | +msgid "Voiced" |
235 | +msgstr "" |
236 | + |
237 | +#: /home/tutebatti/cable/po/../src/Widgets/Channel.vala:31 |
238 | +msgid "Leave Channel" |
239 | +msgstr "" |
240 | + |
241 | +#: /home/tutebatti/cable/po/../src/Widgets/Server.vala:110 |
242 | +#: /home/tutebatti/cable/po/../src/Widgets/Server.vala:122 |
243 | +msgid "Mark Away" |
244 | +msgstr "" |
245 | + |
246 | +#: /home/tutebatti/cable/po/../src/Widgets/Server.vala:111 |
247 | +msgid "Leave all channels" |
248 | +msgstr "" |
249 | + |
250 | +#: /home/tutebatti/cable/po/../src/Widgets/Server.vala:118 |
251 | +#, c-format |
252 | +msgid "%s is away." |
253 | +msgstr "" |
254 | + |
255 | +#: /home/tutebatti/cable/po/../src/Widgets/Server.vala:119 |
256 | +msgid "Mark Present" |
257 | msgstr "" |
258 | |
259 | === modified file 'src/Cable.vala' |
260 | --- src/Cable.vala 2013-06-07 12:59:28 +0000 |
261 | +++ src/Cable.vala 2013-06-28 19:09:26 +0000 |
262 | @@ -1,248 +1,85 @@ |
263 | -namespace Cable { |
264 | - |
265 | - /** |
266 | - * Main class of the application. Manages one window. |
267 | - */ |
268 | - public class App : Granite.Application { |
269 | - |
270 | - construct { |
271 | - program_name = "Cable"; |
272 | - exec_name = "cable"; |
273 | - |
274 | - build_data_dir = Constants.DATADIR; |
275 | - build_pkg_data_dir = Constants.PKGDATADIR; |
276 | - build_release_name = Constants.RELEASE_NAME; |
277 | - build_version = Constants.VERSION; |
278 | - build_version_info = Constants.VERSION_INFO; |
279 | - |
280 | - app_years = "2012"; |
281 | - |
282 | - app_icon = "applications-chat"; |
283 | - app_launcher = "cable.desktop"; |
284 | - application_id = "net.launchpad.cable"; |
285 | - |
286 | - main_url = "https://code.launchpad.net/cable"; |
287 | - bug_url = "https://bugs.launchpad.net/cable"; |
288 | - help_url = "https://code.launchpad.net/cable"; |
289 | - translate_url = "https://translations.launchpad.net/cable"; |
290 | - |
291 | - about_authors = {"Tom Beckmann <tombeckmann@online.de>", "Akshay Shekher <voldyman666@gmail.com"}; |
292 | - about_documenters = {"Tom Beckmann <tombeckmann@online.de>"}; |
293 | - about_artists = {"Harvey Cabaguio"}; |
294 | - about_comments = "Development release, not all features implemented"; |
295 | - about_translators = ""; |
296 | - about_license_type = Gtk.License.GPL_3_0; |
297 | - } |
298 | - |
299 | - Gtk.Window window; |
300 | - bool welcome_shown; |
301 | - |
302 | - public Gtk.EventBox display_box; |
303 | - public Widgets.ServerList server_list; |
304 | - |
305 | - Gtk.Toolbar toolbar; |
306 | - Gtk.Box layout; |
307 | - Granite.Widgets.ThinPaned paned; |
308 | - Gtk.Box sidebar; |
309 | - Gtk.Menu menu; |
310 | - Granite.Widgets.Welcome welcome; |
311 | - |
312 | - public App () { |
313 | - Granite.Services.Logger.initialize ("Cable"); |
314 | - Granite.Services.Logger.DisplayLevel = Granite.Services.LogLevel.DEBUG; |
315 | - } |
316 | - |
317 | - void build () { |
318 | - |
319 | - window = new Gtk.Window (); |
320 | - layout = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); |
321 | - server_list = new Widgets.ServerList (); |
322 | - display_box = new Gtk.EventBox (); |
323 | - toolbar = new Gtk.Toolbar (); |
324 | - paned = new Granite.Widgets.ThinPaned (); |
325 | - menu = new Gtk.Menu (); |
326 | - sidebar = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); |
327 | - welcome = new Granite.Widgets.Welcome (_("Welcome to Cable"), _("Connect to the IRC world")); |
328 | - |
329 | - layout.pack_start( toolbar, false, false, 0); |
330 | - |
331 | - var join_button = new Gtk.ToolButton (new Gtk.Image.from_icon_name ("list-add", Gtk.IconSize.SMALL_TOOLBAR), _("Join a Channel")); |
332 | - var leave_button = new Gtk.ToolButton (new Gtk.Image.from_icon_name ("list-remove", Gtk.IconSize.SMALL_TOOLBAR), _("Leave Channel")); |
333 | - var user_settings_button = new Gtk.ToolButton (new Gtk.Image.from_icon_name ("avatar-default", Gtk.IconSize.SMALL_TOOLBAR), _("Leave Channel")); |
334 | - var add_server_buttton = new Gtk.ToolButton (new Gtk.Image.from_icon_name ("network-server", Gtk.IconSize.SMALL_TOOLBAR), _("Add a Server")); |
335 | - toolbar.insert(join_button, -1); |
336 | - toolbar.insert(leave_button, -1); |
337 | - toolbar.insert(user_settings_button, -1); |
338 | - toolbar.insert(add_server_buttton, -1); |
339 | - |
340 | - welcome.append ("internet-web-browser", _("Channel"), _("Join a Channel")); |
341 | - welcome.append ("network-server", _("Server"), _("Add a Custom Server")); |
342 | - |
343 | - /*var exp = new Gtk.ToolItem (); |
344 | - exp.set_expand (true); |
345 | - |
346 | - menu.append (edit_user); |
347 | - |
348 | - toolbar.insert (exp, -1); |
349 | - toolbar.insert (join_button, -1); |
350 | - toolbar.insert (leave_button, -1); |
351 | - toolbar.insert (exp, -1); |
352 | - toolbar.get_style_context ().add_class (Gtk.STYLE_CLASS_INLINE_TOOLBAR); |
353 | - toolbar.icon_size = 1;*/ |
354 | - |
355 | - paned.position = 150; |
356 | - |
357 | - sidebar.pack_start (server_list); |
358 | - |
359 | - paned.pack1 (sidebar, false, false); |
360 | - paned.pack2 (display_box, true, false); |
361 | - |
362 | - window.set_application (this); |
363 | - window.title = "Cable"; |
364 | - window.icon_name = "internet-chat"; |
365 | - window.set_default_size (740, 480); |
366 | - window.window_position = Gtk.WindowPosition.CENTER; |
367 | - |
368 | - welcome.activated.connect ((index) => { |
369 | - if (index == 0) { |
370 | - var dialog = get_join_dialog (); |
371 | - dialog.show_all (); |
372 | - dialog.run (); |
373 | - } else { |
374 | - var dialog = Widgets.Server.get_add_dialog (); |
375 | - dialog.show_all (); |
376 | - dialog.run (); |
377 | - } |
378 | - }); |
379 | - |
380 | - join_button.clicked.connect (() => { |
381 | - var dialog = get_join_dialog (); |
382 | - dialog.show_all (); |
383 | - dialog.run (); |
384 | - }); |
385 | - |
386 | - leave_button.clicked.connect (() => { |
387 | - server_list.current_server.leave_channel (server_list.current_channel.name); |
388 | - }); |
389 | - |
390 | - add_server_buttton.clicked.connect (() => { |
391 | - var dialog = Widgets.Server.get_add_dialog (); |
392 | - dialog.show_all (); |
393 | - dialog.run (); |
394 | - }); |
395 | - |
396 | - user_settings_button.clicked.connect (() => { |
397 | - var settings_dialog = new Widgets.SettingsDialog (); |
398 | - settings_dialog.show_all (); |
399 | - settings_dialog.run (); |
400 | - }); |
401 | - |
402 | - server_list.item_selected.connect ((item) => { |
403 | - if (item != null && item is Widgets.Channel) { |
404 | - display_box.remove (display_box.get_children ().nth_data (0)); |
405 | - display_box.add ((item as Widgets.Channel).room); |
406 | - display_box.show_all (); |
407 | - } |
408 | - }); |
409 | - |
410 | - /*initial setup*/ |
411 | - var settings = Cable.Settings.get_default (); |
412 | - |
413 | - //we got something to do |
414 | - if (settings.channels.length > 0) { |
415 | - |
416 | - } else { |
417 | - welcome_shown = true; |
418 | - layout.pack_start (welcome, true, true, 0); |
419 | - window.add (layout); |
420 | - window.show_all (); |
421 | - } |
422 | - |
423 | - //configuration incomplete |
424 | - if (settings.real_name == "" || settings.nick == "") { |
425 | - var settings_dialog = new Widgets.SettingsDialog (); |
426 | - settings_dialog.show_all (); |
427 | - settings_dialog.run (); |
428 | - } |
429 | - } |
430 | - |
431 | - public void join_channel (string? server_name, string server_URI, string channel_name) { |
432 | - var server = server_list.get_server_by_URI (server_URI) |
433 | - ?? new Widgets.Server (server_name, server_URI); |
434 | - server_list.add_server (server); |
435 | - |
436 | - server.joined_channel.connect ((channel) => { |
437 | - if (welcome_shown) { |
438 | - welcome_shown = false; |
439 | - |
440 | - layout.remove (welcome); |
441 | - layout.pack_start (paned, true, true, 0); |
442 | - this.window.add (layout); |
443 | - this.window.show_all (); |
444 | - |
445 | - server_list.selected = channel; |
446 | - } |
447 | - }); |
448 | - |
449 | - server.left_channel.connect ((channel) => { |
450 | - if (server_list.get_n_servers () == 0) { |
451 | - welcome_shown = true; |
452 | - |
453 | - layout.remove (paned); |
454 | - layout.pack_start (welcome, true, true, 0); |
455 | - this.window.add (layout); |
456 | - this.window.show_all (); |
457 | - } |
458 | - }); |
459 | - |
460 | - server.join_channel (channel_name); |
461 | - } |
462 | - |
463 | - public Gtk.Dialog get_join_dialog () { |
464 | - var dialog = new Gtk.Dialog (); |
465 | - dialog.modal = true; |
466 | - |
467 | - var box = new Gtk.Grid (); |
468 | - box.margin = 12; |
469 | - box.column_spacing = 6; |
470 | - box.row_spacing = 6; |
471 | - |
472 | - var entry = new Gtk.Entry (); |
473 | - var serverlabel = new Gtk.Label (_("Server")); |
474 | - entry.secondary_icon_name = "edit-redo-symbolic"; |
475 | - |
476 | - var list = Widgets.Server.get_server_list (); |
477 | - |
478 | - |
479 | - box.attach (serverlabel, 0, 0, 1, 1); |
480 | - serverlabel.set_alignment ( 1, 0.5f); |
481 | - box.attach (list, 1, 0, 1, 1); |
482 | - box.attach (new Gtk.Label (_("Join Channel") + " #"), 0, 1, 1, 1); |
483 | - box.attach (entry, 1, 1, 1, 1); |
484 | - box.margin = 6; |
485 | - |
486 | - entry.icon_release.connect (() => entry.activate ()); |
487 | - entry.activate.connect (() => { |
488 | - join_channel (list.get_active_text (), list.active_id, "#"+entry.text); |
489 | - dialog.destroy (); |
490 | - }); |
491 | - |
492 | - (dialog.get_content_area () as Gtk.Container).add (box); |
493 | - dialog.title = _("Join Channel"); |
494 | - |
495 | - entry.grab_focus (); |
496 | - |
497 | - return dialog; |
498 | - } |
499 | - |
500 | - public override void activate () { |
501 | - build (); |
502 | - } |
503 | - } |
504 | -} |
505 | - |
506 | -public static int main (string [] args) { |
507 | - Gtk.init (ref args); |
508 | - var cable = new Cable.App (); |
509 | - return cable.run (args); |
510 | -} |
511 | +/*** |
512 | + Copyright (C) 2013 Cable Developers |
513 | + |
514 | + This program or library is free software; you can redistribute it |
515 | + and/or modify it under the terms of the GNU Lesser General Public |
516 | + License as published by the Free Software Foundation; either |
517 | + version 3 of the License, or (at your option) any later version. |
518 | + |
519 | + This library is distributed in the hope that it will be useful, |
520 | + but WITHOUT ANY WARRANTY; without even the implied warranty of |
521 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
522 | + Lesser General Public License for more details. |
523 | + |
524 | + You should have received a copy of the GNU Lesser General |
525 | + Public License along with this library; if not, write to the |
526 | + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
527 | + Boston, MA 02110-1301 USA. |
528 | +***/ |
529 | + |
530 | +/** |
531 | + * Main class of the application. |
532 | + */ |
533 | +public class Cable.App : Granite.Application { |
534 | + |
535 | + construct { |
536 | + build_data_dir = Constants.DATADIR; |
537 | + build_pkg_data_dir = Constants.PKGDATADIR; |
538 | + build_release_name = Constants.RELEASE_NAME; |
539 | + build_version = Constants.VERSION; |
540 | + build_version_info = Constants.VERSION_INFO; |
541 | + |
542 | + program_name = "Cable"; |
543 | + exec_name = "cable"; |
544 | + |
545 | + app_years = "2012-2013"; |
546 | + app_icon = "internet-chat"; |
547 | + app_launcher = "cable.desktop"; |
548 | + //application_id = "net.launchpad.cable"; |
549 | + |
550 | + main_url = "https://code.launchpad.net/cable"; |
551 | + bug_url = "https://bugs.launchpad.net/cable"; |
552 | + help_url = "https://answers.launchpad.net/cable"; |
553 | + translate_url = "https://translations.launchpad.net/cable"; |
554 | + |
555 | + about_authors = {"Tom Beckmann <tombeckmann@online.de>", "Akshay Shekher <voldyman666@gmail.com", "Julien Spautz <spautz.julien@gmail.com"}; |
556 | + about_documenters = {"Tom Beckmann <tombeckmann@online.de>"}; |
557 | + about_artists = {"Harvey Cabaguio <harveycabaguio@gmail.com"}; |
558 | + about_comments = "Development release, not all features implemented"; |
559 | + about_translators = "Launchpad Translators"; |
560 | + about_license_type = Gtk.License.GPL_3_0; |
561 | + } |
562 | + |
563 | + public App () { |
564 | + Granite.Services.Logger.initialize ("Cable"); |
565 | + Granite.Services.Logger.DisplayLevel = Granite.Services.LogLevel.DEBUG; |
566 | + } |
567 | + |
568 | + public override void activate () { |
569 | + var window = new Cable.Window (this); |
570 | + this.add_window (window); |
571 | + window.show (); |
572 | + } |
573 | + |
574 | + static const OptionEntry[] entries = { |
575 | + { null } |
576 | + // version |
577 | + // reset - reset all settings |
578 | + }; |
579 | + |
580 | + public static int main (string[] args) { |
581 | + var context = new OptionContext ("File"); |
582 | + context.add_main_entries (entries, Constants.GETTEXT_PACKAGE); |
583 | + |
584 | + try { |
585 | + context.parse (ref args); |
586 | + } |
587 | + catch (Error e) { |
588 | + print (e.message + "\n"); |
589 | + } |
590 | + |
591 | + var cable = new Cable.App (); |
592 | + return cable.run (args); |
593 | + } |
594 | +} |
595 | + |
596 | |
597 | === modified file 'src/Config.vala.cmake' |
598 | --- src/Config.vala.cmake 2013-05-16 13:18:25 +0000 |
599 | +++ src/Config.vala.cmake 2013-06-28 19:09:26 +0000 |
600 | @@ -16,11 +16,11 @@ |
601 | // |
602 | |
603 | namespace Constants { |
604 | -public const string DATADIR = "@DATADIR@"; |
605 | -public const string PKGDATADIR = "@PKGDATADIR@"; |
606 | -public const string GETTEXT_PACKAGE = "@GETTEXT_PACKAGE@"; |
607 | -public const string RELEASE_NAME = "@RELEASE_NAME@"; |
608 | -public const string VERSION = "@VERSION@"; |
609 | -public const string VERSION_INFO = "@VERSION_INFO@"; |
610 | -public const string PLUGINDIR = "@PLUGINDIR@"; |
611 | + public const string DATADIR = "@DATADIR@"; |
612 | + public const string PKGDATADIR = "@PKGDATADIR@"; |
613 | + public const string GETTEXT_PACKAGE = "@GETTEXT_PACKAGE@"; |
614 | + public const string RELEASE_NAME = "@RELEASE_NAME@"; |
615 | + public const string VERSION = "@VERSION@"; |
616 | + public const string VERSION_INFO = "@VERSION_INFO@"; |
617 | + public const string PLUGINDIR = "@PLUGINDIR@"; |
618 | } |
619 | |
620 | === added directory 'src/Dialogs' |
621 | === added file 'src/Dialogs/JoinChannel.vala' |
622 | --- src/Dialogs/JoinChannel.vala 1970-01-01 00:00:00 +0000 |
623 | +++ src/Dialogs/JoinChannel.vala 2013-06-28 19:09:26 +0000 |
624 | @@ -0,0 +1,97 @@ |
625 | +/*** |
626 | + Copyright (C) 2013 Cable Developers |
627 | + |
628 | + This program or library is free software; you can redistribute it |
629 | + and/or modify it under the terms of the GNU Lesser General Public |
630 | + License as published by the Free Software Foundation; either |
631 | + version 3 of the License, or (at your option) any later version. |
632 | + |
633 | + This library is distributed in the hope that it will be useful, |
634 | + but WITHOUT ANY WARRANTY; without even the implied warranty of |
635 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
636 | + Lesser General Public License for more details. |
637 | + |
638 | + You should have received a copy of the GNU Lesser General |
639 | + Public License along with this library; if not, write to the |
640 | + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
641 | + Boston, MA 02110-1301 USA. |
642 | +***/ |
643 | + |
644 | +public class Cable.Dialogs.JoinChannel : Granite.Widgets.LightWindow { |
645 | + |
646 | + public signal void done (Settings.Network network, Settings.Identity identity, string channel); |
647 | + |
648 | + public JoinChannel () { |
649 | + this.modal = true; |
650 | + this.window_position = Gtk.WindowPosition.CENTER; |
651 | + |
652 | + var grid = new Gtk.Grid (); |
653 | + grid.margin = 12; |
654 | + grid.column_spacing = 6; |
655 | + grid.row_spacing = 6; |
656 | + |
657 | + // Labels |
658 | + var server_label = new Gtk.Label (_("Network:")); |
659 | + server_label.halign = Gtk.Align.END; |
660 | + server_label.valign = Gtk.Align.CENTER; |
661 | + |
662 | + var id_label = new Gtk.Label (_("Identity:")); |
663 | + id_label.halign = Gtk.Align.END; |
664 | + id_label.valign = Gtk.Align.CENTER; |
665 | + |
666 | + var channel_label = new Gtk.Label (_("Channel:")); |
667 | + channel_label.halign = Gtk.Align.END; |
668 | + channel_label.valign = Gtk.Align.CENTER; |
669 | + |
670 | + // Entries/Comboboxes |
671 | + var server_entry = new Gtk.ComboBoxText.with_entry (); |
672 | + for (int i = 0; i < Settings.networks.size; i++) |
673 | + server_entry.append (i.to_string (), Settings.networks[i].name); |
674 | + server_entry.active = 0; |
675 | + |
676 | + var id_entry = new Gtk.ComboBoxText.with_entry (); |
677 | + for (int i = 0; i < Settings.identities.size; i++) |
678 | + id_entry.append (i.to_string (), Settings.identities[i].nick_name); |
679 | + id_entry.active = 0; |
680 | + |
681 | + var channel_entry = new Gtk.Entry (); |
682 | + channel_entry.secondary_icon_name = "edit-redo-symbolic"; |
683 | + |
684 | + grid.attach (server_label, 0, 0, 1, 1); |
685 | + grid.attach (server_entry, 1, 0, 1, 1); |
686 | + grid.attach (id_label, 0, 1, 1, 1); |
687 | + grid.attach (id_entry, 1, 1, 1, 1); |
688 | + grid.attach (channel_label, 0, 2, 1, 1); |
689 | + grid.attach (channel_entry, 1, 2, 1, 1); |
690 | + grid.margin = 6; |
691 | + |
692 | + add (grid); |
693 | + this.title = _("Join Channel"); |
694 | + |
695 | + channel_entry.text = "#"; |
696 | + channel_entry.grab_focus (); |
697 | + channel_entry.set_position (-1); |
698 | + |
699 | + channel_entry.icon_release.connect (() => channel_entry.activate ()); |
700 | + channel_entry.activate.connect (() => { |
701 | + Settings.Network network; |
702 | + Settings.Identity identity; |
703 | + |
704 | + if (server_entry.active_id == null) { |
705 | + network = new Settings.Network (server_entry.get_active_text ()); |
706 | + } else { |
707 | + network = Settings.networks[int.parse (server_entry.active_id)]; |
708 | + } |
709 | + |
710 | + if (id_entry.active_id == null) { |
711 | + identity = new Settings.Identity (id_entry.get_active_text ()); |
712 | + } else { |
713 | + identity = Settings.identities[int.parse (id_entry.active_id)]; |
714 | + } |
715 | + |
716 | + done (network, identity, channel_entry.text); |
717 | + |
718 | + this.destroy (); |
719 | + }); |
720 | + } |
721 | +} |
722 | |
723 | === added file 'src/Dialogs/ManageIdentity.vala' |
724 | --- src/Dialogs/ManageIdentity.vala 1970-01-01 00:00:00 +0000 |
725 | +++ src/Dialogs/ManageIdentity.vala 2013-06-28 19:09:26 +0000 |
726 | @@ -0,0 +1,117 @@ |
727 | +/*** |
728 | + Copyright (C) 2013 Cable Developers |
729 | + |
730 | + This program or library is free software; you can redistribute it |
731 | + and/or modify it under the terms of the GNU Lesser General Public |
732 | + License as published by the Free Software Foundation; either |
733 | + version 3 of the License, or (at your option) any later version. |
734 | + |
735 | + This library is distributed in the hope that it will be useful, |
736 | + but WITHOUT ANY WARRANTY; without even the implied warranty of |
737 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
738 | + Lesser General Public License for more details. |
739 | + |
740 | + You should have received a copy of the GNU Lesser General |
741 | + Public License along with this library; if not, write to the |
742 | + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
743 | + Boston, MA 02110-1301 USA. |
744 | +***/ |
745 | + |
746 | +/** |
747 | + * Add or edit an identity. |
748 | + */ |
749 | +public class Cable.Dialogs.ManageIdentity : Granite.Widgets.LightWindow { |
750 | + |
751 | + /** |
752 | + * @param identity Resulting identity. |
753 | + */ |
754 | + public signal void done (Settings.Identity identity); |
755 | + |
756 | + /** |
757 | + * @param identity Identity to be edited or null if you want to create |
758 | + * a new one. |
759 | + */ |
760 | + public ManageIdentity (Settings.Identity? identity = null) { |
761 | + this.modal = true; |
762 | + this.window_position = Gtk.WindowPosition.CENTER; |
763 | + |
764 | + var grid = new Gtk.Grid (); |
765 | + grid.margin = 12; |
766 | + grid.column_spacing = 6; |
767 | + grid.row_spacing = 6; |
768 | + |
769 | + var nick_name = new Gtk.Entry (); |
770 | + nick_name.placeholder_text = _("displayed in chats"); |
771 | + nick_name.width_request = 250; |
772 | + var real_name = new Gtk.Entry (); |
773 | + real_name.placeholder_text = _("your real name"); |
774 | + var part_message = new Gtk.Entry (); |
775 | + part_message.placeholder_text = _("displayed when you leave a room"); |
776 | + |
777 | + grid.attach (new Utils.Label.right (_("Nick Name:")), 0, 0, 1, 1); |
778 | + grid.attach (nick_name, 1, 0, 1, 1); |
779 | + grid.attach (new Utils.Label.right (_("Real Name:")), 0, 1, 1, 1); |
780 | + grid.attach (real_name, 1, 1, 1, 1); |
781 | + grid.attach (new Utils.Label.right (_("Part Message:")), 0, 2, 1, 1); |
782 | + grid.attach (part_message, 1, 2, 1, 1); |
783 | + |
784 | + var cancel_button = new Gtk.Button.with_label (_("Cancel")); |
785 | + var apply_button = new Gtk.Button (); |
786 | + apply_button.label = (identity == null) ? _("Add Identity") |
787 | + : _("Apply Changes"); |
788 | + apply_button.sensitive = (identity != null); |
789 | + |
790 | + var button_box = new Gtk.ButtonBox (Gtk.Orientation.HORIZONTAL); |
791 | + button_box.layout_style = Gtk.ButtonBoxStyle.END; |
792 | + button_box.add (cancel_button); |
793 | + button_box.add (apply_button); |
794 | + |
795 | + grid.attach (button_box, 0, 3, 2, 1); |
796 | + |
797 | + this.add (grid); |
798 | + this.title = (identity == null) ? _("Add Identity") |
799 | + : _("Edit Identity"); |
800 | + |
801 | + if (identity != null) { |
802 | + nick_name.text = identity.nick_name; |
803 | + real_name.text = identity.real_name; |
804 | + part_message.text = identity.part_message; |
805 | + } |
806 | + |
807 | + nick_name.changed.connect (() => { |
808 | + apply_button.sensitive = (nick_name.text != ""); |
809 | + }); |
810 | + |
811 | + apply_button.clicked.connect (() => { |
812 | + if (identity == null) { |
813 | + done (create_identity (nick_name.text, real_name.text, part_message.text)); |
814 | + } else { |
815 | + identity.real_name = real_name.text.strip (); |
816 | + identity.nick_name = nick_name.text.strip (); |
817 | + identity.part_message = part_message.text.strip (); |
818 | + done (identity); |
819 | + } |
820 | + |
821 | + this.destroy (); |
822 | + }); |
823 | + |
824 | + cancel_button.clicked.connect (() => { |
825 | + this.destroy (); |
826 | + }); |
827 | + } |
828 | + |
829 | + Settings.Identity create_identity (string nick_name, string real_name, |
830 | + string part_message) |
831 | + requires (nick_name.strip () != "") { |
832 | + |
833 | + if (nick_name.strip () == "") |
834 | + return (Settings.Identity) null; |
835 | + |
836 | + if (real_name.strip () == "") |
837 | + real_name = null; |
838 | + if (part_message.strip () == "") |
839 | + part_message = null; |
840 | + |
841 | + return new Settings.Identity (nick_name, real_name, part_message); |
842 | + } |
843 | +} |
844 | |
845 | === added file 'src/Dialogs/ManageNetwork.vala' |
846 | --- src/Dialogs/ManageNetwork.vala 1970-01-01 00:00:00 +0000 |
847 | +++ src/Dialogs/ManageNetwork.vala 2013-06-28 19:09:26 +0000 |
848 | @@ -0,0 +1,116 @@ |
849 | +/*** |
850 | + Copyright (C) 2013 Cable Developers |
851 | + |
852 | + This program or library is free software; you can redistribute it |
853 | + and/or modify it under the terms of the GNU Lesser General Public |
854 | + License as published by the Free Software Foundation; either |
855 | + version 3 of the License, or (at your option) any later version. |
856 | + |
857 | + This library is distributed in the hope that it will be useful, |
858 | + but WITHOUT ANY WARRANTY; without even the implied warranty of |
859 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
860 | + Lesser General Public License for more details. |
861 | + |
862 | + You should have received a copy of the GNU Lesser General |
863 | + Public License along with this library; if not, write to the |
864 | + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
865 | + Boston, MA 02110-1301 USA. |
866 | +***/ |
867 | + |
868 | +/** |
869 | + * Add or edit a network. |
870 | + */ |
871 | +public class Cable.Dialogs.ManageNetwork : Granite.Widgets.LightWindow { |
872 | + |
873 | + /** |
874 | + * @param network Resulting network. |
875 | + */ |
876 | + public signal void done (Settings.Network network); |
877 | + |
878 | + /** |
879 | + * @param network Network to be edited or null if you want to create |
880 | + * a new one. |
881 | + */ |
882 | + public ManageNetwork (Settings.Network? network = null) { |
883 | + this.modal = true; |
884 | + this.window_position = Gtk.WindowPosition.CENTER; |
885 | + |
886 | + var grid = new Gtk.Grid (); |
887 | + grid.margin = 12; |
888 | + grid.column_spacing = 6; |
889 | + grid.row_spacing = 6; |
890 | + |
891 | + var address = new Gtk.Entry (); |
892 | + address.placeholder_text = _("irc.network.net"); |
893 | + address.width_request = 250; |
894 | + var name = new Gtk.Entry (); |
895 | + name.placeholder_text = _("display name"); |
896 | + var password = new Gtk.Entry (); |
897 | + password.placeholder_text = _("optional"); |
898 | + |
899 | + grid.attach (new Utils.Label.right (_("Address:")), 0, 0, 1, 1); |
900 | + grid.attach (address, 1, 0, 1, 1); |
901 | + grid.attach (new Utils.Label.right (_("Name:")), 0, 1, 1, 1); |
902 | + grid.attach (name, 1, 1, 1, 1); |
903 | + grid.attach (new Utils.Label.right (_("Password:")), 0, 2, 1, 1); |
904 | + grid.attach (password, 1, 2, 1, 1); |
905 | + |
906 | + var cancel_button = new Gtk.Button.with_label (_("Cancel")); |
907 | + var apply_button = new Gtk.Button (); |
908 | + apply_button.label = (network == null) ? _("Add Network") |
909 | + : _("Apply Changes"); |
910 | + apply_button.sensitive = (network != null); |
911 | + |
912 | + var button_box = new Gtk.ButtonBox (Gtk.Orientation.HORIZONTAL); |
913 | + button_box.layout_style = Gtk.ButtonBoxStyle.END; |
914 | + button_box.add (cancel_button); |
915 | + button_box.add (apply_button); |
916 | + |
917 | + grid.attach (button_box, 0, 3, 2, 1); |
918 | + |
919 | + this.add (grid); |
920 | + this.title = (network == null) ? _("Add Network") |
921 | + : _("Change Network"); |
922 | + |
923 | + if (network != null) { |
924 | + address.text = network.address; |
925 | + name.text = network.name; |
926 | + password.text = network.password; |
927 | + } |
928 | + |
929 | + address.changed.connect (() => { |
930 | + apply_button.sensitive = (address.text != ""); |
931 | + }); |
932 | + |
933 | + apply_button.clicked.connect (() => { |
934 | + if (network == null) { |
935 | + done (create_network (address.text, name.text, password.text)); |
936 | + } else { |
937 | + network.address = address.text.strip (); |
938 | + network.name = name.text.strip (); |
939 | + network.password = password.text.strip (); |
940 | + done (network); |
941 | + } |
942 | + this.destroy (); |
943 | + }); |
944 | + |
945 | + cancel_button.clicked.connect (() => { |
946 | + this.destroy (); |
947 | + }); |
948 | + } |
949 | + |
950 | + Settings.Network create_network (string address, string name, |
951 | + string password) |
952 | + requires (address.strip () != "") { |
953 | + |
954 | + if (address.strip () == "") |
955 | + return (Settings.Network) null; |
956 | + |
957 | + if (name.strip () == "") |
958 | + name = null; |
959 | + if (password.strip () == "") |
960 | + password = null; |
961 | + |
962 | + return new Settings.Network (address, name, password); |
963 | + } |
964 | +} |
965 | |
966 | === added file 'src/Dialogs/Preferences.vala' |
967 | --- src/Dialogs/Preferences.vala 1970-01-01 00:00:00 +0000 |
968 | +++ src/Dialogs/Preferences.vala 2013-06-28 19:09:26 +0000 |
969 | @@ -0,0 +1,214 @@ |
970 | +/*** |
971 | + Copyright (C) 2013 Cable Developers |
972 | + |
973 | + This program or library is free software; you can redistribute it |
974 | + and/or modify it under the terms of the GNU Lesser General Public |
975 | + License as published by the Free Software Foundation; either |
976 | + version 3 of the License, or (at your option) any later version. |
977 | + |
978 | + This library is distributed in the hope that it will be useful, |
979 | + but WITHOUT ANY WARRANTY; without even the implied warranty of |
980 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
981 | + Lesser General Public License for more details. |
982 | + |
983 | + You should have received a copy of the GNU Lesser General |
984 | + Public License along with this library; if not, write to the |
985 | + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
986 | + Boston, MA 02110-1301 USA. |
987 | +***/ |
988 | + |
989 | +public class Cable.Dialogs.Preferences : Granite.Widgets.LightWindow { |
990 | + |
991 | + public Preferences () { |
992 | + this.window_position = Gtk.WindowPosition.CENTER; |
993 | + |
994 | + var static_notebook = new Granite.Widgets.StaticNotebook (false); |
995 | + static_notebook.margin = 12; |
996 | + static_notebook.expand = true; |
997 | + static_notebook.append_page (new NetworkPrefs (), new Gtk.Label (_("Networks"))); |
998 | + static_notebook.append_page (new IdentityPrefs (), new Gtk.Label (_("Identities"))); |
999 | + |
1000 | + this.add (static_notebook); |
1001 | + } |
1002 | +} |
1003 | + |
1004 | +public class Cable.Dialogs.NetworkPrefs : Gtk.Grid { |
1005 | + |
1006 | + public NetworkPrefs () { |
1007 | + var tree = new Gtk.TreeView (); |
1008 | + var scroll = new Gtk.ScrolledWindow(null, null); |
1009 | + |
1010 | + sync (tree); |
1011 | + |
1012 | + var cell = new Gtk.CellRendererText (); |
1013 | + tree.insert_column_with_attributes (-1, "Name", cell, "text", 0); |
1014 | + tree.insert_column_with_attributes (-1, "Address", cell, "text", 1); |
1015 | + |
1016 | + scroll.set_size_request (300, 300); |
1017 | + scroll.hscrollbar_policy = Gtk.PolicyType.AUTOMATIC; |
1018 | + scroll.vscrollbar_policy = Gtk.PolicyType.AUTOMATIC; |
1019 | + scroll.shadow_type = Gtk.ShadowType.IN; |
1020 | + scroll.expand = true; |
1021 | + scroll.add (tree); |
1022 | + |
1023 | + var toolbar = new Gtk.Toolbar(); |
1024 | + toolbar.set_style(Gtk.ToolbarStyle.ICONS); |
1025 | + toolbar.set_icon_size(Gtk.IconSize.SMALL_TOOLBAR); |
1026 | + toolbar.set_show_arrow(false); |
1027 | + toolbar.hexpand = true; |
1028 | + |
1029 | + scroll.get_style_context().set_junction_sides(Gtk.JunctionSides.BOTTOM); |
1030 | + toolbar.get_style_context().add_class(Gtk.STYLE_CLASS_INLINE_TOOLBAR); |
1031 | + toolbar.get_style_context().set_junction_sides(Gtk.JunctionSides.TOP); |
1032 | + |
1033 | + var add_button = new Gtk.ToolButton (null, _("Add…")); |
1034 | + var remove_button = new Gtk.ToolButton (null, _("Remove")); |
1035 | + |
1036 | + add_button.set_tooltip_text (_("Add…")); |
1037 | + remove_button.set_tooltip_text (_("Remove")); |
1038 | + |
1039 | + add_button.set_icon_name ("list-add-symbolic"); |
1040 | + remove_button.set_icon_name ("list-remove-symbolic"); |
1041 | + |
1042 | + toolbar.insert (add_button, -1); |
1043 | + toolbar.insert (remove_button, -1); |
1044 | + |
1045 | + this.attach (scroll, 0, 0, 1, 1); |
1046 | + this.attach (toolbar, 0, 1, 1, 1); |
1047 | + |
1048 | + add_button.clicked.connect (() => { |
1049 | + var dialog = new Dialogs.ManageNetwork (); |
1050 | + dialog.done.connect ((network) => { |
1051 | + Settings.networks.add (network); |
1052 | + this.sync (tree); |
1053 | + }); |
1054 | + dialog.show_all (); |
1055 | + }); |
1056 | + |
1057 | + remove_button.clicked.connect (() => { |
1058 | + Gtk.TreePath? path; |
1059 | + tree.get_cursor (out path, null); |
1060 | + |
1061 | + if (path == null) |
1062 | + return; |
1063 | + |
1064 | + var index = path.get_indices ()[0]; |
1065 | + Settings.networks.remove (Settings.networks[index]); |
1066 | + sync (tree); |
1067 | + }); |
1068 | + |
1069 | + tree.row_activated.connect ((path) => { |
1070 | + var index = path.get_indices ()[0]; |
1071 | + var dialog = new Dialogs.ManageNetwork (Settings.networks[index]); |
1072 | + dialog.done.connect (() => { |
1073 | + //Settings.networks[index] = network; |
1074 | + this.sync (tree); |
1075 | + }); |
1076 | + dialog.show_all (); |
1077 | + }); |
1078 | + } |
1079 | + |
1080 | + private void sync (Gtk.TreeView tree) { |
1081 | + var store = new Gtk.ListStore (2, typeof (string), typeof (string)); |
1082 | + |
1083 | + Gtk.TreeIter iter; |
1084 | + |
1085 | + foreach (var network in Settings.networks) { |
1086 | + store.append (out iter); |
1087 | + store.set (iter, 0, network.name, 1, network.address, -1); |
1088 | + } |
1089 | + |
1090 | + tree.model = store; |
1091 | + } |
1092 | +} |
1093 | + |
1094 | + public class Cable.Dialogs.IdentityPrefs : Gtk.Grid { |
1095 | + |
1096 | + public IdentityPrefs () { |
1097 | + var store = new Gtk.ListStore (2, typeof (string), typeof (string)); |
1098 | + var tree = new Gtk.TreeView (); |
1099 | + var scroll = new Gtk.ScrolledWindow(null, null); |
1100 | + |
1101 | + sync (tree); |
1102 | + |
1103 | + var cell = new Gtk.CellRendererText (); |
1104 | + tree.insert_column_with_attributes (-1, "Nick", cell, "text", 0); |
1105 | + tree.insert_column_with_attributes (-1, "Real Name", cell, "text", 1); |
1106 | + |
1107 | + scroll.set_size_request (300, 300); |
1108 | + scroll.hscrollbar_policy = Gtk.PolicyType.AUTOMATIC; |
1109 | + scroll.vscrollbar_policy = Gtk.PolicyType.AUTOMATIC; |
1110 | + scroll.shadow_type = Gtk.ShadowType.IN; |
1111 | + scroll.expand = true; |
1112 | + scroll.add (tree); |
1113 | + |
1114 | + var toolbar = new Gtk.Toolbar(); |
1115 | + toolbar.set_style(Gtk.ToolbarStyle.ICONS); |
1116 | + toolbar.set_icon_size(Gtk.IconSize.SMALL_TOOLBAR); |
1117 | + toolbar.set_show_arrow(false); |
1118 | + toolbar.hexpand = true; |
1119 | + |
1120 | + scroll.get_style_context().set_junction_sides(Gtk.JunctionSides.BOTTOM); |
1121 | + toolbar.get_style_context().add_class(Gtk.STYLE_CLASS_INLINE_TOOLBAR); |
1122 | + toolbar.get_style_context().set_junction_sides(Gtk.JunctionSides.TOP); |
1123 | + |
1124 | + var add_button = new Gtk.ToolButton (null, _("Add")); |
1125 | + var remove_button = new Gtk.ToolButton (null, _("Remove")); |
1126 | + |
1127 | + add_button.set_tooltip_text (_("Add")); |
1128 | + remove_button.set_tooltip_text (_("Remove")); |
1129 | + |
1130 | + add_button.set_icon_name ("list-add-symbolic"); |
1131 | + remove_button.set_icon_name ("list-remove-symbolic"); |
1132 | + |
1133 | + toolbar.insert (add_button, -1); |
1134 | + toolbar.insert (remove_button, -1); |
1135 | + |
1136 | + this.attach (scroll, 0, 0, 1, 1); |
1137 | + this.attach (toolbar, 0, 1, 1, 1); |
1138 | + |
1139 | + add_button.clicked.connect (() => { |
1140 | + var dialog = new Dialogs.ManageIdentity (); |
1141 | + dialog.done.connect ((identitie) => { |
1142 | + Settings.identities.add (identitie); |
1143 | + this.sync (tree); |
1144 | + }); |
1145 | + dialog.show_all (); |
1146 | + }); |
1147 | + |
1148 | + remove_button.clicked.connect (() => { |
1149 | + Gtk.TreePath? path; |
1150 | + tree.get_cursor (out path, null); |
1151 | + |
1152 | + if (path == null) |
1153 | + return; |
1154 | + |
1155 | + var index = path.get_indices ()[0]; |
1156 | + Settings.identities.remove (Settings.identities[index]); |
1157 | + sync (tree); |
1158 | + }); |
1159 | + |
1160 | + tree.row_activated.connect ((path) => { |
1161 | + var index = path.get_indices ()[0]; |
1162 | + var dialog = new Dialogs.ManageIdentity (Settings.identities[index]); |
1163 | + dialog.done.connect (() => { |
1164 | + //Settings.identities[index] = id; |
1165 | + this.sync (tree); |
1166 | + }); |
1167 | + dialog.show_all (); |
1168 | + }); |
1169 | + } |
1170 | + |
1171 | + private void sync (Gtk.TreeView tree) { |
1172 | + var store = new Gtk.ListStore (2, typeof (string), typeof (string)); |
1173 | + |
1174 | + Gtk.TreeIter iter; |
1175 | + |
1176 | + foreach (var identity in Settings.identities) { |
1177 | + store.append (out iter); |
1178 | + store.set (iter, 0, identity.nick_name, 1, identity.real_name, -1); |
1179 | + } |
1180 | + |
1181 | + tree.model = store; |
1182 | + } |
1183 | +} |
1184 | |
1185 | === removed file 'src/Global.vala' |
1186 | --- src/Global.vala 2013-05-29 00:24:15 +0000 |
1187 | +++ src/Global.vala 1970-01-01 00:00:00 +0000 |
1188 | @@ -1,18 +0,0 @@ |
1189 | -namespace Cable { |
1190 | - |
1191 | - public class Global : Object { |
1192 | - |
1193 | - public string user_nick { get; set; } |
1194 | - |
1195 | - Global () { |
1196 | - } |
1197 | - |
1198 | - static Global? instance; |
1199 | - |
1200 | - public static Global get_default () { |
1201 | - if (instance == null) |
1202 | - instance = new Global (); |
1203 | - return instance; |
1204 | - } |
1205 | - } |
1206 | -} |
1207 | \ No newline at end of file |
1208 | |
1209 | === added directory 'src/Services' |
1210 | === added file 'src/Services/Client.vala' |
1211 | --- src/Services/Client.vala 1970-01-01 00:00:00 +0000 |
1212 | +++ src/Services/Client.vala 2013-06-28 19:09:26 +0000 |
1213 | @@ -0,0 +1,278 @@ |
1214 | +/*** |
1215 | + Copyright (C) 2013 Cable Developers |
1216 | + |
1217 | + This program or library is free software; you can redistribute it |
1218 | + and/or modify it under the terms of the GNU Lesser General Public |
1219 | + License as published by the Free Software Foundation; either |
1220 | + version 3 of the License, or (at your option) any later version. |
1221 | + |
1222 | + This library is distributed in the hope that it will be useful, |
1223 | + but WITHOUT ANY WARRANTY; without even the implied warranty of |
1224 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
1225 | + Lesser General Public License for more details. |
1226 | + |
1227 | + You should have received a copy of the GNU Lesser General |
1228 | + Public License along with this library; if not, write to the |
1229 | + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
1230 | + Boston, MA 02110-1301 USA. |
1231 | +***/ |
1232 | + |
1233 | +/** |
1234 | + * This is a dbus interface to the maki daemon from the SushiIRC project. |
1235 | + * Use the methods to send requests or messages to the server and the |
1236 | + * signals to react to the server's replies. |
1237 | + * |
1238 | + * TODO document each function or take the actual documentation, if it exists |
1239 | + */ |
1240 | +[DBus (name = "de.ikkoku.sushi", timeout = 120000)] |
1241 | +private interface Cable.Services.Client : GLib.Object { |
1242 | + |
1243 | + [DBus (name = "action")] |
1244 | + public abstract void action (string server, string channel, string message) throws GLib.IOError; |
1245 | + |
1246 | + [DBus (name = "away")] |
1247 | + public abstract void away (string server, string message) throws GLib.IOError; |
1248 | + |
1249 | + [DBus (name = "back")] |
1250 | + public abstract void back (string server) throws GLib.IOError; |
1251 | + |
1252 | + [DBus (name = "channel_nicks")] |
1253 | + public abstract void channel_nicks (string server, string channel, out string[] nicks, out string[] prefixes) throws GLib.IOError; |
1254 | + |
1255 | + [DBus (name = "channel_topic")] |
1256 | + public abstract string channel_topic (string server, string channel) throws GLib.IOError; |
1257 | + |
1258 | + [DBus (name = "channels")] |
1259 | + public abstract string[] channels (string server) throws GLib.IOError; |
1260 | + |
1261 | + [DBus (name = "config_get")] |
1262 | + public abstract string config_get (string group, string key) throws GLib.IOError; |
1263 | + |
1264 | + [DBus (name = "config_set")] |
1265 | + public abstract void config_set (string group, string key, string value) throws GLib.IOError; |
1266 | + |
1267 | + [DBus (name = "connect")] |
1268 | + public abstract void connect (string server) throws GLib.IOError; |
1269 | + |
1270 | + [DBus (name = "ctcp")] |
1271 | + public abstract void ctcp (string server, string target, string message) throws GLib.IOError; |
1272 | + |
1273 | + [DBus (name = "dcc_send")] |
1274 | + public abstract void dcc_send(string server, string target, string path) throws GLib.IOError; |
1275 | + |
1276 | + [DBus (name = "dcc_sends")] |
1277 | + public abstract void dcc_sends (out uint64[] ids, out string[] servers, out string[] froms, out string[] filenames, out uint64[] sizes, out uint64[] progresses, out uint64[] speeds, out uint64[] statuses) throws GLib.IOError; |
1278 | + |
1279 | + [DBus (name = "dcc_send_accept")] |
1280 | + public abstract void dcc_send_accept (uint64 id) throws GLib.IOError; |
1281 | + |
1282 | + [DBus (name = "dcc_send_get")] |
1283 | + public abstract string dcc_send_get (uint64 id, string key) throws GLib.IOError; |
1284 | + |
1285 | + [DBus (name = "dcc_send_remove")] |
1286 | + public abstract void dcc_send_remove (uint64 id) throws GLib.IOError; |
1287 | + |
1288 | + [DBus (name = "dcc_send_resume")] |
1289 | + public abstract void dcc_send_resume (uint64 id) throws GLib.IOError; |
1290 | + |
1291 | + [DBus (name = "dcc_send_set")] |
1292 | + public abstract void dcc_send_set (uint64 id, string key, string value) throws GLib.IOError; |
1293 | + |
1294 | + [DBus (name = "ignore")] |
1295 | + public abstract void ignore (string server, string pattern) throws GLib.IOError; |
1296 | + |
1297 | + [DBus (name = "ignores")] |
1298 | + public abstract string[] ignores (string server) throws GLib.IOError; |
1299 | + |
1300 | + [DBus (name = "invite")] |
1301 | + public abstract void invite (string server, string channel, string who) throws GLib.IOError; |
1302 | + |
1303 | + [DBus (name = "join")] |
1304 | + public abstract void join (string server, string channel, string key) throws GLib.IOError; |
1305 | + |
1306 | + [DBus (name = "kick")] |
1307 | + public abstract void kick (string server, string channel, string who, string message) throws GLib.IOError; |
1308 | + |
1309 | + [DBus (name = "list")] |
1310 | + public abstract void list (string server, string channel) throws GLib.IOError; |
1311 | + |
1312 | + [DBus (name = "log")] |
1313 | + public abstract string[] log (string server, string target, uint64 lines) throws GLib.IOError; |
1314 | + |
1315 | + [DBus (name = "message")] |
1316 | + public abstract void message (string server, string target, string message) throws GLib.IOError; |
1317 | + |
1318 | + [DBus (name = "mode")] |
1319 | + public abstract void mode (string server, string target, string mode) throws GLib.IOError; |
1320 | + |
1321 | + [DBus (name = "names")] |
1322 | + public abstract void names (string server, string channel) throws GLib.IOError; |
1323 | + |
1324 | + [DBus (name = "nick")] |
1325 | + public abstract void nick (string server, string nick) throws GLib.IOError; |
1326 | + |
1327 | + [DBus (name = "nickserv")] |
1328 | + public abstract void nickserv (string server) throws GLib.IOError; |
1329 | + |
1330 | + [DBus (name = "notice")] |
1331 | + public abstract void notice (string server, string target, string message) throws GLib.IOError; |
1332 | + |
1333 | + [DBus (name = "oper")] |
1334 | + public abstract void oper (string server, string name, string password) throws GLib.IOError; |
1335 | + |
1336 | + [DBus (name = "part")] |
1337 | + public abstract void part (string server, string channel, string message) throws GLib.IOError; |
1338 | + |
1339 | + [DBus (name = "quit")] |
1340 | + public abstract void quit (string server, string message) throws GLib.IOError; |
1341 | + |
1342 | + [DBus (name = "raw")] |
1343 | + public abstract void raw (string server, string command) throws GLib.IOError; |
1344 | + |
1345 | + [DBus (name = "server_get")] |
1346 | + public abstract string server_get (string server, string group, string key) throws GLib.IOError; |
1347 | + |
1348 | + [DBus (name = "server_get_list")] |
1349 | + public abstract string[] server_get_list (string server, string group, string key) throws GLib.IOError; |
1350 | + |
1351 | + [DBus (name = "server_list")] |
1352 | + public abstract string[] server_list (string server, string group) throws GLib.IOError; |
1353 | + |
1354 | + [DBus (name = "server_remove")] |
1355 | + public abstract void server_remove (string server, string group, string key) throws GLib.IOError; |
1356 | + |
1357 | + [DBus (name = "server_rename")] |
1358 | + public abstract void server_rename (string old, string new_) throws GLib.IOError; |
1359 | + |
1360 | + [DBus (name = "server_set")] |
1361 | + public abstract void server_set (string server, string group, string key, string value) throws GLib.IOError; |
1362 | + |
1363 | + [DBus (name = "server_set_list")] |
1364 | + public abstract void server_set_list (string server, string group, string key, string[] list) throws GLib.IOError; |
1365 | + |
1366 | + [DBus (name = "servers")] |
1367 | + public abstract string[] servers () throws GLib.IOError; |
1368 | + |
1369 | + [DBus (name = "shutdown")] |
1370 | + public abstract void shutdown (string message) throws GLib.IOError; |
1371 | + |
1372 | + [DBus (name = "support_chantypes")] |
1373 | + public abstract string support_chantypes (string server) throws GLib.IOError; |
1374 | + |
1375 | + [DBus (name = "support_prefix")] |
1376 | + public abstract string[] support_prefix (string server) throws GLib.IOError; |
1377 | + |
1378 | + [DBus (name = "topic")] |
1379 | + public abstract void topic (string server, string channel, string topic) throws GLib.IOError; |
1380 | + |
1381 | + [DBus (name = "unignore")] |
1382 | + public abstract void unignore (string server, string pattern) throws GLib.IOError; |
1383 | + |
1384 | + [DBus (name = "user_away")] |
1385 | + public abstract bool user_away (string server, string nick) throws GLib.IOError; |
1386 | + |
1387 | + [DBus (name = "user_channel_mode")] |
1388 | + public abstract string user_channel_mode (string server, string channel, string nick) throws GLib.IOError; |
1389 | + |
1390 | + [DBus (name = "user_channel_prefix")] |
1391 | + public abstract string user_channel_prefix (string server, string channel, string nick) throws GLib.IOError; |
1392 | + |
1393 | + [DBus (name = "user_from")] |
1394 | + public abstract string user_from (string server, string nick) throws GLib.IOError; |
1395 | + |
1396 | + [DBus (name = "version")] |
1397 | + public abstract uint64[] version () throws GLib.IOError; |
1398 | + |
1399 | + [DBus (name = "who")] |
1400 | + public abstract void who (string server, string mask, bool operators_only) throws GLib.IOError; |
1401 | + |
1402 | + [DBus (name = "whois")] |
1403 | + public abstract void whois (string server, string mask) throws GLib.IOError; |
1404 | + |
1405 | + [DBus (name = "action")] |
1406 | + public signal void event_action (int64 time, string server, string from, string target, string message); |
1407 | + |
1408 | + [DBus (name = "away")] |
1409 | + public signal void event_away (int64 time, string server); |
1410 | + |
1411 | + [DBus (name = "away_message")] |
1412 | + public signal void event_away_message (int64 time, string server, string nick, string message); |
1413 | + |
1414 | + [DBus (name = "back")] |
1415 | + public signal void event_back (int64 time, string server); |
1416 | + |
1417 | + [DBus (name = "banlist")] |
1418 | + public signal void event_banlist (int64 time, string server, string channel, string mask, string who, int64 when); |
1419 | + |
1420 | + [DBus (name = "cannot_join")] |
1421 | + public signal void event_cannot_join (int64 time, string server, string channel, string reason); |
1422 | + |
1423 | + [DBus (name = "connect")] |
1424 | + public signal void event_connect (int64 time, string server); |
1425 | + |
1426 | + [DBus (name = "connected")] |
1427 | + public signal void event_connected (int64 time, string server); |
1428 | + |
1429 | + [DBus (name = "ctcp")] |
1430 | + public signal void event_ctcp (int64 time, string server, string from, string target, string message); |
1431 | + |
1432 | + [DBus (name = "dcc_send")] |
1433 | + public signal void event_dcc_send (int64 time, string server, uint64 id, string from, string filename, uint64 size, uint64 progress, uint64 speed, uint64 status); |
1434 | + |
1435 | + [DBus (name = "error")] |
1436 | + public signal void event_error (int64 time, string server, string domain, string reason, string[] arguments); |
1437 | + |
1438 | + [DBus (name = "invite")] |
1439 | + public signal void event_invite (int64 time, string server, string from, string channel, string who); |
1440 | + |
1441 | + [DBus (name = "join")] |
1442 | + public signal void event_join (int64 time, string server, string from, string channel); |
1443 | + |
1444 | + [DBus (name = "kick")] |
1445 | + public signal void event_kick (int64 time, string server, string from, string channel, string who, string message); |
1446 | + |
1447 | + [DBus (name = "list")] |
1448 | + public signal void event_list (int64 time, string server, string channel, int64 users, string topic); |
1449 | + |
1450 | + [DBus (name = "message")] |
1451 | + public signal void event_message (int64 time, string server, string from, string target, string message); |
1452 | + |
1453 | + [DBus (name = "mode")] |
1454 | + public signal void event_mode (int64 time, string server, string from, string target, string mode, string parameter); |
1455 | + |
1456 | + [DBus (name = "motd")] |
1457 | + public signal void event_motd (int64 time, string server, string message); |
1458 | + |
1459 | + [DBus (name = "names")] |
1460 | + public signal void event_names (int64 time, string server, string channel, string[] nicks, string[] prefixes); |
1461 | + |
1462 | + [DBus (name = "nick")] |
1463 | + public signal void event_nick (int64 time, string server, string from, string new_nick); |
1464 | + |
1465 | + [DBus (name = "no_such")] |
1466 | + public signal void event_no_such (int64 time, string server, string target, string type); |
1467 | + |
1468 | + [DBus (name = "notice")] |
1469 | + public signal void event_notice (int64 time, string server, string from, string target, string message); |
1470 | + |
1471 | + [DBus (name = "oper")] |
1472 | + public signal void event_oper (int64 time, string server); |
1473 | + |
1474 | + [DBus (name = "part")] |
1475 | + public signal void event_part (int64 time, string server, string from, string channel, string message); |
1476 | + |
1477 | + [DBus (name = "quit")] |
1478 | + public signal void event_quit (int64 time, string server, string from, string message); |
1479 | + |
1480 | + [DBus (name = "shutdown")] |
1481 | + public signal void event_shutdown (int64 time); |
1482 | + |
1483 | + [DBus (name = "topic")] |
1484 | + public signal void event_topic (int64 time, string server, string from, string channel, string topic); |
1485 | + |
1486 | + [DBus (name = "user_away")] |
1487 | + public signal void event_user_away (int64 time, string server, string from, bool away); |
1488 | + |
1489 | + [DBus (name = "whois")] |
1490 | + public signal void event_whois (int64 time, string server, string nick, string message); |
1491 | +} |
1492 | |
1493 | === added file 'src/Services/Identity.vala' |
1494 | --- src/Services/Identity.vala 1970-01-01 00:00:00 +0000 |
1495 | +++ src/Services/Identity.vala 2013-06-28 19:09:26 +0000 |
1496 | @@ -0,0 +1,123 @@ |
1497 | +/*** |
1498 | + Copyright (C) 2013 Cable Developers |
1499 | + |
1500 | + This program or library is free software; you can redistribute it |
1501 | + and/or modify it under the terms of the GNU Lesser General Public |
1502 | + License as published by the Free Software Foundation; either |
1503 | + version 3 of the License, or (at your option) any later version. |
1504 | + |
1505 | + This library is distributed in the hope that it will be useful, |
1506 | + but WITHOUT ANY WARRANTY; without even the implied warranty of |
1507 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
1508 | + Lesser General Public License for more details. |
1509 | + |
1510 | + You should have received a copy of the GNU Lesser General |
1511 | + Public License along with this library; if not, write to the |
1512 | + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
1513 | + Boston, MA 02110-1301 USA. |
1514 | +***/ |
1515 | + |
1516 | +/** |
1517 | + * This class stores one identity and provides some convenience over a |
1518 | + * simple struct. |
1519 | + */ |
1520 | +public class Cable.Settings.Identity : GLib.Object { |
1521 | + |
1522 | + /** |
1523 | + * Nick name displayed to other users. |
1524 | + */ |
1525 | + public string nick_name { get; construct set; } |
1526 | + |
1527 | + /** |
1528 | + * Real name, can be anything pretty much. |
1529 | + */ |
1530 | + public string real_name { get; construct set; } |
1531 | + |
1532 | + /** |
1533 | + * ... |
1534 | + */ |
1535 | + public string user_name { get; construct set; } |
1536 | + |
1537 | + /** |
1538 | + * Message displayed when leaving a channel. |
1539 | + */ |
1540 | + public string part_message { get; construct set; } |
1541 | + |
1542 | + /** |
1543 | + * Message send in reply to a private message when marked away. |
1544 | + */ |
1545 | + public string away_message { get; construct set; } |
1546 | + |
1547 | + /** |
1548 | + * Message displayed when quitting a server. |
1549 | + */ |
1550 | + public string quit_message { get; construct set; } |
1551 | + |
1552 | + /** |
1553 | + * List of all identities. |
1554 | + */ |
1555 | + public static Utils.Array <Identity> all { get; private set; } |
1556 | + |
1557 | + /** |
1558 | + * Create a new identity, only the nick name is required. |
1559 | + */ |
1560 | + public Identity (string nick_name, |
1561 | + string? real_name = null, |
1562 | + string? user_name = null, |
1563 | + string? part_message = null, |
1564 | + string? away_message = null, |
1565 | + string? quit_message = null) |
1566 | + // TODO check for invalid characters and stuff |
1567 | + requires (/^[a-z_\-\[\]\\^{}|`][a-z0-9_\-\[\]\\^{}|`]*$/i.match (nick_name)) { |
1568 | + |
1569 | + this.nick_name = nick_name; |
1570 | + this.real_name = real_name ?? nick_name; |
1571 | + this.part_message = part_message ?? _("Bye."); |
1572 | + this.quit_message = quit_message ?? _("Quit server."); |
1573 | + this.away_message = away_message ?? _("%s is away.").printf (nick_name); |
1574 | + |
1575 | + this.all.add (this); |
1576 | + this.notify.connect (() => Settings.identities.changed ()); |
1577 | + } |
1578 | + |
1579 | + ~Identity () { |
1580 | + this.all.remove (this); |
1581 | + } |
1582 | + |
1583 | + public static void init () { |
1584 | + if (all != null) |
1585 | + return; |
1586 | + |
1587 | + all = new Utils.Array <Identity> (); |
1588 | + |
1589 | + foreach (var identity in settings.get_strv ("identities")) { |
1590 | + var values = identity.split (":"); |
1591 | + |
1592 | + if (values.length != 3) { |
1593 | + warning ("Invalid identity settings"); |
1594 | + continue; |
1595 | + } |
1596 | + |
1597 | + new Settings.Identity (values[0], values[1], values[2]); |
1598 | + } |
1599 | + |
1600 | + all.changed.connect (() => { |
1601 | + string[] ids = {}; |
1602 | + |
1603 | + foreach (var id in all) |
1604 | + ids += string.join (":", id.nick_name, id.real_name, id.part_message); |
1605 | + |
1606 | + settings.set_strv ("identities", ids); |
1607 | + }); |
1608 | + } |
1609 | + |
1610 | + /** |
1611 | + * Creates the default identity from your current login. |
1612 | + * |
1613 | + * @returns Default identity. |
1614 | + */ |
1615 | + public static Identity get_default () { |
1616 | + // TODO |
1617 | + return new Identity ("default"); |
1618 | + } |
1619 | +} |
1620 | |
1621 | === added file 'src/Services/Network.vala' |
1622 | --- src/Services/Network.vala 1970-01-01 00:00:00 +0000 |
1623 | +++ src/Services/Network.vala 2013-06-28 19:09:26 +0000 |
1624 | @@ -0,0 +1,103 @@ |
1625 | +/*** |
1626 | + Copyright (C) 2013 Cable Developers |
1627 | + |
1628 | + This program or library is free software; you can redistribute it |
1629 | + and/or modify it under the terms of the GNU Lesser General Public |
1630 | + License as published by the Free Software Foundation; either |
1631 | + version 3 of the License, or (at your option) any later version. |
1632 | + |
1633 | + This library is distributed in the hope that it will be useful, |
1634 | + but WITHOUT ANY WARRANTY; without even the implied warranty of |
1635 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
1636 | + Lesser General Public License for more details. |
1637 | + |
1638 | + You should have received a copy of the GNU Lesser General |
1639 | + Public License along with this library; if not, write to the |
1640 | + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
1641 | + Boston, MA 02110-1301 USA. |
1642 | +***/ |
1643 | + |
1644 | +/** |
1645 | + * This class represents a network. All used networks must be contained in Settings.networks, |
1646 | + * changes to this class will emit the Settings.networks.changed () signal. |
1647 | + */ |
1648 | + |
1649 | +public class Cable.Settings.Network : GLib.Object { |
1650 | + |
1651 | + /** |
1652 | + * The address of the network, i.e., "irc.freenode.net" |
1653 | + */ |
1654 | + public string address { get; construct set; } |
1655 | + |
1656 | + /** |
1657 | + * A name to display to the user when selecting a network for instance. |
1658 | + */ |
1659 | + public string name { get; construct set; } |
1660 | + |
1661 | + /** |
1662 | + * Password, defaults to "" if it isn't required. |
1663 | + */ |
1664 | + public string password { get; construct set; } |
1665 | + |
1666 | + /** |
1667 | + * Array of all networks. Checked for duplicates. |
1668 | + */ |
1669 | + public static Utils.Array <Network> all { get; private set; } |
1670 | + |
1671 | + |
1672 | + public Network (string address, string? name = null, string? password = null) |
1673 | + requires (address.split (".").length == 3) { |
1674 | + |
1675 | + this.address = address; |
1676 | + this.name = name ?? address.split (".")[1]; |
1677 | + this.password = password ?? ""; |
1678 | + |
1679 | + this.all.add (this); |
1680 | + this.notify.connect (() => Settings.networks.changed ()); |
1681 | + } |
1682 | + |
1683 | + ~Network () { |
1684 | + this.all.remove (this); |
1685 | + } |
1686 | + |
1687 | + public static void init () { |
1688 | + if (all != null) |
1689 | + return; |
1690 | + |
1691 | + all = new Utils.Array <Network> (); |
1692 | + |
1693 | + foreach (var network in settings.get_strv ("networks")) { |
1694 | + var values = network.split (":"); |
1695 | + |
1696 | + if (values.length != 3) { |
1697 | + warning ("Invalid network settings"); |
1698 | + continue; |
1699 | + } |
1700 | + |
1701 | + new Settings.Network (values[0], values[1], values[2]); |
1702 | + } |
1703 | + |
1704 | + networks.changed.connect (() => { |
1705 | + string[] networks = {}; |
1706 | + |
1707 | + foreach (var network in all) |
1708 | + networks += string.join (":", network.address, network.name, network.password); |
1709 | + |
1710 | + settings.set_strv ("networks", networks); |
1711 | + }); |
1712 | + } |
1713 | + |
1714 | + /** |
1715 | + * |
1716 | + */ |
1717 | + public bool is_duplicate (string address, string? name = null) { |
1718 | + foreach (var network in all) { |
1719 | + if (network.address == address) |
1720 | + return false; |
1721 | + if (network.name == name) |
1722 | + return false; |
1723 | + } |
1724 | + |
1725 | + return true; |
1726 | + } |
1727 | +} |
1728 | |
1729 | === added file 'src/Services/Settings.vala' |
1730 | --- src/Services/Settings.vala 1970-01-01 00:00:00 +0000 |
1731 | +++ src/Services/Settings.vala 2013-06-28 19:09:26 +0000 |
1732 | @@ -0,0 +1,146 @@ |
1733 | +/*** |
1734 | + Copyright (C) 2013 Cable Developers |
1735 | + |
1736 | + This program or library is free software; you can redistribute it |
1737 | + and/or modify it under the terms of the GNU Lesser General Public |
1738 | + License as published by the Free Software Foundation; either |
1739 | + version 3 of the License, or (at your option) any later version. |
1740 | + |
1741 | + This library is distributed in the hope that it will be useful, |
1742 | + but WITHOUT ANY WARRANTY; without even the implied warranty of |
1743 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
1744 | + Lesser General Public License for more details. |
1745 | + |
1746 | + You should have received a copy of the GNU Lesser General |
1747 | + Public License along with this library; if not, write to the |
1748 | + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
1749 | + Boston, MA 02110-1301 USA. |
1750 | +***/ |
1751 | + |
1752 | +/** |
1753 | + * Pseudo static class for dealing with gsettings. |
1754 | + * |
1755 | + * How this works: |
1756 | + * |
1757 | + * All settings are stored as public and static members of this class. |
1758 | + * On startup they are read from gsettings. They can be modified in several |
1759 | + * ways (Through the user interface, through gsettings, by the program |
1760 | + * itself…). The settings will then emit a "changed" signal, so the change |
1761 | + * can be immediately propagated to the server, gsettings, the UI and so |
1762 | + * on. |
1763 | + */ |
1764 | +namespace Cable.Settings { |
1765 | + |
1766 | + public GLib.Settings settings; |
1767 | + |
1768 | + public Utils.Array <Network> networks; |
1769 | + public Utils.Array <Identity> identities; |
1770 | + |
1771 | + /** |
1772 | + * Load values from gsettings. |
1773 | + */ |
1774 | + public static void init () { |
1775 | + settings = new GLib.Settings ("org.pantheon.cable"); |
1776 | + |
1777 | + Network.init (); |
1778 | + networks = Network.all; |
1779 | + |
1780 | + Identity.init (); |
1781 | + identities = Identity.all; |
1782 | + } |
1783 | +} |
1784 | + |
1785 | + /* |
1786 | +class Cable.Settings : GLib.Object { |
1787 | + |
1788 | + public static Array <Services.Identity> identities; |
1789 | + public static Array <Services.Network> networks; |
1790 | + |
1791 | + static string[] _chans; |
1792 | + public static string[] channels { |
1793 | + get { return _chans = settings.get_strv ("channels"); } |
1794 | + set { settings.set_strv ("channels", _chans = value); } |
1795 | + } |
1796 | + |
1797 | + private static GLib.Settings settings; |
1798 | + |
1799 | + public static void init () { |
1800 | + settings = new GLib.Settings ("org.pantheon.cable"); |
1801 | + |
1802 | + identities = new Array <Services.Identity> (); |
1803 | + networks = new Array <Services.Network> (); |
1804 | + |
1805 | + foreach (var id in settings.get_strv ("identities")) { |
1806 | + var values = id.split (":"); |
1807 | + |
1808 | + if (values.length != 3) |
1809 | + warning ("Invalid identity settings"); |
1810 | + |
1811 | + identities.add ( |
1812 | + new Services.Identity (values[0], values[1], values[2]) |
1813 | + ); |
1814 | + } |
1815 | + |
1816 | + identities.changed.connect (() => { |
1817 | + string[] ids = {}; |
1818 | + |
1819 | + foreach (var id in identities) |
1820 | + ids += string.join (":", id.nick_name, id.real_name, id.part_message); |
1821 | + |
1822 | + settings.set_strv ("identities", ids); |
1823 | + }); |
1824 | + |
1825 | + foreach (var nw in settings.get_strv ("networks")) { |
1826 | + var values = nw.split (":"); |
1827 | + |
1828 | + if (values.length != 3) { |
1829 | + warning ("Invalid network settings"); |
1830 | + continue; |
1831 | + } |
1832 | + |
1833 | + networks.add ( |
1834 | + new Services.Network (values[0], values[1], values[2]) |
1835 | + ); |
1836 | + } |
1837 | + |
1838 | + networks.changed.connect (() => { |
1839 | + string[] nws = {}; |
1840 | + |
1841 | + foreach (var nw in networks) |
1842 | + nws += string.join (":", nw.address, nw.name, nw.password); |
1843 | + |
1844 | + settings.set_strv ("networks", nws); |
1845 | + }); |
1846 | + } |
1847 | + |
1848 | + private Settings () { |
1849 | + } |
1850 | +} |
1851 | + |
1852 | +public class Cable.Array <G> : Gee.ArrayList <G> { |
1853 | + |
1854 | + public signal void changed (); |
1855 | + |
1856 | + public override bool add (G item) { |
1857 | + var ret = base.add (item); |
1858 | + changed (); |
1859 | + return ret; |
1860 | + } |
1861 | + |
1862 | + public override bool remove (G item) { |
1863 | + var ret = base.remove (item); |
1864 | + changed (); |
1865 | + return ret; |
1866 | + } |
1867 | + |
1868 | + public override G remove_at (int index) { |
1869 | + var ret = base.remove_at (index); |
1870 | + changed (); |
1871 | + return ret; |
1872 | + } |
1873 | + |
1874 | + public override void @set (int index, G item) { |
1875 | + base.set (index, item); |
1876 | + changed (); |
1877 | + } |
1878 | +}*/ |
1879 | |
1880 | === removed file 'src/Settings.vala' |
1881 | --- src/Settings.vala 2013-05-29 00:24:15 +0000 |
1882 | +++ src/Settings.vala 1970-01-01 00:00:00 +0000 |
1883 | @@ -1,23 +0,0 @@ |
1884 | -namespace Cable { |
1885 | - |
1886 | - public class Settings : Granite.Services.Settings { |
1887 | - |
1888 | - public string[] servers { get; set; } |
1889 | - public string nick { get; set; } |
1890 | - public string[] channels { get; set; } |
1891 | - public string real_name { get; set; } |
1892 | - public string login_name { get; set; } |
1893 | - |
1894 | - static Settings? instance; |
1895 | - |
1896 | - Settings () { |
1897 | - base ("org.pantheon.cable"); |
1898 | - } |
1899 | - |
1900 | - public static Settings get_default () { |
1901 | - if (instance == null) |
1902 | - instance = new Settings (); |
1903 | - return instance; |
1904 | - } |
1905 | - } |
1906 | -} |
1907 | |
1908 | === added file 'src/Utils.vala' |
1909 | --- src/Utils.vala 1970-01-01 00:00:00 +0000 |
1910 | +++ src/Utils.vala 2013-06-28 19:09:26 +0000 |
1911 | @@ -0,0 +1,69 @@ |
1912 | +/*** |
1913 | + Copyright (C) 2013 Cable Developers |
1914 | + |
1915 | + This program or library is free software; you can redistribute it |
1916 | + and/or modify it under the terms of the GNU Lesser General Public |
1917 | + License as published by the Free Software Foundation; either |
1918 | + version 3 of the License, or (at your option) any later version. |
1919 | + |
1920 | + This library is distributed in the hope that it will be useful, |
1921 | + but WITHOUT ANY WARRANTY; without even the implied warranty of |
1922 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
1923 | + Lesser General Public License for more details. |
1924 | + |
1925 | + You should have received a copy of the GNU Lesser General |
1926 | + Public License along with this library; if not, write to the |
1927 | + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
1928 | + Boston, MA 02110-1301 USA. |
1929 | +***/ |
1930 | + |
1931 | +class Cable.Utils.Label : Gtk.Label { |
1932 | + |
1933 | + public Label (string text) { |
1934 | + label = text; |
1935 | + halign = Gtk.Align.START; |
1936 | + } |
1937 | + |
1938 | + public Label.right (string text) { |
1939 | + label = text; |
1940 | + halign = Gtk.Align.END; |
1941 | + valign = Gtk.Align.CENTER; |
1942 | + } |
1943 | +} |
1944 | + |
1945 | +public class Cable.Utils.Array <G> : Gee.ArrayList <G> { |
1946 | + |
1947 | + public signal void changed (); |
1948 | + |
1949 | + public override bool add (G item) { |
1950 | + var ret = base.add (item); |
1951 | + changed (); |
1952 | + return ret; |
1953 | + } |
1954 | + |
1955 | + public override bool remove (G item) { |
1956 | + var ret = base.remove (item); |
1957 | + changed (); |
1958 | + return ret; |
1959 | + } |
1960 | + |
1961 | + public override G remove_at (int index) { |
1962 | + var ret = base.remove_at (index); |
1963 | + changed (); |
1964 | + return ret; |
1965 | + } |
1966 | + |
1967 | + public override void @set (int index, G item) { |
1968 | + base.set (index, item); |
1969 | + changed (); |
1970 | + } |
1971 | +} |
1972 | + |
1973 | +// FIXME |
1974 | +namespace Cable.Utils { |
1975 | + public void filter (Gtk.Editable editable, string text, string[] needles) { |
1976 | + foreach (var needle in needles) |
1977 | + if (needle in text) |
1978 | + Signal.stop_emission_by_name (editable, "insert-text"); |
1979 | + } |
1980 | +} |
1981 | |
1982 | === modified file 'src/Widgets/Channel.vala' |
1983 | --- src/Widgets/Channel.vala 2013-05-29 18:15:05 +0000 |
1984 | +++ src/Widgets/Channel.vala 2013-06-28 19:09:26 +0000 |
1985 | @@ -1,58 +1,112 @@ |
1986 | -namespace Cable.Widgets { |
1987 | - |
1988 | - /** |
1989 | - * This class represents a channel and owns the Widgets.Room |
1990 | - * associated to its channel. |
1991 | - */ |
1992 | - public class Channel : Granite.Widgets.SourceList.Item { |
1993 | - |
1994 | - /** |
1995 | - * Get the room object. |
1996 | - */ |
1997 | - public Room room { get; private set; } |
1998 | - |
1999 | - public Server server { |
2000 | - get { return parent as Server; } |
2001 | - } |
2002 | - |
2003 | - doodleIRC.DoodleIRCServer backend_server; |
2004 | - |
2005 | - // context menu |
2006 | - Gtk.Menu menu; |
2007 | - Gtk.MenuItem leave_menu_item; |
2008 | - Gtk.MenuItem away_menu_item; |
2009 | - |
2010 | - public Channel (string channel, doodleIRC.DoodleIRCServer backend_server) { |
2011 | - this.name = channel; |
2012 | - this.backend_server = backend_server; |
2013 | - this.room = new Room (channel); |
2014 | - |
2015 | - this.menu = new Gtk.Menu (); |
2016 | - this.leave_menu_item = new Gtk.MenuItem.with_label (_("Leave Channel")); |
2017 | - this.away_menu_item = new Gtk.MenuItem.with_label (_("Mark Away")); |
2018 | - menu.append (leave_menu_item); |
2019 | - menu.append (new Gtk.SeparatorMenuItem ()); |
2020 | - menu.append (away_menu_item); |
2021 | - |
2022 | - leave_menu_item.activate.connect (() => { |
2023 | - server.leave_channel (name); |
2024 | - }); |
2025 | - away_menu_item.activate.connect (() => { |
2026 | - backend_server.toggle_away (_("Away")); |
2027 | - }); |
2028 | - } |
2029 | +/*** |
2030 | + Copyright (C) 2013 Cable Developers |
2031 | + |
2032 | + This program or library is free software; you can redistribute it |
2033 | + and/or modify it under the terms of the GNU Lesser General Public |
2034 | + License as published by the Free Software Foundation; either |
2035 | + version 3 of the License, or (at your option) any later version. |
2036 | + |
2037 | + This library is distributed in the hope that it will be useful, |
2038 | + but WITHOUT ANY WARRANTY; without even the implied warranty of |
2039 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
2040 | + Lesser General Public License for more details. |
2041 | + |
2042 | + You should have received a copy of the GNU Lesser General |
2043 | + Public License along with this library; if not, write to the |
2044 | + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
2045 | + Boston, MA 02110-1301 USA. |
2046 | +***/ |
2047 | + |
2048 | +/** |
2049 | + * This class represents a channel and owns the Widgets.Room |
2050 | + * associated to its channel. |
2051 | + */ |
2052 | +public class Cable.Widgets.Channel : Granite.Widgets.SourceList.Item { |
2053 | + |
2054 | + /** |
2055 | + * Get the room object. |
2056 | + */ |
2057 | + public Room room { get; private set; } |
2058 | + |
2059 | + /** |
2060 | + * The server this channel belongs to. |
2061 | + */ |
2062 | + public Server server { |
2063 | + get { return parent as Server; } |
2064 | + } |
2065 | + |
2066 | + // context menu |
2067 | + Gtk.Menu menu; |
2068 | + Gtk.MenuItem leave_menu_item; |
2069 | + Gtk.MenuItem away_menu_item; |
2070 | + |
2071 | + public Channel (string channel_name) { |
2072 | + this.name = channel_name; |
2073 | + this.room = new Room (channel_name); |
2074 | + |
2075 | + this.menu = new Gtk.Menu (); |
2076 | + this.leave_menu_item = new Gtk.MenuItem.with_label (_("Leave Channel")); |
2077 | + menu.append (leave_menu_item); |
2078 | + menu.show_all (); |
2079 | |
2080 | - public void list_names (string[] names) { |
2081 | - foreach (var name in names) { |
2082 | - room.add_user (name, 0); |
2083 | - debug ("Listing name: %s", name); |
2084 | + leave_menu_item.activate.connect (() => { |
2085 | + server.leave_channel (name); |
2086 | + }); |
2087 | + } |
2088 | + |
2089 | + /** |
2090 | + * Add names to the source list. |
2091 | + * |
2092 | + * @prefix names Array of names to add. |
2093 | + * @prefix prefixes Array of corresponding prefixes. |
2094 | + */ |
2095 | + public void list_names (string[] names, string[] prefixes) { |
2096 | + UserType user_type = UserType.REGULAR; |
2097 | + |
2098 | + for (int i = 0; i < names.length; i++) { |
2099 | + switch (prefixes[i]) { |
2100 | + case "@": |
2101 | + user_type = UserType.OPERATOR; |
2102 | + break; |
2103 | + case "+": |
2104 | + user_type = UserType.VOICED; |
2105 | + break; |
2106 | + default: |
2107 | + user_type = UserType.REGULAR; |
2108 | + break; |
2109 | } |
2110 | - } |
2111 | - |
2112 | - public override Gtk.Menu? get_context_menu () { |
2113 | - menu.show_all (); |
2114 | - return menu; |
2115 | - } |
2116 | - } |
2117 | - |
2118 | + |
2119 | + room.add_user (names[i], user_type, true); |
2120 | + } |
2121 | + } |
2122 | + |
2123 | + /** |
2124 | + * Tell the room widget that a new user has been added. |
2125 | + * |
2126 | + * @param name The user's nickname (including @ or + prefix). |
2127 | + * @param silent If true, don't display a join message. |
2128 | + */ |
2129 | + public void add_user (string name, bool silent = false) { |
2130 | + if (name.has_prefix ("@")) |
2131 | + room.add_user (name.replace ("@", ""), UserType.OPERATOR, silent); |
2132 | + else if (name.has_prefix ("+")) |
2133 | + room.add_user (name.replace ("+", ""), UserType.VOICED, silent); |
2134 | + else |
2135 | + room.add_user (name, UserType.REGULAR, silent); |
2136 | + } |
2137 | + |
2138 | + /** |
2139 | + * Remove a user from the sidebar and display a leave message. |
2140 | + * |
2141 | + * @param name The users nickname without prefix. |
2142 | + */ |
2143 | + public void remove_user (string name) { |
2144 | + room.remove_user (name); |
2145 | + } |
2146 | + |
2147 | + public override Gtk.Menu? get_context_menu () { |
2148 | + if (menu != null && menu.get_attach_widget () != null) |
2149 | + menu.detach (); |
2150 | + return menu; |
2151 | + } |
2152 | } |
2153 | |
2154 | === modified file 'src/Widgets/Room.vala' |
2155 | --- src/Widgets/Room.vala 2013-06-10 18:12:26 +0000 |
2156 | +++ src/Widgets/Room.vala 2013-06-28 19:09:26 +0000 |
2157 | @@ -1,32 +1,213 @@ |
2158 | -namespace Cable.Widgets { |
2159 | - |
2160 | - public enum UserType { |
2161 | - OPERATOR, |
2162 | - VOICED, |
2163 | - REGULAR |
2164 | - } |
2165 | - |
2166 | - public enum MessageType { |
2167 | - NORMAL, |
2168 | - ENTER, |
2169 | - LEAVE |
2170 | - } |
2171 | - |
2172 | - /** |
2173 | - * This class represents a chat room, i.e, the topic, the message display, |
2174 | - * a list of users and is associated to a channel. |
2175 | - * This class is always accessed through its related channel. |
2176 | - */ |
2177 | - public class Room : Gtk.Box { |
2178 | - |
2179 | - Granite.Widgets.SourceList.ExpandableItem operators; |
2180 | - Granite.Widgets.SourceList.ExpandableItem voiced; |
2181 | - Granite.Widgets.SourceList.ExpandableItem regular; |
2182 | - |
2183 | - Granite.Widgets.SourceList users; |
2184 | - Gtk.TreeView chat; |
2185 | - Gtk.ScrolledWindow left_scrolled; |
2186 | +/*** |
2187 | + Copyright (C) 2013 Cable Developers |
2188 | + |
2189 | + This program or library is free software; you can redistribute it |
2190 | + and/or modify it under the terms of the GNU Lesser General Public |
2191 | + License as published by the Free Software Foundation; either |
2192 | + version 3 of the License, or (at your option) any later version. |
2193 | + |
2194 | + This library is distributed in the hope that it will be useful, |
2195 | + but WITHOUT ANY WARRANTY; without even the implied warranty of |
2196 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
2197 | + Lesser General Public License for more details. |
2198 | + |
2199 | + You should have received a copy of the GNU Lesser General |
2200 | + Public License along with this library; if not, write to the |
2201 | + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
2202 | + Boston, MA 02110-1301 USA. |
2203 | +***/ |
2204 | + |
2205 | +public enum Cable.Widgets.UserType { |
2206 | + OPERATOR, |
2207 | + VOICED, |
2208 | + REGULAR |
2209 | +} |
2210 | + |
2211 | +public enum Cable.Widgets.MessageType { |
2212 | + NORMAL, |
2213 | + ENTER, |
2214 | + LEAVE, |
2215 | + NICK, |
2216 | + AWAY |
2217 | +} |
2218 | + |
2219 | +/** |
2220 | + * This class represents a chat room, i.e, the topic, the message display, |
2221 | + * a list of users and is associated to a channel. |
2222 | + * This class is always accessed through its related channel. |
2223 | + */ |
2224 | +public class Cable.Widgets.Room : Gtk.Box { |
2225 | + |
2226 | + Granite.Widgets.SourceList.ExpandableItem operators; |
2227 | + Granite.Widgets.SourceList.ExpandableItem voiced; |
2228 | + Granite.Widgets.SourceList.ExpandableItem regular; |
2229 | + |
2230 | + Granite.Widgets.SourceList users; |
2231 | + Gtk.TreeView chat; |
2232 | + Gtk.ScrolledWindow left_scrolled; |
2233 | + |
2234 | + |
2235 | + Gtk.Menu menu; |
2236 | + Gtk.MenuItem kick_item; |
2237 | + Gtk.MenuItem ban_item; |
2238 | + Gtk.MenuItem ignore_item; |
2239 | + |
2240 | + public Gtk.InfoBar topic; |
2241 | + public Gtk.Label topic_name; |
2242 | + |
2243 | + public signal void send_message (string message); |
2244 | + |
2245 | + public signal bool kick_user (string nick_name); |
2246 | + public signal bool ban_user (string nick_name); |
2247 | + public signal void ignore (string nick_name, bool ignore = true); |
2248 | + |
2249 | + public Room (string channel) { |
2250 | + |
2251 | + //var web_view = new WebKit.WebView (); |
2252 | + |
2253 | + this.orientation = Gtk.Orientation.VERTICAL; |
2254 | + var paned = new Granite.Widgets.ThinPaned (); |
2255 | + var box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); |
2256 | + users = new Granite.Widgets.SourceList (); |
2257 | + var entry = new Gtk.Entry (); |
2258 | + chat = new Gtk.TreeView.with_model (new Gtk.ListStore (2, typeof(string), typeof(string))); |
2259 | + var topic = new Gtk.InfoBar (); |
2260 | + topic_name = new Gtk.Label (_("Loading Topic…")); |
2261 | + topic_name.wrap = true; |
2262 | + var bottom = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0); |
2263 | + left_scrolled = new Gtk.ScrolledWindow (null, null); |
2264 | + //var user = new Gtk.Button.with_label (Global.get_default ().user_nick); |
2265 | + |
2266 | + var left = new Gtk.CellRendererText (); |
2267 | + left.xalign = 1.0f; |
2268 | + left.width = 90; |
2269 | + left.font_desc = Pango.FontDescription.from_string ( |
2270 | + new GLib.Settings ("org.gnome.desktop.interface").get_string ("document-font-name")); |
2271 | + |
2272 | + var right = new Gtk.CellRendererText (); |
2273 | + right.wrap_mode = Pango.WrapMode.WORD_CHAR; |
2274 | + right.wrap_width = -1; |
2275 | + right.font_desc = left.font_desc; |
2276 | + |
2277 | + chat.enable_grid_lines = Gtk.TreeViewGridLines.VERTICAL; |
2278 | + chat.headers_visible = false; |
2279 | + chat.insert_column_with_attributes (-1, null, left, "markup", 0); |
2280 | + chat.insert_column_with_attributes (-1, null, right, "markup", 1); |
2281 | + chat.button_press_event.connect (() => true ); |
2282 | + |
2283 | + var css = new Gtk.CssProvider (); |
2284 | + try { |
2285 | + css.load_from_data ("* { |
2286 | + -GtkTreeView-grid-line-pattern: '1'; |
2287 | + }", -1); |
2288 | + } catch (Error e) { warning (e.message); } |
2289 | + |
2290 | + chat.get_style_context ().add_provider (css, 40000); |
2291 | + topic_name.halign = Gtk.Align.FILL; |
2292 | + topic_name.valign = Gtk.Align.FILL; |
2293 | + |
2294 | + var content = topic.get_content_area () as Gtk.Container; |
2295 | + content.add (topic_name); |
2296 | + |
2297 | + operators = new Granite.Widgets.SourceList.ExpandableItem (_("Operators")); |
2298 | + regular = new Granite.Widgets.SourceList.ExpandableItem ("Regular"); |
2299 | + voiced = new Granite.Widgets.SourceList.ExpandableItem ("Voiced"); |
2300 | + users.root.add (operators); |
2301 | + users.root.add (voiced); |
2302 | + users.root.add (regular); |
2303 | + users.set_sort_func ((a,b) => { |
2304 | + return a.name.collate (b.name); |
2305 | + }); |
2306 | + |
2307 | + operators.expanded = true; |
2308 | + regular.expanded = true; |
2309 | + voiced.expanded = true; |
2310 | + |
2311 | + css = new Gtk.CssProvider (); |
2312 | + try { |
2313 | + css.load_from_data ("*{ |
2314 | + background-color: #fff; |
2315 | + }", -1); |
2316 | + } catch (Error e) { warning (e.message); } |
2317 | + users.get_style_context ().add_provider (css, 40000); |
2318 | + |
2319 | + users.hscrollbar_policy = Gtk.PolicyType.NEVER; |
2320 | + users.width_request = 150; |
2321 | + |
2322 | + |
2323 | + paned.pack1 (box, true, false); |
2324 | + paned.pack2 (users, false, false); |
2325 | + |
2326 | + /*user.width_request = 99; |
2327 | + user.margin_right = 5; |
2328 | + user.xalign = 1.0f;*/ |
2329 | + |
2330 | + |
2331 | + css = new Gtk.CssProvider (); |
2332 | + try { |
2333 | + css.load_from_data ("*{ |
2334 | + background-image: none; |
2335 | + background-color: transparent; |
2336 | + -unico-inner-stroke-width: 0px; |
2337 | + -unico-outer-stroke-width: 0px; |
2338 | + border-left: 1px solid #666; |
2339 | + border-width: 0px 0px 0px 1px; |
2340 | + } |
2341 | + *:active, *:prelight { |
2342 | + border-color: #666; |
2343 | + }", -1); |
2344 | + } catch (Error e) { warning (e.message); } |
2345 | + entry.get_style_context ().add_provider (css, 40000); |
2346 | + |
2347 | + //bottom.pack_start (user, false); |
2348 | + bottom.pack_start (entry); |
2349 | + |
2350 | + left_scrolled.add (chat); |
2351 | + |
2352 | + box.pack_start (topic, false); |
2353 | + box.pack_start (left_scrolled); |
2354 | + //box.pack_start (bottom, false); |
2355 | + |
2356 | + this.pack_start (paned); |
2357 | + |
2358 | + /*user.clicked.connect (() => { |
2359 | + |
2360 | + var settings_dialog = new Widgets.SettingsDialog (); |
2361 | + |
2362 | + settings_dialog.show_all (); |
2363 | + //settings_dialog.run (); |
2364 | + |
2365 | + });*/ |
2366 | + |
2367 | + entry.activate.connect (() => { |
2368 | + send_message (entry.text); |
2369 | + entry.text = ""; |
2370 | + }); |
2371 | + |
2372 | + bottom.draw.connect ((cr) => { |
2373 | + var grad = new Cairo.Pattern.linear (0, 0, 0, bottom.get_allocated_height () - 4); |
2374 | + grad.add_color_stop_rgb (0.0, 0.9, 0.9, 0.9); |
2375 | + grad.add_color_stop_rgb (1.0, 1.0, 1.0, 1.0); |
2376 | + cr.rectangle (0, 0, bottom.get_allocated_width (), bottom.get_allocated_height ()); |
2377 | + cr.set_source (grad); |
2378 | + cr.fill (); |
2379 | + |
2380 | + cr.move_to (0, 0); |
2381 | + cr.line_to (this.get_allocated_width (), 0); |
2382 | + cr.close_path (); |
2383 | + cr.set_source_rgba (0.1, 0.1, 0.1, 1.0); |
2384 | + cr.set_line_width (1); |
2385 | + cr.stroke (); |
2386 | + |
2387 | + return false; |
2388 | + }); |
2389 | + } |
2390 | + |
2391 | + public void rename_user (string old_name, string new_name, UserType type, bool silent = false) { |
2392 | + remove_user (old_name, true); |
2393 | + add_user (new_name, type, true); |
2394 | |
2395 | +<<<<<<< TREE |
2396 | public Gtk.InfoBar topic; |
2397 | public Gtk.Label topic_name; |
2398 | |
2399 | @@ -175,49 +356,81 @@ |
2400 | else |
2401 | regular.add (new Granite.Widgets.SourceList.Item (name)); |
2402 | |
2403 | +======= |
2404 | + if (!silent) |
2405 | + message (new_name, "", MessageType.NICK); |
2406 | + } |
2407 | + |
2408 | + public void add_user (string name, UserType type, bool silent = false) { |
2409 | + var user = new Granite.Widgets.SourceList.Item (name); |
2410 | + user.selectable = false; |
2411 | + |
2412 | + if (type == UserType.OPERATOR) |
2413 | + operators.add (user); |
2414 | + else if (type == UserType.VOICED) |
2415 | + voiced.add (user); |
2416 | + else |
2417 | + regular.add (user); |
2418 | + |
2419 | + if (!silent) |
2420 | +>>>>>>> MERGE-SOURCE |
2421 | message (name, "", MessageType.ENTER); |
2422 | - } |
2423 | - |
2424 | - public void remove_user (string name) { |
2425 | - Granite.Widgets.SourceList.ExpandableItem[] lists = {voiced, operators, regular}; |
2426 | - foreach (var list in lists) { |
2427 | - foreach (var child in list.children) { |
2428 | - if (child.name == name) { |
2429 | - list.remove (child); |
2430 | - |
2431 | + |
2432 | + regular.name = _("Regular") + " (" + regular.n_children.to_string () + ")"; |
2433 | + operators.name = _("Operators") + " (" + operators.n_children.to_string () + ")"; |
2434 | + voiced.name = _("Voiced") + " (" + voiced.n_children.to_string () + ")"; |
2435 | + } |
2436 | + |
2437 | + public void remove_user (string name, bool silent = false) { |
2438 | + Granite.Widgets.SourceList.ExpandableItem[] lists = {voiced, operators, regular}; |
2439 | + foreach (var list in lists) { |
2440 | + foreach (var child in list.children) { |
2441 | + if (child.name == name) { |
2442 | + list.remove (child); |
2443 | + |
2444 | + if (!silent) |
2445 | message (child.name, "", MessageType.LEAVE); |
2446 | - |
2447 | - return; |
2448 | - } |
2449 | - |
2450 | + |
2451 | + regular.name = _("Regular") + " (" + regular.n_children.to_string () + ")"; |
2452 | + operators.name = _("Operators") + " (" + operators.n_children.to_string () + ")"; |
2453 | + voiced.name = _("Voiced") + " (" + voiced.n_children.to_string () + ")"; |
2454 | + |
2455 | return; |
2456 | } |
2457 | } |
2458 | } |
2459 | - |
2460 | - public void message (owned string from, string message, MessageType type=MessageType.NORMAL) { |
2461 | - bool do_scroll = left_scrolled.vadjustment.value + 10 > left_scrolled.vadjustment.upper; |
2462 | - |
2463 | - Gtk.TreeIter iter; |
2464 | - (chat.model as Gtk.ListStore).append (out iter); |
2465 | - |
2466 | - if (type == MessageType.NORMAL) { |
2467 | - |
2468 | - if (from == Global.get_default ().user_nick) |
2469 | - from = "<span color='#999'>"+from+"</span>"; |
2470 | - else if (message.index_of (Global.get_default ().user_nick) != -1) |
2471 | - from = "<span color='#a00'>"+from+"</span>"; |
2472 | - |
2473 | - (chat.model as Gtk.ListStore).set (iter, 0, from, 1, message); |
2474 | - } else |
2475 | - (chat.model as Gtk.ListStore).set (iter, 0, "", |
2476 | - 1, "<span color='#999'>%s has %s the room.</span>".printf (from, type == MessageType.ENTER ? "entered" : "left")); |
2477 | - |
2478 | - Timeout.add (10, () => { |
2479 | + |
2480 | + } |
2481 | + |
2482 | + public void message (owned string from, string message, MessageType type = MessageType.NORMAL) { |
2483 | + bool do_scroll = left_scrolled.vadjustment.value + 10 > left_scrolled.vadjustment.upper; |
2484 | + |
2485 | + Gtk.TreeIter iter; |
2486 | + var model = chat.model as Gtk.ListStore; |
2487 | + model.append (out iter); |
2488 | + |
2489 | + switch (type) { |
2490 | + case MessageType.NORMAL: |
2491 | + model.set (iter, 0, from, 1, message); |
2492 | + break; |
2493 | + case MessageType.ENTER: |
2494 | + model.set (iter, 0, "", 1, @"<span color='#9a9'>$from joined</span>"); |
2495 | + break; |
2496 | + case MessageType.LEAVE: |
2497 | + model.set (iter, 0, "", 1, @"<span color='#a99'>$from left</span>"); |
2498 | + break; |
2499 | + case MessageType.AWAY: |
2500 | + model.set (iter, 0, "", 1, @"<span color='#999'>$from is away</span>"); |
2501 | + break; |
2502 | + case MessageType.NICK: |
2503 | + model.set (iter, 0, "", 1, @"<span color='#999'>$from</span>"); |
2504 | + break; |
2505 | + } |
2506 | + |
2507 | + Timeout.add (1, () => { |
2508 | if (do_scroll) |
2509 | left_scrolled.vadjustment.value = left_scrolled.vadjustment.upper; |
2510 | return false; |
2511 | - }); |
2512 | - } |
2513 | + }); |
2514 | } |
2515 | } |
2516 | |
2517 | === modified file 'src/Widgets/Server.vala' |
2518 | --- src/Widgets/Server.vala 2013-06-06 21:07:29 +0000 |
2519 | +++ src/Widgets/Server.vala 2013-06-28 19:09:26 +0000 |
2520 | @@ -1,233 +1,384 @@ |
2521 | -namespace Cable.Widgets { |
2522 | - |
2523 | - public class Server : Granite.Widgets.SourceList.ExpandableItem { |
2524 | - |
2525 | - //some default servers |
2526 | - public static const string [] DEFAULT_SERVERS = { |
2527 | - "Freenode", "irc.freenode.net", |
2528 | - "GimpNET", "irc.gimp.org" |
2529 | - }; |
2530 | - |
2531 | - /** |
2532 | - * List of all channels of this Server. |
2533 | - */ |
2534 | - GLib.List <Channel> _channels = null; |
2535 | - public GLib.List <Channel> channels { |
2536 | - get { |
2537 | - _channels = new GLib.List <Channel> (); |
2538 | - foreach (var child in children) |
2539 | - _channels.append (child as Channel); |
2540 | - return _channels; |
2541 | - } |
2542 | - } |
2543 | - |
2544 | - doodleIRC.DoodleIRCServer backend_server; |
2545 | - |
2546 | - public string uri; |
2547 | - |
2548 | - |
2549 | - public signal void left_channel (Channel channel); |
2550 | - public signal void joined_channel (Channel channel); |
2551 | - |
2552 | - /** |
2553 | - * Create and join server. |
2554 | - */ |
2555 | - public Server (string _name, string _uri) { |
2556 | - var settings = Settings.get_default (); |
2557 | - name = _name; |
2558 | - uri = _uri; |
2559 | - |
2560 | - doodleIRC.User user = doodleIRC.User () { |
2561 | - realname = settings.real_name, |
2562 | - hostname = settings.nick, |
2563 | - username = settings.nick, |
2564 | - servername = uri |
2565 | - }; |
2566 | - |
2567 | - backend_server = new doodleIRC.DoodleIRCServer ("irc.freenode.net", user, settings.nick); |
2568 | - Global.get_default ().user_nick = settings.nick; //TODO use fallback nicks |
2569 | - |
2570 | - try { |
2571 | - backend_server.connect (); |
2572 | - } catch (Error e) { |
2573 | - //Needs Fixing |
2574 | - Gtk.main_quit (); |
2575 | - } |
2576 | - |
2577 | - backend_server.on_message.connect ((sender, chan, msg) => { |
2578 | - channels.foreach ((channel) => { |
2579 | - if (channel.name == chan) { |
2580 | - channel.room.message (sender, msg); |
2581 | - return; |
2582 | - } |
2583 | - }); |
2584 | - |
2585 | - critical ("Channel '%s' has not been opened", chan); |
2586 | - }); |
2587 | - |
2588 | - backend_server.on_names_listed.connect ((chan, names) => { |
2589 | - channels.foreach ((channel) => { |
2590 | - if (channel.name == chan) |
2591 | - channel.list_names (names); |
2592 | - }); |
2593 | - }); |
2594 | - } |
2595 | - |
2596 | - /** |
2597 | - * Retrieve a channel by its name |
2598 | - */ |
2599 | - public Channel? get_channel_by_name (string channel_name) { |
2600 | +/*** |
2601 | + Copyright (C) 2013 Cable Developers |
2602 | + |
2603 | + This program or library is free software; you can redistribute it |
2604 | + and/or modify it under the terms of the GNU Lesser General Public |
2605 | + License as published by the Free Software Foundation; either |
2606 | + version 3 of the License, or (at your option) any later version. |
2607 | + |
2608 | + This library is distributed in the hope that it will be useful, |
2609 | + but WITHOUT ANY WARRANTY; without even the implied warranty of |
2610 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
2611 | + Lesser General Public License for more details. |
2612 | + |
2613 | + You should have received a copy of the GNU Lesser General |
2614 | + Public License along with this library; if not, write to the |
2615 | + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
2616 | + Boston, MA 02110-1301 USA. |
2617 | +***/ |
2618 | + |
2619 | +public class Cable.Widgets.Server : Granite.Widgets.SourceList.ExpandableItem { |
2620 | + |
2621 | + /** |
2622 | + * List of all channels of this Server. |
2623 | + */ |
2624 | + Gee.ArrayList <Channel> _channels = null; |
2625 | + public Gee.ArrayList <Channel> channels { |
2626 | + get { |
2627 | + _channels = new Gee.ArrayList <Channel> (); |
2628 | + foreach (var child in children) |
2629 | + _channels.add (child as Channel); |
2630 | + return _channels; |
2631 | + } |
2632 | + } |
2633 | + |
2634 | + /** |
2635 | + * Information about the network we are connected to. |
2636 | + */ |
2637 | + public Settings.Network network { get; private set; } |
2638 | + |
2639 | + /** |
2640 | + * Information about the identity we are using for this connection. |
2641 | + */ |
2642 | + public Settings.Identity identity { get; private set; } |
2643 | + |
2644 | + Services.Client client = null; |
2645 | + string server_id; |
2646 | + bool away; |
2647 | + bool connected = false; |
2648 | + string to_join; |
2649 | + // menu |
2650 | + Gtk.Menu menu; |
2651 | + Gtk.MenuItem away_menu_item; |
2652 | + Gtk.MenuItem part_menu_item; |
2653 | + |
2654 | + /** |
2655 | + * Emitted when the server emits a PART message for us. |
2656 | + * |
2657 | + * @param channel Channel that has been parted. |
2658 | + */ |
2659 | + public signal void left_channel (Channel channel); |
2660 | + |
2661 | + /** |
2662 | + * Emitted when a server confirms that we have joined successfully. |
2663 | + * |
2664 | + * @param channel Channel that has been joined. |
2665 | + */ |
2666 | + public signal void joined_channel (Channel channel); |
2667 | + |
2668 | + /** |
2669 | + * Create and connect to a server. |
2670 | + */ |
2671 | + public Server (Settings.Network network, Settings.Identity identity) { |
2672 | + |
2673 | + this.network = network; |
2674 | + this.identity = identity; |
2675 | + this.name = network.name; |
2676 | + this.server_id = string.join (":", network.address, identity.nick_name); |
2677 | + |
2678 | + try { |
2679 | + client = GLib.Bus.get_proxy_sync ( |
2680 | + GLib.BusType.SESSION, "de.ikkoku.sushi", "/de/ikkoku/sushi" |
2681 | + ); |
2682 | + } catch (IOError e) { |
2683 | + print (e.message); |
2684 | + return; |
2685 | + } |
2686 | + |
2687 | + debug ("Successfully connected to Sushi dbus session.\n"); |
2688 | + |
2689 | + setup_callbacks (); |
2690 | + setup_contextmenu (); |
2691 | + setup_settings_callbacks (); |
2692 | + |
2693 | + foreach (var server in client.servers ()) { |
2694 | + if (client.server_get (server, "server", "nick") == identity.nick_name && |
2695 | + client.server_get (server, "server", "address") == network.address) { |
2696 | + |
2697 | + debug (@"Already connected to $server."); |
2698 | + connected = true; |
2699 | + this.server_id = server; |
2700 | + |
2701 | + return; |
2702 | + } |
2703 | + } |
2704 | + |
2705 | + try { |
2706 | + debug (@"Creating new server $server_id."); |
2707 | + client.server_set (server_id, "server", "address", network.address); |
2708 | + client.server_set (server_id, "server", "nickserv", network.password); |
2709 | + client.server_set (server_id, "server", "nick", identity.nick_name); |
2710 | + client.server_set (server_id, "server", "name", identity.real_name); |
2711 | + client.server_set (server_id, "server", "autoconnect", "true"); |
2712 | + client.connect (server_id); |
2713 | + } catch (GLib.IOError e) { |
2714 | + print (e.message); |
2715 | + return; |
2716 | + } |
2717 | + |
2718 | + debug ("Successfully set up server.\n"); |
2719 | + } |
2720 | + |
2721 | + public override Gtk.Menu? get_context_menu () { |
2722 | + if (menu != null && menu.get_attach_widget () != null) |
2723 | + menu.detach (); |
2724 | + return menu; |
2725 | + } |
2726 | + |
2727 | + /** |
2728 | + * Create the context menu shown when right clicking a server entry. |
2729 | + */ |
2730 | + private void setup_contextmenu () { |
2731 | + this.menu = new Gtk.Menu (); |
2732 | + |
2733 | + this.away_menu_item = new Gtk.MenuItem.with_label (_("Mark Away")); |
2734 | + this.part_menu_item = new Gtk.MenuItem.with_label (_("Leave all channels")); |
2735 | + |
2736 | + menu.append (away_menu_item); |
2737 | + menu.append (part_menu_item); |
2738 | + |
2739 | + away_menu_item.activate.connect (() => { |
2740 | + if (!away) { |
2741 | + client.away (server_id, _("%s is away.").printf (identity.real_name)); |
2742 | + away_menu_item.label = _("Mark Present"); |
2743 | + } else { |
2744 | + client.away (server_id, _("")); |
2745 | + away_menu_item.label = _("Mark Away"); |
2746 | + } |
2747 | + }); |
2748 | + |
2749 | + part_menu_item.activate.connect (() => { |
2750 | foreach (var channel in channels) |
2751 | - if (channel.name == channel_name) |
2752 | - return channel; |
2753 | - |
2754 | - return (Channel) null; |
2755 | - } |
2756 | - |
2757 | - /** |
2758 | - * Join a channel and return the Widget.Channel object |
2759 | - */ |
2760 | - public Channel? join_channel (string channel_name) { |
2761 | - var channel = new Channel (channel_name, backend_server); |
2762 | - |
2763 | - channel.room.send_message.connect ((msg) => { |
2764 | - backend_server.write (channel_name, msg); |
2765 | - }); |
2766 | - |
2767 | - backend_server.join_chan (channel_name); |
2768 | - backend_server.get_topic (channel_name, (channel_name, topic) => { |
2769 | - print ("Topic :%s\n".printf (topic)); |
2770 | - // Set topic |
2771 | - channel.room.topic_name.label = topic; |
2772 | - |
2773 | - // Now check for links TODO async this |
2774 | - /*string parsed_topic = topic; |
2775 | - bool done = false; |
2776 | - int i = 0, start = 0, end = 0, p = 0, counter = 0; |
2777 | - Array<string> links = new Array<string> (); |
2778 | - start = topic.index_of ( "http", i); |
2779 | - while(!done) { |
2780 | - start = topic.index_of ( "http", start); |
2781 | - if ( start == -1) { |
2782 | - // No link |
2783 | - done = true; |
2784 | - } else { |
2785 | - // Contains links |
2786 | - end = topic.index_of ( " ", start); |
2787 | - if ( end == -1) { |
2788 | - // End of topic |
2789 | - end = topic.length; |
2790 | - done = true; |
2791 | - } |
2792 | - print ("URL :%s\n".printf (topic.slice ((long) start, (long) end))); |
2793 | - links.insert_val ( (uint) p, topic.slice ((long) start, (long) end)); |
2794 | - print ("URL in Array :%s\n".printf (links.index(p))); |
2795 | - p++; |
2796 | - start = end; |
2797 | - } |
2798 | + leave_channel (channel.name); |
2799 | + }); |
2800 | + |
2801 | + menu.show_all (); |
2802 | + } |
2803 | + |
2804 | + /** |
2805 | + * Callbacks for the possible server replies. |
2806 | + */ |
2807 | + private void setup_callbacks () { |
2808 | + |
2809 | + // connected |
2810 | + client.event_connected.connect ((time, server) => { |
2811 | + debug (@"Connected to $server"); |
2812 | + connected = true; |
2813 | + if (to_join != null) |
2814 | + join_channel (to_join); |
2815 | + }); |
2816 | + |
2817 | + // join |
2818 | + client.event_join.connect ((time, server, from, chan) => { |
2819 | + |
2820 | + var channel = get_channel_if_valid (server, chan); |
2821 | + |
2822 | + if (channel == null) |
2823 | + return; |
2824 | + |
2825 | + var nick = from.split ("!")[0]; |
2826 | + |
2827 | + if (nick == identity.nick_name) { |
2828 | + debug (@"Joined $chan on $(network.address) as $(identity.nick_name)"); |
2829 | + setup_channel_callbacks (channel); |
2830 | + } else { |
2831 | + channel.add_user (nick); |
2832 | + } |
2833 | + }); |
2834 | + |
2835 | + // no such channel |
2836 | + client.event_no_such.connect ((time, server, target, type) => { |
2837 | + var channel = get_channel_if_valid (server, target); |
2838 | + |
2839 | + if (channel == null) |
2840 | + return; |
2841 | + |
2842 | + warning ("No such channel '%s'.", channel.name); |
2843 | + remove (channel); |
2844 | + left_channel (channel); //signal |
2845 | + }); |
2846 | + |
2847 | + // topic |
2848 | + client.event_topic.connect ((time, server, from, chan, topic) => { |
2849 | + var channel = get_channel_if_valid (server, chan); |
2850 | + |
2851 | + if (channel == null) |
2852 | + return; |
2853 | + |
2854 | + channel.room.topic_name.label = topic; |
2855 | + }); |
2856 | + |
2857 | + |
2858 | + |
2859 | + // names |
2860 | + client.event_names.connect ((time, server, chan, nicks, prefixes) => { |
2861 | + var channel = get_channel_if_valid (server, chan); |
2862 | + |
2863 | + if (channel == null) |
2864 | + return; |
2865 | + |
2866 | + channel.list_names (nicks, prefixes); |
2867 | + }); |
2868 | + |
2869 | + // part |
2870 | + client.event_part.connect ((time, server, from, chan, message) => { |
2871 | + var channel = get_channel_if_valid (server, chan); |
2872 | + |
2873 | + if (channel == null) |
2874 | + return; |
2875 | + |
2876 | + debug (@"Parted from $chan on $(network.address) as $(identity.nick_name)"); |
2877 | + |
2878 | + var nick = from.split ("!")[0]; |
2879 | + |
2880 | + if (nick == identity.nick_name) { |
2881 | + remove (channel); |
2882 | + left_channel (channel); //signal |
2883 | + } else { |
2884 | + channel.remove_user (nick); |
2885 | + } |
2886 | + }); |
2887 | + |
2888 | + // message |
2889 | + client.event_message.connect ((time, server, from, target, message) => { |
2890 | + var channel = get_channel_if_valid (server, target); |
2891 | + |
2892 | + if (channel == null) |
2893 | + return; |
2894 | + |
2895 | + var nick = from.split ("!")[0]; |
2896 | + |
2897 | + channel.room.message (nick, message); |
2898 | + }); |
2899 | + |
2900 | + // away |
2901 | + client.event_user_away.connect ((time, server, from, away) => { |
2902 | + if (server != this.server_id) |
2903 | + return; |
2904 | + |
2905 | + var nick = from.split ("!")[0]; |
2906 | + |
2907 | + debug (@"AWAY $server $nick $away"); |
2908 | + |
2909 | + if (nick == identity.nick_name) |
2910 | + this.away = away; |
2911 | + }); |
2912 | + |
2913 | + // nick |
2914 | + client.event_nick.connect ((time, server, from, new_nick) => { |
2915 | + if (server != this.server_id) |
2916 | + return; |
2917 | + |
2918 | + if (identity.nick_name != new_nick) |
2919 | + identity.nick_name = new_nick; |
2920 | + |
2921 | + client.server_set (server_id, "server", "nick", identity.nick_name); |
2922 | + }); |
2923 | + } |
2924 | + |
2925 | + /** |
2926 | + * Callbacks for GUI signals. |
2927 | + */ |
2928 | + private void setup_channel_callbacks (Channel channel) { |
2929 | + channel.room.send_message.connect ((text) => { |
2930 | + if (text[0] == '/'){} |
2931 | + //TODO client.raw (this.server_id, text.replace ("/", "")); |
2932 | + else |
2933 | + client.message (this.server_id, channel.name, text); |
2934 | + }); |
2935 | + } |
2936 | + |
2937 | + private void setup_settings_callbacks () { |
2938 | + identity.notify["nick-name"].connect (() => { |
2939 | + debug ("Sending nick request %s", identity.nick_name); |
2940 | + client.nick (this.server_id, identity.nick_name); |
2941 | + }); |
2942 | + } |
2943 | + |
2944 | + private Channel get_channel_if_valid (string server, string chan) { |
2945 | + if (server != this.server_id) |
2946 | + return (Channel) null; |
2947 | + |
2948 | + var channel = get_channel_by_name (chan); |
2949 | + |
2950 | + if (channel == null) |
2951 | + critical ("Channel '%s' has not been opened", chan); |
2952 | + |
2953 | + return channel; |
2954 | + } |
2955 | + |
2956 | + public void send_message (Channel channel, string message) { |
2957 | + client.message (this.server_id, channel.name, message); |
2958 | + } |
2959 | + |
2960 | + /** |
2961 | + * Retrieve a channel by its name. |
2962 | + * |
2963 | + * @param channel_name Name of the channel you are looking for. |
2964 | + */ |
2965 | + public Channel? get_channel_by_name (string channel_name) { |
2966 | + foreach (var channel in channels) |
2967 | + if (channel.name == channel_name) |
2968 | + return channel; |
2969 | + |
2970 | + return (Channel) null; |
2971 | + } |
2972 | + |
2973 | + public bool channel_is_joined (string channel_name) { |
2974 | + foreach (var channel in channels) |
2975 | + if (channel.name == channel_name) |
2976 | + return true; |
2977 | + |
2978 | + return false; |
2979 | + } |
2980 | + |
2981 | + /** |
2982 | + * Join a channel and return the Widget.Channel object. |
2983 | + * |
2984 | + * @param channel_name Name of the channel to be joined. |
2985 | + * @returns The created channel. |
2986 | + */ |
2987 | + public Channel? join_channel (string channel_name) { |
2988 | + if (connected == false) { |
2989 | + |
2990 | + client.event_connected.connect ((time, server) => { |
2991 | + if (server == this.server_id) { |
2992 | + connected = true; |
2993 | + join_channel (channel_name); |
2994 | } |
2995 | - |
2996 | - for (counter = 0; counter < p; counter++) { |
2997 | - string parsed = "<a href=\"" + links.index(counter) + "\">" + links.index(counter) + "</a>"; |
2998 | - print ("Link :%s\n".printf (links.index(counter))); |
2999 | - print ("Parsed Link :%s\n".printf (parsed)); |
3000 | - parsed_topic = parsed_topic.replace (links.index(counter), parsed); |
3001 | - } |
3002 | - |
3003 | - channel.room.topic_name.set_use_markup (true); |
3004 | - print ("Parsed Topic :%s\n".printf (parsed_topic)); |
3005 | - channel.room.topic_name.label = parsed_topic;*/ |
3006 | - }); |
3007 | - |
3008 | - this.add (channel); |
3009 | - |
3010 | - joined_channel (channel); //signal |
3011 | - |
3012 | - return channel; |
3013 | - } |
3014 | - |
3015 | - /** |
3016 | - * Leave a channel. |
3017 | - */ |
3018 | - public void leave_channel (string channel_name) { |
3019 | - var channel = get_channel_by_name (channel_name); |
3020 | - backend_server.leave_chan (channel_name); |
3021 | - remove (channel); |
3022 | - left_channel (channel); // signal |
3023 | - } |
3024 | - |
3025 | - public void quit () { |
3026 | - backend_server.quit_server ("Quitting:"); |
3027 | - } |
3028 | - |
3029 | - //builds up a ComboBox offering some default and your custom servers |
3030 | - /*modified by Xylon*/ |
3031 | - public static Gtk.ComboBoxText get_server_list () { |
3032 | - var box = new Gtk.ComboBoxText.with_entry (); |
3033 | - |
3034 | - //add the default ones |
3035 | - for (var i = 0; i < DEFAULT_SERVERS.length; i += 2) { |
3036 | - box.append (DEFAULT_SERVERS[i + 1], DEFAULT_SERVERS[i]); |
3037 | - } |
3038 | - |
3039 | - //add the custom ones |
3040 | - foreach (var server in Settings.get_default ().servers) { |
3041 | - if (server == "") |
3042 | - continue; |
3043 | - |
3044 | - var details = server.split (":"); |
3045 | - box.append (details[1], details[0]); |
3046 | - } |
3047 | - |
3048 | - box.active = 0; |
3049 | - |
3050 | - return box; |
3051 | - } |
3052 | - |
3053 | - public static Gtk.Dialog get_add_dialog () |
3054 | - { |
3055 | - var dialog = new Gtk.Dialog.with_buttons (_("Add Server"), null, Gtk.DialogFlags.MODAL); |
3056 | - var grid = new Gtk.Grid (); |
3057 | - var servernamelabel = new Gtk.Label (_("Server Name:")); |
3058 | - var serverurllabel = new Gtk.Label (_("Server URL:")); |
3059 | - var name = new Gtk.Entry (); |
3060 | - var url = new Gtk.Entry (); |
3061 | - var add = new Gtk.Button.with_label (_("Add Server")); |
3062 | - |
3063 | - name.placeholder_text = "Server"; |
3064 | - url.placeholder_text = "irc.server.net"; |
3065 | - grid.margin = 12; |
3066 | - grid.column_spacing = 6; |
3067 | - grid.row_spacing = 6; |
3068 | - |
3069 | - grid.attach (servernamelabel, 0, 0, 1, 1); |
3070 | - servernamelabel.set_alignment ( 1, 0.5f); |
3071 | - grid.attach (name, 1, 0, 1, 1); |
3072 | - grid.attach (serverurllabel, 0, 1, 1, 1); |
3073 | - serverurllabel.set_alignment ( 1, 0.5f); |
3074 | - grid.attach (url, 1, 1, 1, 1); |
3075 | - grid.attach (add, 1, 2, 1, 1); |
3076 | - |
3077 | - url.activate.connect (() => add.clicked ()); |
3078 | - |
3079 | - add.clicked.connect (() => { |
3080 | - var servers = Settings.get_default ().servers; |
3081 | - servers.resize (servers.length + 1); |
3082 | - servers[servers.length - 1] = name.text + ":" + url.text; |
3083 | - Settings.get_default ().servers = servers; |
3084 | - |
3085 | - dialog.destroy (); |
3086 | - }); |
3087 | - |
3088 | - name.changed.connect (() => add.sensitive = name.text != "" && url.text != ""); |
3089 | - url.changed.connect (() => add.sensitive = name.text != "" && url.text != ""); |
3090 | - |
3091 | - add.sensitive = false; |
3092 | - |
3093 | - (dialog.get_content_area () as Gtk.Container).add (grid); |
3094 | - dialog.title = _("Add Server"); |
3095 | - |
3096 | - return dialog; |
3097 | - } |
3098 | + }); |
3099 | + |
3100 | + return (Channel) null; |
3101 | + } |
3102 | + |
3103 | + if (channel_is_joined (channel_name)) { |
3104 | + warning (@"Channel '$channel_name' already joined."); |
3105 | + return (Channel) null; |
3106 | + } |
3107 | + |
3108 | + var channel = new Channel (channel_name); |
3109 | + this.add (channel); |
3110 | + |
3111 | + client.join (this.server_id, channel_name, ""); |
3112 | + joined_channel (channel); //signal |
3113 | + |
3114 | + return channel; |
3115 | + } |
3116 | + |
3117 | + /** |
3118 | + * Send PART message to server. |
3119 | + * |
3120 | + * @param channel_name Name of the channel you want to leave. |
3121 | + */ |
3122 | + public void leave_channel (string channel_name) { |
3123 | + var channel = get_channel_by_name (channel_name); |
3124 | + client.part (this.server_id, channel_name, identity.part_message); |
3125 | + } |
3126 | + |
3127 | + /** |
3128 | + * Quit the server. |
3129 | + */ |
3130 | + public void quit () { |
3131 | + client.quit (this.server_id, "Quit."); |
3132 | } |
3133 | } |
3134 | |
3135 | === modified file 'src/Widgets/ServerList.vala' |
3136 | --- src/Widgets/ServerList.vala 2013-05-29 18:15:05 +0000 |
3137 | +++ src/Widgets/ServerList.vala 2013-06-28 19:09:26 +0000 |
3138 | @@ -1,77 +1,104 @@ |
3139 | -namespace Cable.Widgets { |
3140 | - |
3141 | - /** |
3142 | - * This class stores all servers (Widget.Server) of the current window in |
3143 | - * a Granite.Widgets.SourceList. |
3144 | - */ |
3145 | - public class ServerList : Granite.Widgets.SourceList { |
3146 | - |
3147 | - /** |
3148 | - * List of all servers in the ServerList. |
3149 | - */ |
3150 | - GLib.List <Server> _servers = null; |
3151 | - public GLib.List <Server> servers { |
3152 | - get { |
3153 | - _servers = new GLib.List <Server> (); |
3154 | - foreach (var child in root.children) |
3155 | - _servers.append (child as Server); |
3156 | - return _servers; |
3157 | - } |
3158 | - } |
3159 | - |
3160 | - /** |
3161 | - * Get the server of the currently selected channel. |
3162 | - */ |
3163 | - public Server? current_server { |
3164 | - get { return selected.parent as Server; } |
3165 | - } |
3166 | - |
3167 | - /** |
3168 | - * Get the currently selected channel. |
3169 | - */ |
3170 | - public Channel? current_channel { |
3171 | - get { return selected as Channel; } |
3172 | - } |
3173 | - |
3174 | - /** |
3175 | - * Get the currently selected channel's room. |
3176 | - */ |
3177 | - public Room? current_room { |
3178 | - get { return current_channel.room as Room; } |
3179 | - } |
3180 | - |
3181 | - public ServerList () { |
3182 | - } |
3183 | - |
3184 | - public Server? get_server_by_URI (string URI) { |
3185 | - foreach (var server in servers) |
3186 | - if (server.uri == URI) |
3187 | - return server; |
3188 | - |
3189 | - return (Server) null; |
3190 | - } |
3191 | - |
3192 | - /** |
3193 | - * Amount of opened servers. |
3194 | - */ |
3195 | - public uint get_n_servers () { |
3196 | - return get_n_visible_children (root); |
3197 | - } |
3198 | - |
3199 | - /** |
3200 | - * Removes and quits a server from the List. |
3201 | - */ |
3202 | - public void remove_server (Server server) { |
3203 | - server.quit (); |
3204 | - root.remove (server); |
3205 | - } |
3206 | - |
3207 | - /** |
3208 | - * Add and connect to server. |
3209 | - */ |
3210 | - public void add_server (Server server) { |
3211 | - root.add (server); |
3212 | - } |
3213 | - } |
3214 | - |
3215 | +/*** |
3216 | + Copyright (C) 2013 Cable Developers |
3217 | + |
3218 | + This program or library is free software; you can redistribute it |
3219 | + and/or modify it under the terms of the GNU Lesser General Public |
3220 | + License as published by the Free Software Foundation; either |
3221 | + version 3 of the License, or (at your option) any later version. |
3222 | + |
3223 | + This library is distributed in the hope that it will be useful, |
3224 | + but WITHOUT ANY WARRANTY; without even the implied warranty of |
3225 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
3226 | + Lesser General Public License for more details. |
3227 | + |
3228 | + You should have received a copy of the GNU Lesser General |
3229 | + Public License along with this library; if not, write to the |
3230 | + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
3231 | + Boston, MA 02110-1301 USA. |
3232 | +***/ |
3233 | + |
3234 | +/** |
3235 | + * This class stores all servers (Widget.Server) of the current window in |
3236 | + * a Granite.Widgets.SourceList. |
3237 | + */ |
3238 | +public class Cable.Widgets.ServerList : Granite.Widgets.SourceList { |
3239 | + |
3240 | + /** |
3241 | + * List of all servers in the ServerList. |
3242 | + */ |
3243 | + Gee.ArrayList <Server> _servers = null; |
3244 | + public Gee.ArrayList <Server> servers { |
3245 | + get { |
3246 | + _servers = new Gee.ArrayList <Server> (); |
3247 | + foreach (var child in root.children) |
3248 | + _servers.add (child as Server); |
3249 | + return _servers; |
3250 | + } |
3251 | + } |
3252 | + |
3253 | + /** |
3254 | + * Get the server of the currently selected channel. |
3255 | + */ |
3256 | + public Server? current_server { |
3257 | + get { return selected.parent as Server; } |
3258 | + } |
3259 | + |
3260 | + /** |
3261 | + * Get the currently selected channel. |
3262 | + */ |
3263 | + public Channel? current_channel { |
3264 | + get { return selected as Channel; } |
3265 | + } |
3266 | + |
3267 | + /** |
3268 | + * Get the currently selected channel's room. |
3269 | + */ |
3270 | + public Room? current_room { |
3271 | + get { return current_channel.room as Room; } |
3272 | + } |
3273 | + |
3274 | + /** |
3275 | + * Amount of opened servers. |
3276 | + */ |
3277 | + /*public uint n_servers { |
3278 | + get { return get_n_visible_children (root); } |
3279 | + }*/ |
3280 | + |
3281 | + public ServerList () { |
3282 | + width_request = 150; |
3283 | + } |
3284 | + |
3285 | + /** |
3286 | + * Returns Server object from server URI or null |
3287 | + */ |
3288 | + public Server? get_server (string URI, string nick) { |
3289 | + foreach (var server in servers) |
3290 | + if (server.network.address == URI && |
3291 | + server.identity.nick_name == nick) |
3292 | + return server; |
3293 | + |
3294 | + return (Server) null; |
3295 | + } |
3296 | + |
3297 | + /** |
3298 | + * Amount of opened servers. |
3299 | + */ |
3300 | + public uint get_n_servers () { |
3301 | + return get_n_visible_children (root); |
3302 | + } |
3303 | + |
3304 | + /** |
3305 | + * Removes and quits a server from the List. |
3306 | + */ |
3307 | + public void remove_server (Server server) { |
3308 | + server.quit (); |
3309 | + root.remove (server); |
3310 | + } |
3311 | + |
3312 | + /** |
3313 | + * Add server. |
3314 | + */ |
3315 | + public void add_server (Server server) { |
3316 | + root.add (server); |
3317 | + } |
3318 | } |
3319 | |
3320 | === removed file 'src/Widgets/SettingsDialog.vala' |
3321 | --- src/Widgets/SettingsDialog.vala 2013-06-06 21:07:29 +0000 |
3322 | +++ src/Widgets/SettingsDialog.vala 1970-01-01 00:00:00 +0000 |
3323 | @@ -1,65 +0,0 @@ |
3324 | - |
3325 | -namespace Cable.Widgets { |
3326 | - |
3327 | - class LLabel : Gtk.Label { |
3328 | - |
3329 | - public LLabel (string text) { |
3330 | - label = text; |
3331 | - halign = Gtk.Align.START; |
3332 | - } |
3333 | - |
3334 | - public LLabel.right (string text) { |
3335 | - label = text; |
3336 | - halign = Gtk.Align.END; |
3337 | - } |
3338 | - } |
3339 | - |
3340 | - Gtk.Entry nick; |
3341 | - Gtk.Entry realname; |
3342 | - Gtk.Button done; |
3343 | - |
3344 | - public class SettingsDialog : Gtk.Dialog { |
3345 | - |
3346 | - public SettingsDialog () { |
3347 | - var main = new Gtk.Grid (); |
3348 | - main.margin = 12; |
3349 | - main.column_spacing = 6; |
3350 | - main.row_spacing = 6; |
3351 | - |
3352 | - nick = new Gtk.Entry (); |
3353 | - realname = new Gtk.Entry (); |
3354 | - |
3355 | - done = new Gtk.Button.with_label (_("Done")); |
3356 | - |
3357 | - main.attach (new LLabel.right (_("Nick:")), 0, 0, 1, 1); |
3358 | - main.attach (nick, 1, 0, 1, 1); |
3359 | - main.attach (new LLabel.right (_("Real Name:")), 0, 1, 1, 1); |
3360 | - main.attach (realname, 1, 1, 1, 1); |
3361 | - main.attach (done, 1, 2, 1, 1); |
3362 | - |
3363 | - modal = true; |
3364 | - (get_content_area () as Gtk.Container).add (main); |
3365 | - this.title = _("User Settings"); |
3366 | - |
3367 | - nick.changed.connect (update_sensivity); |
3368 | - realname.changed.connect (update_sensivity); |
3369 | - |
3370 | - done.clicked.connect (() => { |
3371 | - var settings = Cable.Settings.get_default (); |
3372 | - settings.real_name = realname.text; |
3373 | - settings.nick = nick.text; |
3374 | - |
3375 | - destroy (); |
3376 | - }); |
3377 | - |
3378 | - nick.text = Settings.get_default ().nick; |
3379 | - realname.text = Settings.get_default ().real_name; |
3380 | - |
3381 | - update_sensivity (); |
3382 | - } |
3383 | - |
3384 | - void update_sensivity () { |
3385 | - done.sensitive = nick.text != "" && realname.text != ""; |
3386 | - } |
3387 | - } |
3388 | -} |
3389 | |
3390 | === added file 'src/Widgets/StatusBar.vala' |
3391 | --- src/Widgets/StatusBar.vala 1970-01-01 00:00:00 +0000 |
3392 | +++ src/Widgets/StatusBar.vala 2013-06-28 19:09:26 +0000 |
3393 | @@ -0,0 +1,49 @@ |
3394 | +/*** |
3395 | + Copyright (C) 2013 Cable Developers |
3396 | + |
3397 | + This program or library is free software; you can redistribute it |
3398 | + and/or modify it under the terms of the GNU Lesser General Public |
3399 | + License as published by the Free Software Foundation; either |
3400 | + version 3 of the License, or (at your option) any later version. |
3401 | + |
3402 | + This library is distributed in the hope that it will be useful, |
3403 | + but WITHOUT ANY WARRANTY; without even the implied warranty of |
3404 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
3405 | + Lesser General Public License for more details. |
3406 | + |
3407 | + You should have received a copy of the GNU Lesser General |
3408 | + Public License along with this library; if not, write to the |
3409 | + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
3410 | + Boston, MA 02110-1301 USA. |
3411 | +***/ |
3412 | + |
3413 | +public class Cable.Widgets.StatusBar : Granite.Widgets.StatusBar { |
3414 | + |
3415 | + public signal void send_message (string message); |
3416 | + |
3417 | + public StatusBar () { |
3418 | + var item = get_nth_item (1); |
3419 | + item.remove (item.get_child ()); |
3420 | + item.set_expand (true); |
3421 | + item.halign = Gtk.Align.FILL; |
3422 | + |
3423 | + var entry = new Gtk.Entry (); |
3424 | + entry.halign = Gtk.Align.FILL; |
3425 | + |
3426 | + item.add (entry); |
3427 | + |
3428 | + get_nth_item (0).width_request = 156; |
3429 | + get_nth_item (2).width_request = 156; |
3430 | + |
3431 | + insert_widget (main_actions.get_action ("JoinChannel").create_tool_item() as Gtk.ToolButton, true); |
3432 | + insert_widget (main_actions.get_action ("LeaveChannel").create_tool_item() as Gtk.ToolButton, true); |
3433 | + insert_widget (main_actions.get_action ("EditCurrentId").create_tool_item() as Gtk.ToolButton, true); |
3434 | + insert_widget (main_actions.get_action ("Preferences").create_tool_item() as Gtk.ToolButton); |
3435 | + insert_widget (main_actions.get_action ("About").create_tool_item() as Gtk.ToolButton); |
3436 | + |
3437 | + entry.activate.connect (() => { |
3438 | + send_message (entry.text); |
3439 | + entry.text = ""; |
3440 | + }); |
3441 | + } |
3442 | +} |
3443 | |
3444 | === added file 'src/Widgets/Welcome.vala' |
3445 | --- src/Widgets/Welcome.vala 1970-01-01 00:00:00 +0000 |
3446 | +++ src/Widgets/Welcome.vala 2013-06-28 19:09:26 +0000 |
3447 | @@ -0,0 +1,112 @@ |
3448 | +/*** |
3449 | + Copyright (C) 2013 Cable Developers |
3450 | + |
3451 | + This program or library is free software; you can redistribute it |
3452 | + and/or modify it under the terms of the GNU Lesser General Public |
3453 | + License as published by the Free Software Foundation; either |
3454 | + version 3 of the License, or (at your option) any later version. |
3455 | + |
3456 | + This library is distributed in the hope that it will be useful, |
3457 | + but WITHOUT ANY WARRANTY; without even the implied warranty of |
3458 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
3459 | + Lesser General Public License for more details. |
3460 | + |
3461 | + You should have received a copy of the GNU Lesser General |
3462 | + Public License along with this library; if not, write to the |
3463 | + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
3464 | + Boston, MA 02110-1301 USA. |
3465 | +***/ |
3466 | + |
3467 | +public class Cable.Widgets.Welcome : Granite.Widgets.Welcome { |
3468 | + |
3469 | + public signal void done (Settings.Network network, Settings.Identity identity, string channel); |
3470 | + |
3471 | + Gtk.Entry channel_entry; |
3472 | + |
3473 | + public Welcome () { |
3474 | + base (_("Connect to the IRC world."), _("Join a Channel.")); |
3475 | + |
3476 | + var grid = new Gtk.Grid (); |
3477 | + grid.margin = 12; |
3478 | + grid.column_spacing = 6; |
3479 | + grid.row_spacing = 6; |
3480 | + |
3481 | + // Labels |
3482 | + var server_label = new Gtk.Label (_("Network:")); |
3483 | + server_label.halign = Gtk.Align.END; |
3484 | + server_label.valign = Gtk.Align.CENTER; |
3485 | + |
3486 | + var id_label = new Gtk.Label (_("Identity:")); |
3487 | + id_label.halign = Gtk.Align.END; |
3488 | + id_label.valign = Gtk.Align.CENTER; |
3489 | + |
3490 | + var channel_label = new Gtk.Label (_("Channel:")); |
3491 | + channel_label.halign = Gtk.Align.END; |
3492 | + channel_label.valign = Gtk.Align.CENTER; |
3493 | + |
3494 | + // Entries/Comboboxes |
3495 | + var server_entry = new Gtk.ComboBoxText.with_entry (); |
3496 | + for (int i = 0; i < Settings.networks.size; i++) |
3497 | + server_entry.append (i.to_string (), Settings.networks[i].name); |
3498 | + server_entry.active = 0; |
3499 | + |
3500 | + var id_entry = new Gtk.ComboBoxText.with_entry (); |
3501 | + for (int i = 0; i < Settings.identities.size; i++) |
3502 | + id_entry.append (i.to_string (), Settings.identities[i].nick_name); |
3503 | + id_entry.active = 0; |
3504 | + |
3505 | + channel_entry = new Gtk.Entry (); |
3506 | + channel_entry.secondary_icon_name = "edit-redo-symbolic"; |
3507 | + channel_entry.text = "#"; |
3508 | + |
3509 | + // button |
3510 | + var join_button = new Gtk.Button.with_label (_("Join Channel")); |
3511 | + join_button.halign = Gtk.Align.END; |
3512 | + |
3513 | + var button_box = new Gtk.ButtonBox (Gtk.Orientation.HORIZONTAL); |
3514 | + button_box.layout_style = Gtk.ButtonBoxStyle.END; |
3515 | + button_box.add (join_button); |
3516 | + |
3517 | + grid.attach (server_label, 0, 0, 1, 1); |
3518 | + grid.attach (server_entry, 1, 0, 1, 1); |
3519 | + grid.attach (id_label, 0, 1, 1, 1); |
3520 | + grid.attach (id_entry, 1, 1, 1, 1); |
3521 | + grid.attach (channel_label, 0, 2, 1, 1); |
3522 | + grid.attach (channel_entry, 1, 2, 1, 1); |
3523 | + grid.attach (button_box, 1, 3, 1, 1); |
3524 | + grid.margin = 6; |
3525 | + |
3526 | + channel_entry.insert_text.connect ((text) => |
3527 | + Utils.filter (channel_entry, text, {" ", ":"}) |
3528 | + ); |
3529 | + |
3530 | + join_button.clicked.connect (() => channel_entry.activate ()); |
3531 | + channel_entry.icon_release.connect (() => channel_entry.activate ()); |
3532 | + channel_entry.activate.connect (() => { |
3533 | + Settings.Network network; |
3534 | + Settings.Identity identity; |
3535 | + |
3536 | + if (server_entry.active_id == null) { |
3537 | + network = new Settings.Network (server_entry.get_active_text ()); |
3538 | + } else { |
3539 | + network = Settings.networks[int.parse (server_entry.active_id)]; |
3540 | + } |
3541 | + |
3542 | + if (id_entry.active_id == null) { |
3543 | + identity = new Settings.Identity (id_entry.get_active_text ()); |
3544 | + } else { |
3545 | + identity = Settings.identities[int.parse (id_entry.active_id)]; |
3546 | + } |
3547 | + |
3548 | + done (network, identity, channel_entry.text); |
3549 | + }); |
3550 | + |
3551 | + options.add (grid); |
3552 | + this.show_all (); |
3553 | + } |
3554 | + |
3555 | + public void focus_channel_entry () { |
3556 | + channel_entry.grab_focus (); |
3557 | + channel_entry.set_position (-1); |
3558 | + } |
3559 | +} |
3560 | |
3561 | === added file 'src/Window.vala' |
3562 | --- src/Window.vala 1970-01-01 00:00:00 +0000 |
3563 | +++ src/Window.vala 2013-06-28 19:09:26 +0000 |
3564 | @@ -0,0 +1,272 @@ |
3565 | +/*** |
3566 | + Copyright (C) 2013 Cable Developers |
3567 | + |
3568 | + This program or library is free software; you can redistribute it |
3569 | + and/or modify it under the terms of the GNU Lesser General Public |
3570 | + License as published by the Free Software Foundation; either |
3571 | + version 3 of the License, or (at your option) any later version. |
3572 | + |
3573 | + This library is distributed in the hope that it will be useful, |
3574 | + but WITHOUT ANY WARRANTY; without even the implied warranty of |
3575 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
3576 | + Lesser General Public License for more details. |
3577 | + |
3578 | + You should have received a copy of the GNU Lesser General |
3579 | + Public License along with this library; if not, write to the |
3580 | + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
3581 | + Boston, MA 02110-1301 USA. |
3582 | +***/ |
3583 | + |
3584 | +Gtk.ActionGroup main_actions; |
3585 | + |
3586 | +public class Cable.Window : Gtk.Window { |
3587 | + |
3588 | + bool welcome_shown; |
3589 | + |
3590 | + Gtk.EventBox display_box; |
3591 | + Widgets.ServerList server_list; |
3592 | + |
3593 | + Gtk.Grid layout; |
3594 | + Gtk.Toolbar toolbar; |
3595 | + Granite.Widgets.ThinPaned paned; |
3596 | + Widgets.StatusBar statusbar; |
3597 | + Widgets.Welcome welcome; |
3598 | + |
3599 | + Gtk.UIManager ui; |
3600 | + |
3601 | + const string ui_string = """ |
3602 | + <ui> |
3603 | + <popup name="MenuItemTool"> |
3604 | + <menuitem name="Join Channel" action="JoinChannel"/> |
3605 | + <menuitem name="Leave Channel" action="LeaveChannel"/> |
3606 | + <menuitem name="Edit Identity" action="EditCurrentId"/> |
3607 | + </popup> |
3608 | + |
3609 | + <popup name="AppMenu"> |
3610 | + <menuitem name="Preferences" action="Preferences"/> |
3611 | + </popup> |
3612 | + </ui> |
3613 | + """; |
3614 | + |
3615 | + public Window (Cable.App app) { |
3616 | + GLib.Object (application: app); |
3617 | + Settings.init (); |
3618 | + init_actions (); |
3619 | + init_layout (); |
3620 | + } |
3621 | + |
3622 | + ~Window () { |
3623 | + string [] channels = {}; |
3624 | + |
3625 | + foreach (var server in server_list.servers) { |
3626 | + foreach (var channel in server.channels) { |
3627 | + channels += string.join (":", server.network.address, |
3628 | + server.identity.nick_name, channel.name); |
3629 | + server.leave_channel (channel.name); |
3630 | + } |
3631 | + } |
3632 | + |
3633 | + Settings.settings.set_strv ("channels", channels); |
3634 | + } |
3635 | + |
3636 | + public void init_actions () { |
3637 | + main_actions = new Gtk.ActionGroup ("MainActionGroup"); |
3638 | + main_actions.set_translation_domain (Constants.GETTEXT_PACKAGE); |
3639 | + main_actions.add_actions (main_entries, this); |
3640 | + |
3641 | + ui = new Gtk.UIManager (); |
3642 | + |
3643 | + try { |
3644 | + ui.add_ui_from_string (ui_string, -1); |
3645 | + } catch (Error e) { |
3646 | + error ("Couldn't load the UI: %s", e.message); |
3647 | + } |
3648 | + |
3649 | + Gtk.AccelGroup accel_group = ui.get_accel_group (); |
3650 | + add_accel_group (accel_group); |
3651 | + |
3652 | + ui.insert_action_group (main_actions, 0); |
3653 | + ui.ensure_update (); |
3654 | + } |
3655 | + |
3656 | + private void init_layout () { |
3657 | + layout = new Gtk.Grid (); |
3658 | + server_list = new Widgets.ServerList (); |
3659 | + display_box = new Gtk.EventBox (); |
3660 | + toolbar = new Gtk.Toolbar (); |
3661 | + paned = new Granite.Widgets.ThinPaned (); |
3662 | + welcome = new Widgets.Welcome (); |
3663 | + statusbar = new Widgets.StatusBar (); |
3664 | + |
3665 | + layout.attach (toolbar, 0, 0, 1, 1); |
3666 | + |
3667 | + var join_button = main_actions.get_action ("JoinChannel").create_tool_item() as Gtk.ToolButton; |
3668 | + var leave_button = main_actions.get_action ("LeaveChannel").create_tool_item() as Gtk.ToolButton; |
3669 | + |
3670 | + toolbar.vexpand = false; |
3671 | + //toolbar.add (join_button); |
3672 | + //toolbar.add (leave_button); |
3673 | + |
3674 | + /*var spacer = new Gtk.ToolItem (); |
3675 | + spacer.set_expand (true); |
3676 | + toolbar.add (spacer); |
3677 | + |
3678 | + var menu = ui.get_widget ("ui/AppMenu") as Gtk.Menu; |
3679 | + app_menu = (application as Granite.Application).create_appmenu (menu); |
3680 | + toolbar.add (app_menu); |
3681 | + */ |
3682 | + |
3683 | + welcome.done.connect (join_channel); |
3684 | + welcome.hexpand = true; |
3685 | + welcome.vexpand = true; |
3686 | + |
3687 | + paned.position = 150; |
3688 | + paned.pack1 (server_list, false, false); |
3689 | + paned.pack2 (display_box, true, false); |
3690 | + |
3691 | + this.title = "Cable"; |
3692 | + this.icon_name = "internet-chat"; |
3693 | + this.set_default_size (740, 480); |
3694 | + this.window_position = Gtk.WindowPosition.CENTER; |
3695 | + this.show_all (); |
3696 | + |
3697 | + statusbar.send_message.connect ((msg) => { |
3698 | + server_list.current_server.send_message (server_list.current_channel, msg); |
3699 | + }); |
3700 | + |
3701 | + server_list.item_selected.connect ((item) => { |
3702 | + if (item != null && item is Widgets.Channel) { |
3703 | + var channel = item as Widgets.Channel; |
3704 | + var content = display_box.get_children ().nth_data (0); |
3705 | + |
3706 | + if (content != null) |
3707 | + display_box.remove (content); |
3708 | + |
3709 | + display_box.add ((item as Widgets.Channel).room); |
3710 | + display_box.show_all (); |
3711 | + title = string.join (" — ", channel.name, channel.server.identity.nick_name); |
3712 | + } |
3713 | + }); |
3714 | + |
3715 | + var channels = Settings.settings.get_strv ("channels"); |
3716 | + |
3717 | + if (channels.length > 0) { |
3718 | + welcome_shown = false; |
3719 | + layout.attach (paned, 0, 1, 1, 1); |
3720 | + layout.attach (statusbar, 0, 2, 1, 1); |
3721 | + this.add (layout); |
3722 | + this.show_all (); |
3723 | + |
3724 | + foreach (var channel in channels) { |
3725 | + var parts = channel.split (":"); |
3726 | + |
3727 | + Settings.Network network = null; |
3728 | + Settings.Identity identity = null; |
3729 | + |
3730 | + foreach (var nw in Settings.networks) |
3731 | + if (nw.address == parts[0]) |
3732 | + network = nw; |
3733 | + |
3734 | + foreach (var id in Settings.identities) |
3735 | + if (id.nick_name == parts[1]) |
3736 | + identity = id; |
3737 | + |
3738 | + if (network == null) |
3739 | + network = new Settings.Network (parts[0]); |
3740 | + |
3741 | + if (identity == null) |
3742 | + identity = new Settings.Identity (parts[1]); |
3743 | + |
3744 | + join_channel (network, identity, parts[2]); |
3745 | + } |
3746 | + |
3747 | + server_list.selected = server_list.servers[0].channels[0]; |
3748 | + } else { |
3749 | + welcome_shown = true; |
3750 | + layout.attach (welcome, 0, 1, 1, 1); |
3751 | + this.add (layout); |
3752 | + this.show_all (); |
3753 | + welcome.focus_channel_entry (); |
3754 | + } |
3755 | + } |
3756 | + |
3757 | + void join_channel (Settings.Network network, Settings.Identity identity, string channel_name) { |
3758 | + var server = server_list.get_server (network.address, identity.nick_name); |
3759 | + |
3760 | + if (server == null) { |
3761 | + |
3762 | + server = new Widgets.Server (network, identity); |
3763 | + server_list.add_server (server); |
3764 | + |
3765 | + server.joined_channel.connect ((channel) => { |
3766 | + if (welcome_shown) { |
3767 | + welcome_shown = false; |
3768 | + layout.remove (welcome); |
3769 | + layout.attach (paned, 0, 1, 1, 1); |
3770 | + layout.attach (statusbar, 0, 2, 1, 1); |
3771 | + this.show_all (); |
3772 | + welcome.focus_channel_entry (); |
3773 | + server_list.selected = channel; |
3774 | + } |
3775 | + }); |
3776 | + |
3777 | + server.left_channel.connect ((channel) => { |
3778 | + if (server_list.get_n_servers () == 0) { |
3779 | + welcome_shown = true; |
3780 | + layout.remove (paned); |
3781 | + layout.remove (statusbar); |
3782 | + layout.attach (welcome, 0, 1, 1, 1); |
3783 | + this.show_all (); |
3784 | + } |
3785 | + }); |
3786 | + } |
3787 | + |
3788 | + server.join_channel (channel_name); |
3789 | + } |
3790 | + |
3791 | + void action_join_channel () { |
3792 | + var dialog = new Dialogs.JoinChannel (); |
3793 | + dialog.done.connect (join_channel); |
3794 | + dialog.show_all (); |
3795 | + } |
3796 | + |
3797 | + void action_leave_channel () { |
3798 | + var channel = server_list.current_channel; |
3799 | + |
3800 | + if (channel != null) |
3801 | + server_list.current_server.leave_channel (channel.name); |
3802 | + else |
3803 | + warning ("No channel selected, cannot leave."); |
3804 | + } |
3805 | + |
3806 | + void action_edit_identity () { |
3807 | + var dialog = new Dialogs.ManageIdentity (server_list.current_server.identity); |
3808 | + dialog.show_all (); |
3809 | + } |
3810 | + |
3811 | + void action_about () { |
3812 | + (application as Cable.App).show_about (this); |
3813 | + } |
3814 | + |
3815 | + void action_preferences () { |
3816 | + var dialog = new Dialogs.Preferences (); |
3817 | + dialog.show_all (); |
3818 | + } |
3819 | + |
3820 | + private static const Gtk.ActionEntry[] main_entries = { |
3821 | + { "JoinChannel", "list-add-symbolic", N_("Join Channel…"), "<Control>j", |
3822 | + N_("Join Channel…"), action_join_channel }, |
3823 | + |
3824 | + { "LeaveChannel", "list-remove-symbolic", N_("Leave current Channel"), "<Control>l", |
3825 | + N_("Leave current channel"), action_leave_channel }, |
3826 | + |
3827 | + { "EditCurrentId", "avatar-default-symbolic", N_("Edit current Identity…"), "<Control>i", |
3828 | + N_("Edit current Identity…"), action_edit_identity }, |
3829 | + |
3830 | + { "Preferences", "document-properties-symbolic", N_("Preferences"), null, |
3831 | + N_("Preferences"), action_preferences }, |
3832 | + |
3833 | + { "About", "help-info-symbolic", N_("About"), null, |
3834 | + N_("About"), action_about } |
3835 | + }; |
3836 | +} |
3837 | |
3838 | === removed file 'src/doodleIRC.vala' |
3839 | --- src/doodleIRC.vala 2013-05-29 18:15:05 +0000 |
3840 | +++ src/doodleIRC.vala 1970-01-01 00:00:00 +0000 |
3841 | @@ -1,385 +0,0 @@ |
3842 | -// -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*- |
3843 | -/*** |
3844 | - BEGIN LICENSE |
3845 | - |
3846 | - Copyright (C) 2013 Akshay Shekher <voldyman666@gmail.com> |
3847 | - This program is free software: you can redistribute it and/or modify it |
3848 | - under the terms of the GNU Lesser General Public License version 3, as published |
3849 | - by the Free Software Foundation. |
3850 | - |
3851 | - This program is distributed in the hope that it will be useful, but |
3852 | - WITHOUT ANY WARRANTY; without even the implied warranties of |
3853 | - MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
3854 | - PURPOSE. See the GNU General Public License for more details. |
3855 | - |
3856 | - You should have received a copy of the GNU General Public License along |
3857 | - with this program. If not, see <http://www.gnu.org/licenses/> |
3858 | - |
3859 | - END LICENSE |
3860 | -***/ |
3861 | - |
3862 | -namespace doodleIRC { |
3863 | - |
3864 | - public errordomain IRCError { |
3865 | - COULD_NOT_CONNECT, |
3866 | - COULD_NOT_JOIN |
3867 | - // ... |
3868 | - } |
3869 | - |
3870 | - public class Channel { |
3871 | - |
3872 | - public string nick; |
3873 | - public string topic; |
3874 | - public List<string> users; |
3875 | - public string name; |
3876 | - |
3877 | - public Channel (string name) { |
3878 | - this.name = name; |
3879 | - } |
3880 | - } |
3881 | - |
3882 | - public class DoodleIRCServer { |
3883 | - |
3884 | - // Signals |
3885 | - public signal void on_connect_complete (); |
3886 | - public signal void on_message (string sender, string chan, string msg); |
3887 | - public signal void on_action (string sender, string chan, string msg); |
3888 | - public signal void on_notice (string notice); |
3889 | - public signal void on_error (string error_msg); |
3890 | - public signal void on_user_join (string chan, string nick); |
3891 | - public signal void on_join_complete (string chan, string nick); |
3892 | - public signal void on_user_quit (string chan, string nick, string msg); |
3893 | - public signal void on_names_listed (string chan, string[] names); |
3894 | - |
3895 | - public delegate void GetTopicFunc (string chan, string topic); |
3896 | - public List<Channel> chans; |
3897 | - |
3898 | - GetTopicFunc topic_received; |
3899 | - string nick; |
3900 | - bool away; |
3901 | - string server_url; |
3902 | - User user; |
3903 | - SocketConnection connection; |
3904 | - DataInputStream response; |
3905 | - bool connected; |
3906 | - List<string> to_send; |
3907 | - Gee.HashMap<string, string> list_of_names; |
3908 | - |
3909 | - public DoodleIRCServer (string url, User user,string nick) { |
3910 | - this.server_url = url; |
3911 | - this.user = user; |
3912 | - this.nick = nick; |
3913 | - away = false; |
3914 | - |
3915 | - topic_received = (chan, topic) => { |
3916 | - debug (chan + "=>" + topic); |
3917 | - }; |
3918 | - this.chans = new List<Channel> (); |
3919 | - connected = false; |
3920 | - to_send = new List<string> (); |
3921 | - |
3922 | - list_of_names = new Gee.HashMap<string,string> (); |
3923 | - |
3924 | - on_connect_complete.connect (() => { |
3925 | - to_send.foreach ((cmd) => { |
3926 | - debug ("Sending "+cmd); |
3927 | - raw_send (cmd); |
3928 | - to_send.remove (cmd); |
3929 | - }); |
3930 | - }); |
3931 | - } |
3932 | - |
3933 | - ~DoodleIRCServer () { |
3934 | - print ("Exiting"); |
3935 | - quit_server ("Client Quit"); |
3936 | - } |
3937 | - |
3938 | - public async void connect (string server = "") { |
3939 | - try { |
3940 | - // Resolve hostname to IP address |
3941 | - var resolver = Resolver.get_default (); |
3942 | - var addresses = yield resolver.lookup_by_name_async (this.server_url, null); |
3943 | - var address = addresses.nth_data (0); |
3944 | - debug ("Resolved %s to %s\n".printf (this.server_url, address.to_string ())); |
3945 | - |
3946 | - // Connect |
3947 | - var client = new SocketClient (); |
3948 | - connection = yield client.connect_async (new InetSocketAddress (address, 6667)); |
3949 | - debug ("Connected to %s\n".printf (this.server_url)); |
3950 | - this.connected = true; |
3951 | - //response stream |
3952 | - response = new DataInputStream (connection.input_stream); |
3953 | - |
3954 | - // Send USER request |
3955 | - var message = "USER %s %s %s :%s\r\n".printf (user.username, user.hostname, |
3956 | - user.servername, user.realname); |
3957 | - raw_send (message); |
3958 | - debug ("Wrote request USER\n"); |
3959 | - |
3960 | - // Send NICK request |
3961 | - message = "NICK %s\r\n".printf (nick); |
3962 | - raw_send (message); |
3963 | - debug ("Wrote nick request\n"); |
3964 | - |
3965 | - wait.begin (); |
3966 | - } catch (Error e) { |
3967 | - error ("Could not connect: %s".printf (e.message)); |
3968 | - } |
3969 | - |
3970 | - } |
3971 | - |
3972 | - public async void wait () { |
3973 | - try { |
3974 | - var line = yield response.read_line_async (); |
3975 | - parse_line (line); |
3976 | - } catch (Error e) { |
3977 | - print ("Error: %s\n".printf (e.message)); |
3978 | - } |
3979 | - |
3980 | - if (connected) |
3981 | - wait.begin (); |
3982 | - } |
3983 | - |
3984 | - private void parse_line (string line) { |
3985 | - print (line + "\n"); |
3986 | - |
3987 | - if (line[0] != ':') { |
3988 | - process_named_server_message (line); |
3989 | - return; |
3990 | - } |
3991 | - |
3992 | - if (line[0] == ':') { |
3993 | - if ((line.split (" ")[1][0]).isdigit ()) { |
3994 | - process_numeric_cmd (line); |
3995 | - } else { |
3996 | - process_named_message (line); |
3997 | - } |
3998 | - } |
3999 | - } |
4000 | - |
4001 | - private void process_named_message (string line) { |
4002 | - string sender="", cmd="", chan="", msg=""; |
4003 | - parse_named_msg (line, out sender,out cmd, out chan, out msg); |
4004 | - |
4005 | - switch (cmd.up ()) { |
4006 | - case "PRIVMSG": |
4007 | - if (msg.split (" ")[0] == "\001ACTION") { |
4008 | - msg = msg.replace ("ACTION ", ""); |
4009 | - msg = msg.replace ("\001", ""); |
4010 | - on_action (sender, chan, msg); |
4011 | - break; |
4012 | - } |
4013 | - |
4014 | - print ("Chan-> "+chan+"\nMSG-> "+msg+"\n"); |
4015 | - on_message (sender, chan, msg); |
4016 | - break; |
4017 | - |
4018 | - case "QUIT": |
4019 | - print (" %s has quit\n".printf (sender)); |
4020 | - on_user_quit (chan, sender, msg); |
4021 | - break; |
4022 | - |
4023 | - case "JOIN": |
4024 | - if (sender == nick) { |
4025 | - on_join_complete (chan, sender); |
4026 | - break; |
4027 | - } |
4028 | - print ("User has Joined"); |
4029 | - on_user_join (chan, sender); |
4030 | - break; |
4031 | - } |
4032 | - } |
4033 | - |
4034 | - private void process_named_server_message (string line) { |
4035 | - var cmd = line.split (" ")[0].strip (); |
4036 | - var msg = line.split (" :")[1].strip (); |
4037 | - |
4038 | - switch (cmd.up ()) { |
4039 | - case "PING": |
4040 | - print ("pinged\n"); |
4041 | - raw_send (line.replace ("PING","PONG")); |
4042 | - break; |
4043 | - |
4044 | - case "NOTICE": |
4045 | - print ("Noice: "+msg+"\n"); |
4046 | - on_notice (msg); |
4047 | - break; |
4048 | - |
4049 | - case "ERROR": |
4050 | - print ("An Error Occured: %s\n".printf (msg)); |
4051 | - on_error (msg); |
4052 | - break; |
4053 | - } |
4054 | - } |
4055 | - |
4056 | - private void process_numeric_cmd (string line) { |
4057 | - var first_split = line.split (" "); |
4058 | - /* this might come handy in the future :) */ |
4059 | - //var sender = first_split[0].strip (); |
4060 | - var cmd = first_split[1].strip (); |
4061 | - var msg = line.split (" :")[1].strip (); |
4062 | - |
4063 | - /* more info about these commands can be found at the IRC RFC page */ |
4064 | - switch (cmd) { |
4065 | - case "001": |
4066 | - on_connect_complete (); |
4067 | - break; |
4068 | - |
4069 | - case "005": |
4070 | - // this.connect (msg); |
4071 | - break; |
4072 | - |
4073 | - case "301": |
4074 | - print ("Away: "+msg); |
4075 | - break; |
4076 | - |
4077 | - case "433": // nick name is use |
4078 | - change_nick (this.nick + "_"); |
4079 | - rejoin_channels (); |
4080 | - break; |
4081 | - |
4082 | - case "353": //RPL_NAMESLISTED |
4083 | - var chan = first_split[4]; |
4084 | - if (list_of_names.has_key (chan)) { |
4085 | - var names = list_of_names.get (chan); |
4086 | - names = " " + msg; |
4087 | - list_of_names.set (chan, names); |
4088 | - } else { |
4089 | - list_of_names.set (chan, msg); |
4090 | - } |
4091 | - |
4092 | - break; |
4093 | - |
4094 | - case "366": //RPL_ENDOFNAMES |
4095 | - foreach (var channel in list_of_names.keys.to_array ()) { |
4096 | - on_names_listed (channel, list_of_names.get (channel).split (" ")); |
4097 | - } |
4098 | - |
4099 | - list_of_names.clear (); |
4100 | - break; |
4101 | - case "332": |
4102 | - var chan = first_split[3].strip (); |
4103 | - chans.foreach((channel) => { |
4104 | - if (channel.name == chan) { |
4105 | - channel.topic = msg; |
4106 | - topic_received (channel.name, msg); |
4107 | - } |
4108 | - }); |
4109 | - break; |
4110 | - } |
4111 | - } |
4112 | - |
4113 | - private void parse_named_msg (string line, out string sender,out string cmd, |
4114 | - out string chan, out string msg) { |
4115 | - // split the message from the info |
4116 | - var first_split = line.split (":"); |
4117 | - var info = first_split[1]; |
4118 | - // msg = join_str_ar (2, first_split.length, first_split); |
4119 | - msg = line.split (" :")[1]; |
4120 | - |
4121 | - // split the info to extract sender and chan |
4122 | - var second_split = info.split (" "); |
4123 | - cmd = second_split[1].strip (); |
4124 | - chan = second_split[2].strip (); |
4125 | - sender = second_split[0].strip ().split ("!")[0]; |
4126 | - } |
4127 | - |
4128 | - private void raw_send (string line) { |
4129 | - try { |
4130 | - connection.output_stream.write (line.data); |
4131 | - connection.output_stream.flush (); |
4132 | - } catch (Error e) { |
4133 | - error ("raw_send: %s".printf (e.message)); |
4134 | - } |
4135 | - } |
4136 | - |
4137 | - public void send (string cmd) { |
4138 | - if (connected) |
4139 | - raw_send (cmd); |
4140 | - else |
4141 | - to_send.append (cmd); |
4142 | - } |
4143 | - |
4144 | - private void rejoin_channels () { |
4145 | - // Send JOIN request |
4146 | - foreach (var chan in chans) { |
4147 | - string chan_name = chan.name; |
4148 | - raw_send ("JOIN %s\r\n".printf (chan_name)); |
4149 | - print ("Wrote request to join %s\n".printf (chan_name)); |
4150 | - } |
4151 | - } |
4152 | - |
4153 | - public void kick_user (string chan, string user, string reason) { |
4154 | - send ("KICK %s %s :%s\r\n".printf (chan, user, reason)); |
4155 | - } |
4156 | - |
4157 | - public void join_chan (string chan, string key="") /*throws IRCError*/ { |
4158 | - send ("JOIN %s :%s\r\n".printf (chan, key)); |
4159 | - var channel = new Channel (chan); |
4160 | - chans.append (channel); |
4161 | - } |
4162 | - |
4163 | - public void quit_server (string message) { |
4164 | - send ("QUIT :%s\r\n".printf (message)); |
4165 | - } |
4166 | - |
4167 | - public void leave_chan (string chan) { |
4168 | - send ("PART %s\r\n".printf (chan)); |
4169 | - } |
4170 | - |
4171 | - public void write (string chan, string msg) { |
4172 | - send ("PRIVMSG %s :%s\r\n".printf (chan, msg)); |
4173 | - } |
4174 | - |
4175 | - public void notice (string to, string text) { |
4176 | - send ("NOTICE %s :%s\r\n".printf (to, text)); |
4177 | - } |
4178 | - |
4179 | - public void get_names (string chan) { |
4180 | - send ("NAMES %s\r\n".printf (chan)); |
4181 | - } |
4182 | - |
4183 | - public void set_away (string reason) { |
4184 | - away = true; |
4185 | - send ("AWAY :%s\r\n".printf (reason)); |
4186 | - } |
4187 | - |
4188 | - public void set_back () { |
4189 | - away = false; |
4190 | - send ("AWAY \r\n"); |
4191 | - } |
4192 | - |
4193 | - public void toggle_away (string reason = "") { |
4194 | - if (this.away) |
4195 | - set_back (); |
4196 | - else |
4197 | - set_away (reason); |
4198 | - } |
4199 | - |
4200 | - public void change_nick (string nick) { |
4201 | - this.nick = nick; |
4202 | - raw_send ("NICK %s\r\n".printf (this.nick)); |
4203 | - } |
4204 | - |
4205 | - public void write_action (string chan, string msg) { |
4206 | - write (chan, "\001ACTION %s\001\r\n".printf (msg)); |
4207 | - } |
4208 | - |
4209 | - public void disconnect () { |
4210 | - raw_send ("QUIT :bye"); |
4211 | - connected = false; |
4212 | - } |
4213 | - |
4214 | - public void get_topic (string chan, GetTopicFunc func) { |
4215 | - topic_received = func; |
4216 | - send ("TOPIC %s\r\n".printf (chan)); |
4217 | - } |
4218 | - } |
4219 | - |
4220 | - public struct User { |
4221 | - public string username; |
4222 | - public string hostname; |
4223 | - public string servername; |
4224 | - public string realname; |
4225 | - } |
4226 | -} |
This is now almost ready for merging. There are still a few regressiong left because of the switch to maki as backend daemon, which I'll try to fix asap so we can continue enhancing cable and implementing new features.