1 /*
2 * Simple demo GUI for the Pedro mini-XMPP client.
3 *
4 * Authors:
5 * Bob Jamison
6 *
7 * Copyright (C) 2005 Bob Jamison
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
24 #include "jabber_whiteboard/pedrogui.h"
25 #include "jabber_whiteboard/session-manager.h"
27 #include <glibmm/i18n.h>
29 #include <stdarg.h>
31 namespace Pedro
32 {
36 //#########################################################################
37 //# I C O N S
38 //#########################################################################
40 static const guint8 icon_available[] =
41 { ""
42 /* Pixbuf magic (0x47646b50) */
43 "GdkP"
44 /* length: header (24) + pixel_data (672) */
45 "\0\0\2\270"
46 /* pixdata_type (0x1010002) */
47 "\1\1\0\2"
48 /* rowstride (48) */
49 "\0\0\0""0"
50 /* width (12) */
51 "\0\0\0\14"
52 /* height (14) */
53 "\0\0\0\16"
54 /* pixel_data: */
55 "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377333"
56 "\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
57 "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377"
58 "\0\377\377\377\0\377\377\377\0\377333\377\377\377\377\0\377\377\377\0"
59 "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377"
60 "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\37733"
61 "3\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377"
62 "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
63 "\377\377\0\377\377\377\0\377333\377\377\377\377\0\377\377\377\0\377\377"
64 "\377\0""333\377\377\377\0\377\377\377\0\377\0\0\0\377\377\377\0\377\0"
65 "\0\0\377\377\377\0\377\377\377\0\377333\377\377\377\377\0\377\377\377"
66 "\0\377\377\377\0""333\377\377\377\0\377\377\377\0\377\0\0\0\377\377\377"
67 "\0\377\0\0\0\377\377\377\0\377\377\377\0\377333\377\377\377\377\0\377"
68 "\377\377\0\377\377\377\0""333\377\377\377\0\377\377\377\0\377\377\377"
69 "\0\377\0\0\0\377\377\377\0\377\377\377\0\377\377\377\0\377333\377\377"
70 "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377"
71 "\0\377\377\377\0\377\0\0\0\377\377\377\0\377\377\377\0\377333\377\377"
72 "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""3"
73 "33\377\377\377\0\377\377\377\0\377\0\0\0\377\377\377\0\377\377\377\0"
74 "\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
75 "\377\377\0\377\377\377\0""333\377\377\377\0\377\377\377\0\377\377\377"
76 "\0\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
77 "\377\377\377\0\377\377\377\0\377\377\377\0LLL\377\0\0\0\377\0\0\0\377"
78 "\0\0\0\377LLL\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
79 "\0\377\377\377\0\377\377\377\0\377\377\377\0LLL\377\0\0\0\377\0\0\0\377"
80 "\0\0\0\377LLL\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
81 "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\0\0\0\377"
82 "\0\0\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
83 "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
84 "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
85 "\377\0\377\377\377\0\377\377\377\0\377\377\377\0"};
88 static const guint8 icon_away[] =
89 { ""
90 /* Pixbuf magic (0x47646b50) */
91 "GdkP"
92 /* length: header (24) + pixel_data (672) */
93 "\0\0\2\270"
94 /* pixdata_type (0x1010002) */
95 "\1\1\0\2"
96 /* rowstride (48) */
97 "\0\0\0""0"
98 /* width (12) */
99 "\0\0\0\14"
100 /* height (14) */
101 "\0\0\0\16"
102 /* pixel_data: */
103 "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
104 "\0""333\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
105 "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
106 "\377\0""333\377\377\377\0\377\377\377\0\377333\377\377\377\377\0\377"
107 "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
108 "\377\377\0""333\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
109 "\0\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
110 "\377\377\377\0\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0"
111 "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\377\377\0\377\377\377"
112 "\0\377\377\377\0\377\0\0\377\377\377\377\377\377\377\377\377\377\377"
113 "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
114 "\377\377\377\377\377\377\0\0\377\377\377\377\0\377\0\0\377\377\377\377"
115 "\377\0\0\0\377\377\377\377\377\377\377\377\377\0\0\0\377\377\377\377"
116 "\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\0\0\377"
117 "\377\0\0\377\377\377\377\377\0\0\0\377\0\0\0\377\377\377\377\377\0\0"
118 "\0\377\0\0\0\377\377\377\377\377\377\377\377\377\0\0\0\377\377\377\377"
119 "\377\377\0\0\377\377\0\0\377\377\377\377\377\0\0\0\377\377\377\377\377"
120 "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377"
121 "\377\377\377\0\0\377\377\0\0\377\377\377\377\377\0\0\0\377\377\377\377"
122 "\377\377\377\377\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377"
123 "\377\0\0\0\377\377\377\377\377\377\0\0\377\377\377\377\0\377\0\0\377"
124 "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
125 "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0"
126 "\377\377\377\377\0\377\377\377\0\377\377\377\0\377\0\0\377\377\0\0\377"
127 "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0"
128 "\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
129 "\377\0\377\377\377\0LLL\377333\377\0\0\0\377\0\0\0\377LLL\377\377\377"
130 "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
131 "\377\0\377\377\377\0\377\377\377\0""333\377333\377333\377\377\377\377"
132 "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
133 "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
134 "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
135 "\0"};
138 static const guint8 icon_chat[] =
139 { ""
140 /* Pixbuf magic (0x47646b50) */
141 "GdkP"
142 /* length: header (24) + pixel_data (672) */
143 "\0\0\2\270"
144 /* pixdata_type (0x1010002) */
145 "\1\1\0\2"
146 /* rowstride (48) */
147 "\0\0\0""0"
148 /* width (12) */
149 "\0\0\0\14"
150 /* height (14) */
151 "\0\0\0\16"
152 /* pixel_data: */
153 "\377\377\377\0\377\377\377\0\377\377\377\0""333\377333\377333\377\377"
154 "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
155 "\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377\377\377"
156 "\0\377\377\377\0\377333\377\377\377\377\0\377\377\377\0\377\377\377\0"
157 "\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377\377"
158 "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377333\377\377\377\377"
159 "\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377\377"
160 "\377\0\377fff\377\377\377\0\377fff\377\377\377\0\377\377\377\0\37733"
161 "3\377\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377"
162 "fff\377\377\377\0\377fff\377\377\377\0\377fff\377\377\377\0\377333\377"
163 "\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377fff"
164 "\377\377\377\0\377\377\377\0\377\377\377\0\377\0\0\0\377\0\0\0\377\0"
165 "\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""33"
166 "3\377\377\377\0\377fff\377\377\377\0\377\0\0\0\377\377\377\0\377\377"
167 "\377\0\377\377\377\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377\377"
168 "\377\0""333\377\377\377\0\377fff\377\0\0\0\377\377\377\0\377\377\377"
169 "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\0\0\0\377\377\377\377"
170 "\0\377\377\377\0\377\377\377\0""333\377\0\0\0\377\377\377\0\377\377\377"
171 "\0\377\0\0\0\377\377\377\0\377\0\0\0\377\377\377\0\377\377\377\0\377"
172 "\0\0\0\377\377\377\377\0\377\377\377\0""333\377\0\0\0\377\377\377\0\377"
173 "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
174 "\377\377\0\377\0\0\0\377\377\377\377\0\377\377\377\0LLL\377\0\0\0\377"
175 "\377\377\0\377\377\377\0\377\0\0\0\377\377\377\0\377\0\0\0\377\377\377"
176 "\0\377\377\377\0\377\0\0\0\377\377\377\377\0\377\377\377\0LLL\377333"
177 "\377\0\0\0\377\377\377\0\377\377\377\0\377\0\0\0\377\377\377\0\377\377"
178 "\377\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
179 "\377\0""333\377333\377\0\0\0\377\377\377\0\377\377\377\0\377\377\377"
180 "\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
181 "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\0\0\0\377"
182 "\0\0\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0"};
185 static const guint8 icon_dnd[] =
186 { ""
187 /* Pixbuf magic (0x47646b50) */
188 "GdkP"
189 /* length: header (24) + pixel_data (672) */
190 "\0\0\2\270"
191 /* pixdata_type (0x1010002) */
192 "\1\1\0\2"
193 /* rowstride (48) */
194 "\0\0\0""0"
195 /* width (12) */
196 "\0\0\0\14"
197 /* height (14) */
198 "\0\0\0\16"
199 /* pixel_data: */
200 "\377\377\377\0\377\377\377\0\377\377\377\0""333\377333\377333\377\377"
201 "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
202 "\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377\377\377"
203 "\0\377\377\377\0\377333\377\377\377\377\0\377\377\377\0\377\377\377\0"
204 "\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377\377"
205 "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377333\377\377\377\377"
206 "\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377\377"
207 "\377\0\377fff\377\377\377\0\377fff\377\377\377\0\377\377\377\0\37733"
208 "3\377\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377"
209 "fff\377\377\377\0\377fff\377\377\377\0\377fff\377\377\377\0\377333\377"
210 "\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377fff"
211 "\377\377\377\0\377\377\377\0\377\377\377\0\377\177\0\0\377\177\0\0\377"
212 "\177\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
213 "333\377\377\377\0\377fff\377\377\377\0\377\177\0\0\377\377\0\0\377\377"
214 "\0\0\377\377\0\0\377\177\0\0\377\377\377\377\0\377\377\377\0\377\377"
215 "\377\0""333\377\377\377\0\377fff\377\177\0\0\377\377\377\377\377fff\377"
216 "\377\0\0\377fff\377\377\377\377\377\177\0\0\377\377\377\377\0\377\377"
217 "\377\0\377\377\377\0""333\377\177\0\0\377\377\0\0\377fff\377\377\377"
218 "\377\377fff\377\377\377\377\377fff\377\377\0\0\377\177\0\0\377\377\377"
219 "\377\0\377\377\377\0""333\377\177\0\0\377\377\0\0\377\377\0\0\377fff"
220 "\377\377\377\377\377fff\377\377\0\0\377\377\0\0\377\177\0\0\377\377\377"
221 "\377\0\377\377\377\0LLL\377\177\0\0\377\377\0\0\377fff\377\377\377\377"
222 "\377fff\377\377\377\377\377fff\377\377\0\0\377\177\0\0\377\377\377\377"
223 "\0\377\377\377\0LLL\377333\377\177\0\0\377\377\377\377\377fff\377\377"
224 "\0\0\377fff\377\377\377\377\377\177\0\0\377\377\377\377\0\377\377\377"
225 "\0\377\377\377\0\377\377\377\0""333\377333\377\177\0\0\377\377\0\0\377"
226 "\377\0\0\377\377\0\0\377\177\0\0\377\377\377\377\0\377\377\377\0\377"
227 "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
228 "\377\377\0\177\0\0\377\177\0\0\377\177\0\0\377\377\377\377\0\377\377"
229 "\377\0\377\377\377\0"};
232 static const guint8 icon_error[] =
233 { ""
234 /* Pixbuf magic (0x47646b50) */
235 "GdkP"
236 /* length: header (24) + pixel_data (672) */
237 "\0\0\2\270"
238 /* pixdata_type (0x1010002) */
239 "\1\1\0\2"
240 /* rowstride (48) */
241 "\0\0\0""0"
242 /* width (12) */
243 "\0\0\0\14"
244 /* height (14) */
245 "\0\0\0\16"
246 /* pixel_data: */
247 "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
248 "\0""333\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
249 "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377"
250 "\377\377\377\0\0\0\0\377\350\350\350\377333\377\377\377\377\0\377\377"
251 "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377"
252 "\350\350\350\377fff\377\0\0\0\377\350\350\350\377\350\350\350\377333"
253 "\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377"
254 "\350\350\350\377\350\350\350\377\350\350\350\377\0\0\0\377\350\350\350"
255 "\377\350\350\350\377\350\350\350\377333\377\377\377\377\0\377\377\377"
256 "\0\377\377\377\0""333\377\350\350\350\377\350\350\350\377\0\0\0\377\0"
257 "\0\0\377fff\377\350\350\350\377\350\350\350\377333\377\377\377\377\0"
258 "\377\377\377\0\377\377\377\0""333\377\350\350\350\377\350\350\350\377"
259 "\0\0\0\377\350\350\350\377\0\0\0\377\0\0\0\377\0\0\0\377333\377\377\377"
260 "\377\0\377\377\377\0\377\377\377\0""333\377\350\350\350\377\0\0\0\377"
261 "\350\350\350\377\0\0\0\377\350\350\350\377\350\350\350\377\350\350\350"
262 "\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""3"
263 "33\377\350\350\350\377\0\0\0\377\0\0\0\377\0\0\0\377\350\350\350\377"
264 "fff\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
265 "\377\0""333\377\0\0\0\377\350\350\350\377\350\350\350\377\350\350\350"
266 "\377\0\0\0\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
267 "\377\0\377\377\377\0\377\377\377\0""333\377\350\350\350\377\350\350\350"
268 "\377\350\350\350\377333\377\377\377\377\0\377\377\377\0\377\377\377\0"
269 "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0LLL\377\0\0\0"
270 "\377\0\0\0\377\0\0\0\377LLL\377\377\377\377\0\377\377\377\0\377\377\377"
271 "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0LLL\377\0\0"
272 "\0\377\0\0\0\377\0\0\0\377LLL\377\377\377\377\0\377\377\377\0\377\377"
273 "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
274 "\377\0\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377"
275 "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
276 "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
277 "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"};
280 static const guint8 icon_offline[] =
281 { ""
282 /* Pixbuf magic (0x47646b50) */
283 "GdkP"
284 /* length: header (24) + pixel_data (672) */
285 "\0\0\2\270"
286 /* pixdata_type (0x1010002) */
287 "\1\1\0\2"
288 /* rowstride (48) */
289 "\0\0\0""0"
290 /* width (12) */
291 "\0\0\0\14"
292 /* height (14) */
293 "\0\0\0\16"
294 /* pixel_data: */
295 "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377333"
296 "\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
297 "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377"
298 "\377\377\377\377\377\377\377\377\377\377333\377\377\377\377\0\377\377"
299 "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377"
300 "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
301 "\377\377\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
302 "\377\0""333\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
303 "\377\377\377\377\377\377\377\377\377\377\377\377\377\377333\377\377\377"
304 "\377\0\377\377\377\0\377\377\377\0""333\377\377\377\377\377\377\377\377"
305 "\377\0\0\0\377\377\377\377\377\0\0\0\377\377\377\377\377\377\377\377"
306 "\377333\377\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377"
307 "\377\377\377\377\377\377\0\0\0\377\377\377\377\377\0\0\0\377\377\377"
308 "\377\377\377\377\377\377333\377\377\377\377\0\377\377\377\0\377\377\377"
309 "\0""333\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377"
310 "\377\377\377\377\377\377\377\377\377\377\377\377333\377\377\377\377\0"
311 "\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\377\377\377"
312 "\377\377\377\0\0\0\377\377\377\377\377\377\377\377\377333\377\377\377"
313 "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377"
314 "\377\377\377\377\377\377\377\377\0\0\0\377\377\377\377\377\377\377\377"
315 "\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
316 "\377\377\0\377\377\377\0""333\377\377\377\377\377\377\377\377\377\377"
317 "\377\377\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
318 "\377\0\377\377\377\0\377\377\377\0\377\377\377\0LLL\377\0\0\0\377\0\0"
319 "\0\377\0\0\0\377LLL\377\377\377\377\0\377\377\377\0\377\377\377\0\377"
320 "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0LLL\377\0\0\0\377"
321 "\0\0\0\377\0\0\0\377LLL\377\377\377\377\0\377\377\377\0\377\377\377\0"
322 "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
323 "\0\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377\377"
324 "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
325 "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
326 "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"};
329 static const guint8 icon_xa[] =
330 { ""
331 /* Pixbuf magic (0x47646b50) */
332 "GdkP"
333 /* length: header (24) + pixel_data (672) */
334 "\0\0\2\270"
335 /* pixdata_type (0x1010002) */
336 "\1\1\0\2"
337 /* rowstride (48) */
338 "\0\0\0""0"
339 /* width (12) */
340 "\0\0\0\14"
341 /* height (14) */
342 "\0\0\0\16"
343 /* pixel_data: */
344 "\377\377\377\0\377\377\377\0\377\377\377\0\377\0\0\377333\377333\377"
345 "333\377\377\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
346 "\377\0\377\377\377\0\377\377\377\0\377\0\0\377333\377\377\377\0\377\377"
347 "\377\0\377\377\377\0\377333\377\377\0\0\377\377\377\377\0\377\377\377"
348 "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\0\0\377\377\377\0\377"
349 "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\0\0\377"
350 "\177\0\0\377\177\0\0\377\377\377\377\0\377\377\377\0""333\377\377\0\0"
351 "\377\377\377\0\377fff\377\377\377\0\377\177\0\0\377\177\0\0\377\377\0"
352 "\0\377\377\377\377\377\177\0\0\377\377\377\377\0\377\377\377\0""333\377"
353 "\377\0\0\377\177\0\0\377\177\0\0\377\177\0\0\377\377\377\377\377\377"
354 "\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\177\0\0\377\177\0\0"
355 "\377\177\0\0\377\377\0\0\377\377\377\377\377\377\377\377\377\377\377"
356 "\377\377\262\262\262\377\377\377\377\377\0\0\0\377\0\0\0\377\377\377"
357 "\377\377\177\0\0\377\177\0\0\377\377\377\377\377\262\262\262\377\0\0"
358 "\0\377\262\262\262\377\0\0\0\377\377\377\377\377\0\0\0\377\377\377\377"
359 "\377\262\262\262\377\0\0\0\377\177\0\0\377\177\0\0\377\377\377\377\377"
360 "\0\0\0\377\377\377\377\377\0\0\0\377\0\0\0\377\377\377\377\377\0\0\0"
361 "\377\0\0\0\377\377\377\377\377\0\0\0\377\177\0\0\377\177\0\0\377\377"
362 "\377\377\377\0\0\0\377\377\377\377\377\0\0\0\377\377\377\377\377\0\0"
363 "\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\177"
364 "\0\0\377\377\377\377\0\177\0\0\377\262\262\262\377\0\0\0\377\262\262"
365 "\262\377\377\377\377\377\377\377\377\377\377\377\377\377\177\0\0\377"
366 "\177\0\0\377\177\0\0\377\377\377\377\0\377\377\377\0\177\0\0\377\377"
367 "\377\377\377\377\377\377\377\177\0\0\377\177\0\0\377\177\0\0\377\177"
368 "\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
369 "\377\377\0\177\0\0\377\177\0\0\377\177\0\0\377333\377\0\0\0\377\0\0\0"
370 "\377LLL\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
371 "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377333\377"
372 "333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
373 "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
374 "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
375 "\377\0\377\377\377\0\377\377\377\0"};
378 //#########################################################################
379 //# R O S T E R
380 //#########################################################################
383 void Roster::doubleClickCallback(const Gtk::TreeModel::Path &path,
384 Gtk::TreeViewColumn *col)
385 {
386 Glib::RefPtr<Gtk::TreeModel> model = rosterView.get_model();
387 Glib::RefPtr<Gtk::TreeSelection> sel = rosterView.get_selection();
388 Gtk::TreeModel::iterator iter = sel->get_selected();
389 DOMString nick = iter->get_value(rosterColumns.userColumn);
390 //printf("Double clicked:%s\n", nick.c_str());
391 if (parent)
392 parent->doChat(nick);
394 }
396 void Roster::chatCallback()
397 {
398 Glib::RefPtr<Gtk::TreeModel> model = rosterView.get_model();
399 Glib::RefPtr<Gtk::TreeSelection> sel = rosterView.get_selection();
400 Gtk::TreeModel::iterator iter = sel->get_selected();
401 DOMString nick = iter->get_value(rosterColumns.userColumn);
402 //printf("Chat with:%s\n", nick.c_str());
403 if (parent)
404 parent->doChat(nick);
405 }
407 void Roster::sendFileCallback()
408 {
409 Glib::RefPtr<Gtk::TreeModel> model = rosterView.get_model();
410 Glib::RefPtr<Gtk::TreeSelection> sel = rosterView.get_selection();
411 Gtk::TreeModel::iterator iter = sel->get_selected();
412 DOMString nick = iter->get_value(rosterColumns.userColumn);
413 //printf("Send file to:%s\n", nick.c_str());
414 if (parent)
415 parent->doSendFile(nick);
416 }
418 void Roster::shareCallback()
419 {
420 Glib::RefPtr<Gtk::TreeModel> model = rosterView.get_model();
421 Glib::RefPtr<Gtk::TreeSelection> sel = rosterView.get_selection();
422 Gtk::TreeModel::iterator iter = sel->get_selected();
423 DOMString nick = iter->get_value(rosterColumns.userColumn);
424 //printf("share to:%s\n", nick.c_str());
425 if (parent)
426 parent->doShare(nick);
427 }
429 bool Roster::buttonPressCallback(GdkEventButton* event)
430 {
431 if( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) )
432 {
433 Gtk::Widget *wid = uiManager->get_widget("/PopupMenu");
434 Gtk::Menu *popupMenu = dynamic_cast<Gtk::Menu*>(wid);
435 popupMenu->popup(event->button, event->time);
436 return true;
437 }
438 else
439 return false;
440 }
442 bool Roster::doSetup()
443 {
444 set_size_request(200,200);
446 pixbuf_available = Gdk::Pixbuf::create_from_inline(
447 sizeof(icon_available), icon_available, false);
448 pixbuf_away = Gdk::Pixbuf::create_from_inline(
449 sizeof(icon_away), icon_away, false);
450 pixbuf_chat = Gdk::Pixbuf::create_from_inline(
451 sizeof(icon_chat), icon_chat, false);
452 pixbuf_dnd = Gdk::Pixbuf::create_from_inline(
453 sizeof(icon_dnd), icon_dnd, false);
454 pixbuf_error = Gdk::Pixbuf::create_from_inline(
455 sizeof(icon_error), icon_error, false);
456 pixbuf_offline = Gdk::Pixbuf::create_from_inline(
457 sizeof(icon_offline), icon_offline, false);
458 pixbuf_xa = Gdk::Pixbuf::create_from_inline(
459 sizeof(icon_xa), icon_xa, false);
461 rosterView.setParent(this);
462 treeStore = Gtk::TreeStore::create(rosterColumns);
463 rosterView.set_model(treeStore);
465 Gtk::CellRendererText *rend0 = new Gtk::CellRendererText();
466 //rend0->property_background() = "gray";
467 //rend0->property_foreground() = "black";
468 rosterView.append_column("Group", *rend0);
469 Gtk::TreeViewColumn *col0 = rosterView.get_column(0);
470 col0->add_attribute(*rend0, "text", 0);
472 Gtk::CellRendererPixbuf *rend1 = new Gtk::CellRendererPixbuf();
473 rosterView.append_column("Status", *rend1);
474 Gtk::TreeViewColumn *col1 = rosterView.get_column(1);
475 col1->add_attribute(*rend1, "pixbuf", 1);
477 Gtk::CellRendererText *rend2 = new Gtk::CellRendererText();
478 rosterView.append_column("Item", *rend2);
479 Gtk::TreeViewColumn *col2 = rosterView.get_column(2);
480 col2->add_attribute(*rend2, "text", 2);
482 Gtk::CellRendererText *rend3 = new Gtk::CellRendererText();
483 rosterView.append_column("Name", *rend3);
484 Gtk::TreeViewColumn *col3 = rosterView.get_column(3);
485 col3->add_attribute(*rend3, "text", 3);
487 Gtk::CellRendererText *rend4 = new Gtk::CellRendererText();
488 rosterView.append_column("Subscription", *rend4);
489 Gtk::TreeViewColumn *col4 = rosterView.get_column(4);
490 col4->add_attribute(*rend4, "text", 4);
492 rosterView.signal_row_activated().connect(
493 sigc::mem_fun(*this, &Roster::doubleClickCallback) );
495 add(rosterView);
496 set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS);
498 //##### POPUP MENU
499 Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
501 actionGroup->add( Gtk::Action::create("UserMenu", "_User Menu") );
503 actionGroup->add( Gtk::Action::create("Chat",
504 Gtk::Stock::CONNECT, "Chat"),
505 sigc::mem_fun(*this, &Roster::chatCallback) );
506 actionGroup->add( Gtk::Action::create("SendFile",
507 Gtk::Stock::CONNECT, "Send file"),
508 sigc::mem_fun(*this, &Roster::sendFileCallback) );
509 actionGroup->add( Gtk::Action::create("Share",
510 Gtk::Stock::CONNECT, "Share whiteboard"),
511 sigc::mem_fun(*this, &Roster::shareCallback) );
514 uiManager = Gtk::UIManager::create();
516 uiManager->insert_action_group(actionGroup, 0);
518 Glib::ustring ui_info =
519 "<ui>"
520 " <popup name='PopupMenu'>"
521 " <menuitem action='Chat'/>"
522 " <menuitem action='SendFile'/>"
523 " <menuitem action='Share'/>"
524 " </popup>"
525 "</ui>";
527 uiManager->add_ui_from_string(ui_info);
530 show_all_children();
532 return true;
533 }
536 /**
537 * Clear the roster
538 */
539 void Roster::clear()
540 {
541 treeStore->clear();
542 }
544 /**
545 * Regenerate the roster
546 */
547 void Roster::refresh()
548 {
549 if (!parent)
550 return;
551 treeStore->clear();
552 std::vector<XmppUser> items = parent->client.getRoster();
554 //## Add in tree fashion
555 DOMString lastGroup = "";
556 Gtk::TreeModel::Row row = *(treeStore->append());
557 row[rosterColumns.groupColumn] = "";
558 for (unsigned int i=0 ; i<items.size() ; i++)
559 {
560 XmppUser user = items[i];
561 if (user.group != lastGroup)
562 {
563 if (lastGroup.size()>0)
564 row = *(treeStore->append());
565 row[rosterColumns.groupColumn] = user.group;
566 lastGroup = user.group;
567 }
568 Glib::RefPtr<Gdk::Pixbuf> pb = pixbuf_offline;
569 if (user.show == "available")
570 pb = pixbuf_available;
571 else if (user.show == "away")
572 pb = pixbuf_away;
573 else if (user.show == "chat")
574 pb = pixbuf_chat;
575 else if (user.show == "dnd")
576 pb = pixbuf_dnd;
577 else if (user.show == "xa")
578 pb = pixbuf_xa;
579 else
580 {
581 //printf("Unknown show for %s:'%s'\n", user.c_str(), show.c_str());
582 }
583 Gtk::TreeModel::Row childRow = *(treeStore->append(row.children()));
584 childRow[rosterColumns.statusColumn] = pb;
585 childRow[rosterColumns.userColumn] = user.jid;
586 childRow[rosterColumns.nameColumn] = user.nick;
587 childRow[rosterColumns.subColumn] = user.subscription;
588 }
589 rosterView.expand_all();
590 }
592 //#########################################################################
593 //# M E S S A G E L I S T
594 //#########################################################################
596 bool MessageList::doSetup()
597 {
598 set_size_request(400,200);
600 messageListBuffer = Gtk::TextBuffer::create();
601 messageList.set_buffer(messageListBuffer);
602 messageList.set_editable(false);
603 messageList.set_wrap_mode(Gtk::WRAP_WORD_CHAR);
605 Glib::RefPtr<Gtk::TextBuffer::TagTable> table =
606 messageListBuffer->get_tag_table();
607 Glib::RefPtr<Gtk::TextBuffer::Tag> color0 =
608 Gtk::TextBuffer::Tag::create("color0");
609 color0->property_foreground() = "DarkGreen";
610 color0->property_weight() = Pango::WEIGHT_BOLD;
611 table->add(color0);
612 Glib::RefPtr<Gtk::TextBuffer::Tag> color1 =
613 Gtk::TextBuffer::Tag::create("color1");
614 color1->property_foreground() = "chocolate4";
615 color1->property_weight() = Pango::WEIGHT_BOLD;
616 table->add(color1);
617 Glib::RefPtr<Gtk::TextBuffer::Tag> color2 =
618 Gtk::TextBuffer::Tag::create("color2");
619 color2->property_foreground() = "red4";
620 color2->property_weight() = Pango::WEIGHT_BOLD;
621 table->add(color2);
622 Glib::RefPtr<Gtk::TextBuffer::Tag> color3 =
623 Gtk::TextBuffer::Tag::create("color3");
624 color3->property_foreground() = "MidnightBlue";
625 color3->property_weight() = Pango::WEIGHT_BOLD;
626 table->add(color3);
627 Glib::RefPtr<Gtk::TextBuffer::Tag> color4 =
628 Gtk::TextBuffer::Tag::create("color4");
629 color4->property_foreground() = "turquoise4";
630 color4->property_weight() = Pango::WEIGHT_BOLD;
631 table->add(color4);
632 Glib::RefPtr<Gtk::TextBuffer::Tag> color5 =
633 Gtk::TextBuffer::Tag::create("color5");
634 color5->property_foreground() = "OliveDrab";
635 color5->property_weight() = Pango::WEIGHT_BOLD;
636 table->add(color5);
637 Glib::RefPtr<Gtk::TextBuffer::Tag> color6 =
638 Gtk::TextBuffer::Tag::create("color6");
639 color6->property_foreground() = "purple4";
640 color6->property_weight() = Pango::WEIGHT_BOLD;
641 table->add(color6);
642 Glib::RefPtr<Gtk::TextBuffer::Tag> color7 =
643 Gtk::TextBuffer::Tag::create("color7");
644 color7->property_foreground() = "VioletRed4";
645 color7->property_weight() = Pango::WEIGHT_BOLD;
646 table->add(color7);
648 add(messageList);
649 set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS);
652 show_all_children();
654 return true;
655 }
657 /**
658 * Clear all messages from the list
659 */
660 void MessageList::clear()
661 {
662 messageListBuffer->erase(messageListBuffer->begin(),
663 messageListBuffer->end());
664 }
667 /**
668 * Post a message to the list
669 */
670 void MessageList::postMessage(const DOMString &from, const DOMString &msg)
671 {
672 DOMString out = "<";
673 out.append(from);
674 out.append("> ");
676 int val = 0;
677 for (unsigned int i=0 ; i<from.size() ; i++)
678 val += from[i];
679 val = val % 8;
681 char buf[16];
682 sprintf(buf, "color%d", val);
683 DOMString tagName = buf;
685 messageListBuffer->insert_with_tag(
686 messageListBuffer->end(), out, tagName);
687 messageListBuffer->insert(messageListBuffer->end(), msg);
688 messageListBuffer->insert(messageListBuffer->end(), "\n");
689 //Gtk::Adjustment *adj = get_vadjustment();
690 //adj->set_value(adj->get_upper()-adj->get_page_size());
691 Glib::RefPtr<Gtk::TextBuffer::Mark> mark =
692 messageListBuffer->create_mark("temp", messageListBuffer->end());
693 messageList.scroll_mark_onscreen(mark);
694 messageListBuffer->delete_mark(mark);
695 }
699 //#########################################################################
700 //# U S E R L I S T
701 //#########################################################################
702 void UserList::doubleClickCallback(const Gtk::TreeModel::Path &path,
703 Gtk::TreeViewColumn *col)
704 {
705 Glib::RefPtr<Gtk::TreeModel> model = userList.get_model();
706 Glib::RefPtr<Gtk::TreeSelection> sel = userList.get_selection();
707 Gtk::TreeModel::iterator iter = sel->get_selected();
708 DOMString nick = iter->get_value(userListColumns.userColumn);
709 //printf("Double clicked:%s\n", nick.c_str());
710 if (parent)
711 parent->doChat(nick);
713 }
715 void UserList::chatCallback()
716 {
717 Glib::RefPtr<Gtk::TreeModel> model = userList.get_model();
718 Glib::RefPtr<Gtk::TreeSelection> sel = userList.get_selection();
719 Gtk::TreeModel::iterator iter = sel->get_selected();
720 DOMString nick = iter->get_value(userListColumns.userColumn);
721 //printf("Chat with:%s\n", nick.c_str());
722 if (parent)
723 parent->doChat(nick);
724 }
726 void UserList::sendFileCallback()
727 {
728 Glib::RefPtr<Gtk::TreeModel> model = userList.get_model();
729 Glib::RefPtr<Gtk::TreeSelection> sel = userList.get_selection();
730 Gtk::TreeModel::iterator iter = sel->get_selected();
731 DOMString nick = iter->get_value(userListColumns.userColumn);
732 //printf("Send file to:%s\n", nick.c_str());
733 if (parent)
734 parent->doSendFile(nick);
735 }
737 void UserList::shareCallback()
738 {
739 Glib::RefPtr<Gtk::TreeModel> model = userList.get_model();
740 Glib::RefPtr<Gtk::TreeSelection> sel = userList.get_selection();
741 Gtk::TreeModel::iterator iter = sel->get_selected();
742 DOMString nick = iter->get_value(userListColumns.userColumn);
743 //printf("Send file to:%s\n", nick.c_str());
744 if (parent)
745 parent->doShare(nick);
746 }
748 bool UserList::buttonPressCallback(GdkEventButton* event)
749 {
750 if( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) )
751 {
752 Gtk::Widget *wid = uiManager->get_widget("/PopupMenu");
753 Gtk::Menu *popupMenu = dynamic_cast<Gtk::Menu*>(wid);
754 popupMenu->popup(event->button, event->time);
755 return true;
756 }
757 else
758 return false;
759 }
761 bool UserList::doSetup()
762 {
763 set_size_request(200,200);
765 setParent(NULL);
767 pixbuf_available = Gdk::Pixbuf::create_from_inline(
768 sizeof(icon_available), icon_available, false);
769 pixbuf_away = Gdk::Pixbuf::create_from_inline(
770 sizeof(icon_away), icon_away, false);
771 pixbuf_chat = Gdk::Pixbuf::create_from_inline(
772 sizeof(icon_chat), icon_chat, false);
773 pixbuf_dnd = Gdk::Pixbuf::create_from_inline(
774 sizeof(icon_dnd), icon_dnd, false);
775 pixbuf_error = Gdk::Pixbuf::create_from_inline(
776 sizeof(icon_error), icon_error, false);
777 pixbuf_offline = Gdk::Pixbuf::create_from_inline(
778 sizeof(icon_offline), icon_offline, false);
779 pixbuf_xa = Gdk::Pixbuf::create_from_inline(
780 sizeof(icon_xa), icon_xa, false);
782 userList.setParent(this);
783 userListStore = Gtk::ListStore::create(userListColumns);
784 userList.set_model(userListStore);
786 Gtk::CellRendererPixbuf *rend0 = new Gtk::CellRendererPixbuf();
787 userList.append_column("Status", *rend0);
788 Gtk::TreeViewColumn *col0 = userList.get_column(0);
789 col0->add_attribute(*rend0, "pixbuf", 0);
791 Gtk::CellRendererText *rend1 = new Gtk::CellRendererText();
792 //rend1->property_background() = "gray";
793 //rend1->property_foreground() = "black";
794 userList.append_column("User", *rend1);
795 Gtk::TreeViewColumn *col1 = userList.get_column(1);
796 col1->add_attribute(*rend1, "text", 1);
798 userList.set_headers_visible(false);
800 userList.signal_row_activated().connect(
801 sigc::mem_fun(*this, &UserList::doubleClickCallback) );
803 add(userList);
804 set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS);
806 //##### POPUP MENU
807 Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
809 actionGroup->add( Gtk::Action::create("UserMenu", "_User Menu") );
811 actionGroup->add( Gtk::Action::create("Chat",
812 Gtk::Stock::CONNECT, "Chat"),
813 sigc::mem_fun(*this, &UserList::chatCallback) );
814 actionGroup->add( Gtk::Action::create("SendFile",
815 Gtk::Stock::CONNECT, "Send file"),
816 sigc::mem_fun(*this, &UserList::sendFileCallback) );
817 actionGroup->add( Gtk::Action::create("Share",
818 Gtk::Stock::CONNECT, "Share whiteboard"),
819 sigc::mem_fun(*this, &UserList::shareCallback) );
822 uiManager = Gtk::UIManager::create();
824 uiManager->insert_action_group(actionGroup, 0);
826 Glib::ustring ui_info =
827 "<ui>"
828 " <popup name='PopupMenu'>"
829 " <menuitem action='Chat'/>"
830 " <menuitem action='SendFile'/>"
831 " <menuitem action='Share'/>"
832 " </popup>"
833 "</ui>";
835 uiManager->add_ui_from_string(ui_info);
837 show_all_children();
839 return true;
840 }
842 /**
843 * Clear all messages from the list
844 */
845 void UserList::clear()
846 {
847 userListStore->clear();
848 }
851 /**
852 * Add a user to the list
853 */
854 void UserList::addUser(const DOMString &user, const DOMString &show)
855 {
856 Glib::RefPtr<Gdk::Pixbuf> pb = pixbuf_offline;
857 if (show == "available")
858 pb = pixbuf_available;
859 else if (show == "away")
860 pb = pixbuf_away;
861 else if (show == "chat")
862 pb = pixbuf_chat;
863 else if (show == "dnd")
864 pb = pixbuf_dnd;
865 else if (show == "xa")
866 pb = pixbuf_xa;
867 else
868 {
869 //printf("Unknown show for %s:'%s'\n", user.c_str(), show.c_str());
870 }
871 Gtk::TreeModel::Row row = *(userListStore->append());
872 row[userListColumns.userColumn] = user;
873 row[userListColumns.statusColumn] = pb;
874 }
879 //#########################################################################
880 //# C H A T W I N D O W
881 //#########################################################################
882 ChatWindow::ChatWindow(PedroGui &par, const DOMString jidArg)
883 : parent(par)
884 {
885 jid = jidArg;
886 doSetup();
887 }
889 ChatWindow::~ChatWindow()
890 {
891 }
893 void ChatWindow::leaveCallback()
894 {
895 hide();
896 parent.chatDelete(jid);
897 }
900 void ChatWindow::hideCallback()
901 {
902 hide();
903 parent.chatDelete(jid);
904 }
906 void ChatWindow::shareCallback()
907 {
908 // hide();
909 parent.doShare(this->jid);
910 }
912 void ChatWindow::textEnterCallback()
913 {
914 DOMString str = inputTxt.get_text();
915 if (str.size() > 0)
916 parent.client.message(jid, str);
917 inputTxt.set_text("");
918 messageList.postMessage(parent.client.getJid(), str);
919 }
921 bool ChatWindow::doSetup()
922 {
923 DOMString title = "Private Chat - ";
924 title.append(jid);
925 set_title(title);
927 set_size_request(500,300);
929 signal_hide().connect(
930 sigc::mem_fun(*this, &ChatWindow::hideCallback) );
932 Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
933 actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
934 actionGroup->add( Gtk::Action::create("Leave", Gtk::Stock::CANCEL),
935 sigc::mem_fun(*this, &ChatWindow::leaveCallback) );
936 actionGroup->add( Gtk::Action::create("Share", Gtk::Stock::CONNECT,
937 "Share whiteboard"), sigc::mem_fun(*this, &ChatWindow::shareCallback) );
940 Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
942 uiManager->insert_action_group(actionGroup, 0);
943 add_accel_group(uiManager->get_accel_group());
945 Glib::ustring ui_info =
946 "<ui>"
947 " <menubar name='MenuBar'>"
948 " <menu action='MenuFile'>"
949 " <menuitem action='Leave'/>"
950 " <menuitem action='Share'/>"
951 " </menu>"
952 " </menubar>"
953 "</ui>";
955 add(vbox);
957 uiManager->add_ui_from_string(ui_info);
958 Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
959 vbox.pack_start(*pMenuBar, Gtk::PACK_SHRINK);
961 vbox.pack_end(vPaned);
963 vPaned.add1(messageList);
964 vPaned.add2(inputTxt);
966 inputTxt.signal_activate().connect(
967 sigc::mem_fun(*this, &ChatWindow::textEnterCallback) );
969 show_all_children();
971 return true;
972 }
974 bool ChatWindow::postMessage(const DOMString &data)
975 {
976 messageList.postMessage(jid, data);
977 return true;
978 }
980 //#########################################################################
981 //# G R O U P C H A T W I N D O W
982 //#########################################################################
984 GroupChatWindow::GroupChatWindow(PedroGui &par,
985 const DOMString &groupJidArg,
986 const DOMString &nickArg)
987 : parent(par)
988 {
989 groupJid = groupJidArg;
990 nick = nickArg;
991 doSetup();
992 }
994 GroupChatWindow::~GroupChatWindow()
995 {
996 }
999 void GroupChatWindow::leaveCallback()
1000 {
1001 parent.client.groupChatLeave(groupJid, nick);
1002 hide();
1003 parent.groupChatDelete(groupJid, nick);
1004 }
1006 void GroupChatWindow::hideCallback()
1007 {
1008 parent.client.groupChatLeave(groupJid, nick);
1009 hide();
1010 parent.groupChatDelete(groupJid, nick);
1011 }
1013 void GroupChatWindow::textEnterCallback()
1014 {
1015 DOMString str = inputTxt.get_text();
1016 if (str.size() > 0)
1017 parent.client.groupChatMessage(groupJid, str);
1018 inputTxt.set_text("");
1019 }
1021 void GroupChatWindow::shareCallback()
1022 {
1023 parent.doGroupShare(groupJid);
1024 }
1026 bool GroupChatWindow::doSetup()
1027 {
1028 DOMString title = "Group Chat - ";
1029 title.append(groupJid);
1030 set_title(title);
1032 userList.setParent(this);
1034 set_size_request(500,300);
1036 signal_hide().connect(
1037 sigc::mem_fun(*this, &GroupChatWindow::hideCallback) );
1039 Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
1040 actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
1041 actionGroup->add( Gtk::Action::create("Leave", Gtk::Stock::CANCEL),
1042 sigc::mem_fun(*this, &GroupChatWindow::leaveCallback) );
1043 actionGroup->add( Gtk::Action::create("Share", Gtk::Stock::CONNECT, "Share whiteboard"),
1044 sigc::mem_fun(*this, &GroupChatWindow::shareCallback) );
1047 Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
1049 uiManager->insert_action_group(actionGroup, 0);
1050 add_accel_group(uiManager->get_accel_group());
1052 Glib::ustring ui_info =
1053 "<ui>"
1054 " <menubar name='MenuBar'>"
1055 " <menu action='MenuFile'>"
1056 " <menuitem action='Leave'/>"
1057 " <menuitem action='Share'/>"
1058 " </menu>"
1059 " </menubar>"
1060 "</ui>";
1062 add(vbox);
1063 uiManager->add_ui_from_string(ui_info);
1064 Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
1065 vbox.pack_start(*pMenuBar, Gtk::PACK_SHRINK);
1067 vbox.pack_end(vPaned);
1069 vPaned.add1(hPaned);
1070 vPaned.add2(inputTxt);
1071 inputTxt.signal_activate().connect(
1072 sigc::mem_fun(*this, &GroupChatWindow::textEnterCallback) );
1075 hPaned.add1(messageList);
1076 hPaned.add2(userList);
1079 show_all_children();
1082 return true;
1083 }
1085 bool GroupChatWindow::receiveMessage(const DOMString &from,
1086 const DOMString &data)
1087 {
1088 messageList.postMessage(from, data);
1089 return true;
1090 }
1092 bool GroupChatWindow::receivePresence(const DOMString &fromNick,
1093 bool presence,
1094 const DOMString &show,
1095 const DOMString &status)
1096 {
1098 DOMString presStr = "";
1099 presStr.append(fromNick);
1100 if (!presence)
1101 presStr.append(" left the group");
1102 else
1103 {
1104 if (show.size()<1)
1105 presStr.append(" joined the group");
1106 else
1107 {
1108 presStr.append(" : ");
1109 presStr.append(show);
1110 }
1111 }
1113 if (presStr != "xa")
1114 messageList.postMessage("*", presStr);
1116 userList.clear();
1117 std::vector<XmppUser> memberList =
1118 parent.client.groupChatGetUserList(groupJid);
1119 for (unsigned int i=0 ; i<memberList.size() ; i++)
1120 {
1121 XmppUser user = memberList[i];
1122 userList.addUser(user.nick, user.show);
1123 }
1124 return true;
1125 }
1128 void GroupChatWindow::doChat(const DOMString &nick)
1129 {
1130 printf("##Chat with %s\n", nick.c_str());
1131 DOMString fullJid = groupJid;
1132 fullJid.append("/");
1133 fullJid.append(nick);
1134 parent.doChat(fullJid);
1135 }
1137 void GroupChatWindow::doSendFile(const DOMString &nick)
1138 {
1139 printf("##Send file to %s\n", nick.c_str());
1140 DOMString fullJid = groupJid;
1141 fullJid.append("/");
1142 fullJid.append(nick);
1143 parent.doSendFile(fullJid);
1145 }
1147 void GroupChatWindow::doShare(const DOMString &nick)
1148 {
1149 printf("##Share inkboard with %s\n", nick.c_str());
1150 DOMString fullJid = groupJid;
1151 fullJid.append("/");
1152 fullJid.append(nick);
1153 parent.doShare(fullJid);
1155 }
1158 //#########################################################################
1159 //# C O N F I G D I A L O G
1160 //#########################################################################
1163 void ConfigDialog::okCallback()
1164 {
1165 Glib::ustring pass = passField.get_text();
1166 Glib::ustring newpass = newField.get_text();
1167 Glib::ustring confpass = confField.get_text();
1168 if ((pass.size() < 5 || pass.size() > 12 ) ||
1169 (newpass.size() < 5 || newpass.size() > 12 ) ||
1170 (confpass.size() < 5 || confpass.size()> 12 ))
1171 {
1172 Gtk::MessageDialog dlg(*this, "Password must be 5 to 12 characters",
1173 false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
1174 dlg.run();
1175 }
1176 else if (newpass != confpass)
1177 {
1178 Gtk::MessageDialog dlg(*this, "New password and confirmation do not match",
1179 false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
1180 dlg.run();
1181 }
1182 else
1183 {
1184 //response(Gtk::RESPONSE_OK);
1185 hide();
1186 }
1187 }
1189 void ConfigDialog::cancelCallback()
1190 {
1191 //response(Gtk::RESPONSE_CANCEL);
1192 hide();
1193 }
1195 void ConfigDialog::on_response(int response_id)
1196 {
1197 if (response_id == Gtk::RESPONSE_OK)
1198 okCallback();
1199 else
1200 cancelCallback();
1201 }
1203 bool ConfigDialog::doSetup()
1204 {
1205 set_title("Change Password");
1206 set_size_request(300,200);
1208 Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
1209 actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
1210 actionGroup->add( Gtk::Action::create("Change", Gtk::Stock::OK, "Change Password"),
1211 sigc::mem_fun(*this, &ConfigDialog::okCallback) );
1212 actionGroup->add( Gtk::Action::create("Cancel", Gtk::Stock::CANCEL, "Cancel"),
1213 sigc::mem_fun(*this, &ConfigDialog::cancelCallback) );
1216 Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
1218 uiManager->insert_action_group(actionGroup, 0);
1219 add_accel_group(uiManager->get_accel_group());
1221 Glib::ustring ui_info =
1222 "<ui>"
1223 " <menubar name='MenuBar'>"
1224 " <menu action='MenuFile'>"
1225 " <menuitem action='Change'/>"
1226 " <separator/>"
1227 " <menuitem action='Cancel'/>"
1228 " </menu>"
1229 " </menubar>"
1230 "</ui>";
1232 uiManager->add_ui_from_string(ui_info);
1233 Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
1234 get_vbox()->pack_start(*pMenuBar, Gtk::PACK_SHRINK);
1236 table.resize(3, 2);
1237 get_vbox()->pack_start(table);
1239 passLabel.set_text("Current Password");
1240 table.attach(passLabel, 0, 1, 0, 1);
1241 passField.set_visibility(false);
1242 passField.set_text(parent.client.getPassword());
1243 table.attach(passField, 1, 2, 0, 1);
1245 newLabel.set_text("New Password");
1246 table.attach(newLabel, 0, 1, 1, 2);
1247 newField.set_visibility(false);
1248 table.attach(newField, 1, 2, 1, 2);
1250 confLabel.set_text("Confirm New Password");
1251 table.attach(confLabel, 0, 1, 2, 3);
1252 confField.set_visibility(false);
1253 confField.signal_activate().connect(
1254 sigc::mem_fun(*this, &ConfigDialog::okCallback) );
1255 table.attach(confField, 1, 2, 2, 3);
1257 add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1258 add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
1260 show_all_children();
1262 return true;
1263 }
1265 //#########################################################################
1266 //# P A S S W O R D D I A L O G
1267 //#########################################################################
1270 void PasswordDialog::okCallback()
1271 {
1272 Glib::ustring pass = passField.get_text();
1273 Glib::ustring newpass = newField.get_text();
1274 Glib::ustring confpass = confField.get_text();
1275 if ((pass.size() < 5 || pass.size() > 12 ) ||
1276 (newpass.size() < 5 || newpass.size() > 12 ) ||
1277 (confpass.size() < 5 || confpass.size()> 12 ))
1278 {
1279 Gtk::MessageDialog dlg(*this, "Password must be 5 to 12 characters",
1280 false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
1281 dlg.run();
1282 }
1283 else if (newpass != confpass)
1284 {
1285 Gtk::MessageDialog dlg(*this, "New password and confirmation do not match",
1286 false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
1287 dlg.run();
1288 }
1289 else
1290 {
1291 //response(Gtk::RESPONSE_OK);
1292 hide();
1293 }
1294 }
1296 void PasswordDialog::cancelCallback()
1297 {
1298 //response(Gtk::RESPONSE_CANCEL);
1299 hide();
1300 }
1302 void PasswordDialog::on_response(int response_id)
1303 {
1304 if (response_id == Gtk::RESPONSE_OK)
1305 okCallback();
1306 else
1307 cancelCallback();
1308 }
1310 bool PasswordDialog::doSetup()
1311 {
1312 set_title("Change Password");
1313 set_size_request(300,200);
1315 Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
1316 actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
1317 actionGroup->add( Gtk::Action::create("Change", Gtk::Stock::OK, "Change Password"),
1318 sigc::mem_fun(*this, &PasswordDialog::okCallback) );
1319 actionGroup->add( Gtk::Action::create("Cancel", Gtk::Stock::CANCEL, "Cancel"),
1320 sigc::mem_fun(*this, &PasswordDialog::cancelCallback) );
1323 Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
1325 uiManager->insert_action_group(actionGroup, 0);
1326 add_accel_group(uiManager->get_accel_group());
1328 Glib::ustring ui_info =
1329 "<ui>"
1330 " <menubar name='MenuBar'>"
1331 " <menu action='MenuFile'>"
1332 " <menuitem action='Change'/>"
1333 " <separator/>"
1334 " <menuitem action='Cancel'/>"
1335 " </menu>"
1336 " </menubar>"
1337 "</ui>";
1339 uiManager->add_ui_from_string(ui_info);
1340 Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
1341 get_vbox()->pack_start(*pMenuBar, Gtk::PACK_SHRINK);
1343 table.resize(3, 2);
1344 get_vbox()->pack_start(table);
1346 passLabel.set_text("Current Password");
1347 table.attach(passLabel, 0, 1, 0, 1);
1348 passField.set_visibility(false);
1349 passField.set_text(parent.client.getPassword());
1350 table.attach(passField, 1, 2, 0, 1);
1352 newLabel.set_text("New Password");
1353 table.attach(newLabel, 0, 1, 1, 2);
1354 newField.set_visibility(false);
1355 table.attach(newField, 1, 2, 1, 2);
1357 confLabel.set_text("Confirm New Password");
1358 table.attach(confLabel, 0, 1, 2, 3);
1359 confField.set_visibility(false);
1360 confField.signal_activate().connect(
1361 sigc::mem_fun(*this, &PasswordDialog::okCallback) );
1362 table.attach(confField, 1, 2, 2, 3);
1364 add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1365 add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
1367 show_all_children();
1369 return true;
1370 }
1372 //#########################################################################
1373 //# C H A T D I A L O G
1374 //#########################################################################
1377 void ChatDialog::okCallback()
1378 {
1379 response(Gtk::RESPONSE_OK);
1380 hide();
1381 }
1383 void ChatDialog::cancelCallback()
1384 {
1385 response(Gtk::RESPONSE_CANCEL);
1386 hide();
1387 }
1390 bool ChatDialog::doSetup()
1391 {
1392 set_title("Chat with User");
1393 set_size_request(300,200);
1395 Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
1396 actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
1397 actionGroup->add( Gtk::Action::create("Chat", Gtk::Stock::CONNECT, "Chat"),
1398 sigc::mem_fun(*this, &ChatDialog::okCallback) );
1399 actionGroup->add( Gtk::Action::create("Cancel", Gtk::Stock::CANCEL, "Cancel"),
1400 sigc::mem_fun(*this, &ChatDialog::cancelCallback) );
1403 Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
1405 uiManager->insert_action_group(actionGroup, 0);
1406 add_accel_group(uiManager->get_accel_group());
1408 Glib::ustring ui_info =
1409 "<ui>"
1410 " <menubar name='MenuBar'>"
1411 " <menu action='MenuFile'>"
1412 " <menuitem action='Chat'/>"
1413 " <separator/>"
1414 " <menuitem action='Cancel'/>"
1415 " </menu>"
1416 " </menubar>"
1417 "</ui>";
1419 uiManager->add_ui_from_string(ui_info);
1420 Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
1421 get_vbox()->pack_start(*pMenuBar, Gtk::PACK_SHRINK);
1423 table.resize(2, 2);
1424 get_vbox()->pack_start(table);
1426 userLabel.set_text("User");
1427 table.attach(userLabel, 0, 1, 0, 1);
1428 //userField.set_text("");
1429 table.attach(userField, 1, 2, 0, 1);
1431 //userField.set_text("");
1432 table.attach(textField, 0, 2, 1, 2);
1434 add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1435 add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
1437 show_all_children();
1439 return true;
1440 }
1442 //#########################################################################
1443 //# G R O U P C H A T D I A L O G
1444 //#########################################################################
1447 void GroupChatDialog::okCallback()
1448 {
1449 response(Gtk::RESPONSE_OK);
1450 hide();
1451 }
1453 void GroupChatDialog::cancelCallback()
1454 {
1455 response(Gtk::RESPONSE_CANCEL);
1456 hide();
1457 }
1460 bool GroupChatDialog::doSetup()
1461 {
1462 set_title("Join Group Chat");
1463 set_size_request(300,200);
1465 Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
1466 actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
1467 actionGroup->add( Gtk::Action::create("Join", Gtk::Stock::CONNECT, "Join Group"),
1468 sigc::mem_fun(*this, &GroupChatDialog::okCallback) );
1469 actionGroup->add( Gtk::Action::create("Cancel", Gtk::Stock::CANCEL, "Cancel"),
1470 sigc::mem_fun(*this, &GroupChatDialog::cancelCallback) );
1473 Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
1475 uiManager->insert_action_group(actionGroup, 0);
1476 add_accel_group(uiManager->get_accel_group());
1478 Glib::ustring ui_info =
1479 "<ui>"
1480 " <menubar name='MenuBar'>"
1481 " <menu action='MenuFile'>"
1482 " <menuitem action='Join'/>"
1483 " <separator/>"
1484 " <menuitem action='Cancel'/>"
1485 " </menu>"
1486 " </menubar>"
1487 "</ui>";
1489 uiManager->add_ui_from_string(ui_info);
1490 Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
1491 get_vbox()->pack_start(*pMenuBar, Gtk::PACK_SHRINK);
1493 table.resize(4, 2);
1494 get_vbox()->pack_start(table);
1496 groupLabel.set_text("Group");
1497 table.attach(groupLabel, 0, 1, 0, 1);
1498 groupField.set_text(parent.config.getMucGroup());
1499 table.attach(groupField, 1, 2, 0, 1);
1501 hostLabel.set_text("Host");
1502 table.attach(hostLabel, 0, 1, 1, 2);
1503 hostField.set_text(parent.config.getMucHost());
1504 table.attach(hostField, 1, 2, 1, 2);
1506 nickLabel.set_text("Alt Name");
1507 table.attach(nickLabel, 0, 1, 2, 3);
1508 nickField.set_text(parent.config.getMucNick());
1509 table.attach(nickField, 1, 2, 2, 3);
1511 passLabel.set_text("Password");
1512 table.attach(passLabel, 0, 1, 3, 4);
1513 passField.set_visibility(false);
1514 passField.set_text(parent.config.getMucPassword());
1515 table.attach(passField, 1, 2, 3, 4);
1518 add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1519 add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
1521 show_all_children();
1523 return true;
1524 }
1529 //#########################################################################
1530 //# C O N N E C T D I A L O G
1531 //#########################################################################
1534 void ConnectDialog::okCallback()
1535 {
1536 response(Gtk::RESPONSE_OK);
1537 hide();
1538 }
1540 void ConnectDialog::saveCallback()
1541 {
1542 Gtk::Entry txtField;
1543 Gtk::Dialog dlg("Account name", *this, true, true);
1544 dlg.get_vbox()->pack_start(txtField);
1545 txtField.signal_activate().connect(
1546 sigc::bind(sigc::mem_fun(dlg, &Gtk::Dialog::response),
1547 Gtk::RESPONSE_OK ));
1548 dlg.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1549 dlg.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
1550 dlg.show_all_children();
1551 int ret = dlg.run();
1552 if (ret != Gtk::RESPONSE_OK)
1553 return;
1555 Glib::ustring name = txtField.get_text();
1556 if (name.size() < 1)
1557 {
1558 parent.error("Account name too short");
1559 return;
1560 }
1562 if (parent.config.accountExists(name))
1563 {
1564 parent.config.accountRemove(name);
1565 }
1567 XmppAccount account;
1568 account.setName(name);
1569 account.setHost(getHost());
1570 account.setPort(getPort());
1571 account.setUsername(getUser());
1572 account.setPassword(getPass());
1573 parent.config.accountAdd(account);
1575 refresh();
1577 parent.configSave();
1578 }
1580 void ConnectDialog::cancelCallback()
1581 {
1582 response(Gtk::RESPONSE_CANCEL);
1583 hide();
1584 }
1587 void ConnectDialog::doubleClickCallback(
1588 const Gtk::TreeModel::Path &path,
1589 Gtk::TreeViewColumn *col)
1590 {
1591 Glib::RefPtr<Gtk::TreeModel> model = accountView.get_model();
1592 Glib::RefPtr<Gtk::TreeSelection> sel = accountView.get_selection();
1593 Gtk::TreeModel::iterator iter = sel->get_selected();
1594 DOMString name = iter->get_value(accountColumns.nameColumn);
1595 //printf("Double clicked:%s\n", name.c_str());
1596 XmppAccount account;
1597 if (!parent.config.accountFind(name, account))
1598 return;
1599 setHost(account.getHost());
1600 setPort(account.getPort());
1601 setUser(account.getUsername());
1602 setPass(account.getPassword());
1604 response(Gtk::RESPONSE_OK);
1605 hide();
1606 }
1608 void ConnectDialog::selectedCallback()
1609 {
1610 Glib::RefPtr<Gtk::TreeModel> model = accountView.get_model();
1611 Glib::RefPtr<Gtk::TreeSelection> sel = accountView.get_selection();
1612 Gtk::TreeModel::iterator iter = sel->get_selected();
1613 DOMString name = iter->get_value(accountColumns.nameColumn);
1614 //printf("Single clicked:%s\n", name.c_str());
1615 XmppAccount account;
1616 if (!parent.config.accountFind(name, account))
1617 return;
1618 setHost(account.getHost());
1619 setPort(account.getPort());
1620 setUser(account.getUsername());
1621 setPass(account.getPassword());
1622 }
1624 void ConnectDialog::deleteCallback()
1625 {
1626 Glib::RefPtr<Gtk::TreeModel> model = accountView.get_model();
1627 Glib::RefPtr<Gtk::TreeSelection> sel = accountView.get_selection();
1628 Gtk::TreeModel::iterator iter = sel->get_selected();
1629 DOMString name = iter->get_value(accountColumns.nameColumn);
1631 parent.config.accountRemove(name);
1632 refresh();
1633 parent.configSave();
1635 }
1639 void ConnectDialog::buttonPressCallback(GdkEventButton* event)
1640 {
1641 if( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) )
1642 {
1643 Gtk::Widget *wid = accountUiManager->get_widget("/PopupMenu");
1644 Gtk::Menu *popupMenu = dynamic_cast<Gtk::Menu*>(wid);
1645 popupMenu->popup(event->button, event->time);
1646 }
1647 }
1650 bool ConnectDialog::doSetup()
1651 {
1652 set_title("Connect");
1653 set_size_request(300,400);
1655 Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
1656 actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
1657 actionGroup->add( Gtk::Action::create("Connect",
1658 Gtk::Stock::CONNECT, "Connect"),
1659 sigc::mem_fun(*this, &ConnectDialog::okCallback) );
1660 actionGroup->add( Gtk::Action::create("Save",
1661 Gtk::Stock::CONNECT, "Save as account"),
1662 sigc::mem_fun(*this, &ConnectDialog::saveCallback) );
1663 actionGroup->add( Gtk::Action::create("Cancel",
1664 Gtk::Stock::CANCEL, "Cancel"),
1665 sigc::mem_fun(*this, &ConnectDialog::cancelCallback) );
1668 Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
1670 uiManager->insert_action_group(actionGroup, 0);
1671 add_accel_group(uiManager->get_accel_group());
1673 Glib::ustring ui_info =
1674 "<ui>"
1675 " <menubar name='MenuBar'>"
1676 " <menu action='MenuFile'>"
1677 " <menuitem action='Connect'/>"
1678 " <separator/>"
1679 " <menuitem action='Save'/>"
1680 " <separator/>"
1681 " <menuitem action='Cancel'/>"
1682 " </menu>"
1683 " </menubar>"
1684 "</ui>";
1686 uiManager->add_ui_from_string(ui_info);
1687 Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
1688 get_vbox()->pack_start(*pMenuBar, Gtk::PACK_SHRINK);
1690 table.resize(6, 2);
1691 get_vbox()->pack_start(table);
1693 parent.client.setHost("broadway.dynalias.com");
1694 parent.client.setPort(5222);
1695 parent.client.setUsername("");
1696 parent.client.setPassword("");
1697 parent.client.setResource("pedroXmpp");
1699 hostLabel.set_text("Host");
1700 table.attach(hostLabel, 0, 1, 0, 1);
1701 hostField.set_text(parent.client.getHost());
1702 table.attach(hostField, 1, 2, 0, 1);
1704 portLabel.set_text("Port");
1705 table.attach(portLabel, 0, 1, 1, 2);
1706 portSpinner.set_digits(0);
1707 portSpinner.set_range(1, 65000);
1708 portSpinner.set_value(parent.client.getPort());
1709 table.attach(portSpinner, 1, 2, 1, 2);
1711 userLabel.set_text("Username");
1712 table.attach(userLabel, 0, 1, 2, 3);
1713 userField.set_text(parent.client.getUsername());
1714 table.attach(userField, 1, 2, 2, 3);
1716 passLabel.set_text("Password");
1717 table.attach(passLabel, 0, 1, 3, 4);
1718 passField.set_visibility(false);
1719 passField.set_text(parent.client.getPassword());
1720 passField.signal_activate().connect(
1721 sigc::mem_fun(*this, &ConnectDialog::okCallback) );
1722 table.attach(passField, 1, 2, 3, 4);
1724 resourceLabel.set_text("Resource");
1725 table.attach(resourceLabel, 0, 1, 4, 5);
1726 resourceField.set_text(parent.client.getResource());
1727 table.attach(resourceField, 1, 2, 4, 5);
1729 registerLabel.set_text("Register");
1730 table.attach(registerLabel, 0, 1, 5, 6);
1731 registerButton.set_active(false);
1732 table.attach(registerButton, 1, 2, 5, 6);
1734 add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1735 add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
1738 //######################
1739 //# ACCOUNT LIST
1740 //######################
1743 accountListStore = Gtk::ListStore::create(accountColumns);
1744 accountView.set_model(accountListStore);
1746 accountView.signal_row_activated().connect(
1747 sigc::mem_fun(*this, &ConnectDialog::doubleClickCallback) );
1749 accountView.get_selection()->signal_changed().connect(
1750 sigc::mem_fun(*this, &ConnectDialog::selectedCallback) );
1752 accountView.append_column("Account", accountColumns.nameColumn);
1753 accountView.append_column("Host", accountColumns.hostColumn);
1755 //accountView.signal_row_activated().connect(
1756 // sigc::mem_fun(*this, &AccountDialog::connectCallback) );
1758 accountScroll.add(accountView);
1759 accountScroll.set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS);
1761 get_vbox()->pack_start(accountScroll);
1763 //##### POPUP MENU
1764 accountView.signal_button_press_event().connect_notify(
1765 sigc::mem_fun(*this, &ConnectDialog::buttonPressCallback) );
1767 Glib::RefPtr<Gtk::ActionGroup> accountActionGroup =
1768 Gtk::ActionGroup::create();
1770 accountActionGroup->add( Gtk::Action::create("PopupMenu", "_Account") );
1772 accountActionGroup->add( Gtk::Action::create("Delete",
1773 Gtk::Stock::DELETE, "Delete"),
1774 sigc::mem_fun(*this, &ConnectDialog::deleteCallback) );
1777 accountUiManager = Gtk::UIManager::create();
1779 accountUiManager->insert_action_group(accountActionGroup, 0);
1781 Glib::ustring account_ui_info =
1782 "<ui>"
1783 " <popup name='PopupMenu'>"
1784 " <menuitem action='Delete'/>"
1785 " </popup>"
1786 "</ui>";
1788 accountUiManager->add_ui_from_string(account_ui_info);
1789 //Gtk::Widget* accountMenuBar = uiManager->get_widget("/PopupMenu");
1790 //get_vbox()->pack_start(*accountMenuBar, Gtk::PACK_SHRINK);
1792 refresh();
1794 show_all_children();
1796 return true;
1797 }
1800 /**
1801 * Regenerate the account list
1802 */
1803 void ConnectDialog::refresh()
1804 {
1805 accountListStore->clear();
1807 std::vector<XmppAccount> accounts = parent.config.getAccounts();
1808 for (unsigned int i=0 ; i<accounts.size() ; i++)
1809 {
1810 XmppAccount account = accounts[i];
1811 Gtk::TreeModel::Row row = *(accountListStore->append());
1812 row[accountColumns.nameColumn] = account.getName();
1813 row[accountColumns.hostColumn] = account.getHost();
1814 }
1815 accountView.expand_all();
1816 }
1820 //#########################################################################
1821 //# F I L E S E N D D I A L O G
1822 //#########################################################################
1825 void FileSendDialog::okCallback()
1826 {
1827 response(Gtk::RESPONSE_OK);
1828 hide();
1829 }
1831 void FileSendDialog::cancelCallback()
1832 {
1833 response(Gtk::RESPONSE_CANCEL);
1834 hide();
1835 }
1838 void FileSendDialog::buttonCallback()
1839 {
1840 Gtk::FileChooserDialog dlg("Select a file to send",
1841 Gtk::FILE_CHOOSER_ACTION_OPEN);
1842 dlg.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1843 dlg.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
1844 int ret = dlg.run();
1845 if (ret == Gtk::RESPONSE_OK || ret == Gtk::RESPONSE_ACCEPT)
1846 {
1847 fileName = dlg.get_filename();
1848 fileNameField.set_text(fileName);
1849 }
1850 }
1852 bool FileSendDialog::doSetup()
1853 {
1854 set_title("Send file to user");
1855 set_size_request(400,150);
1857 Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
1858 actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
1859 actionGroup->add( Gtk::Action::create("Send", Gtk::Stock::NETWORK, "Send File"),
1860 sigc::mem_fun(*this, &FileSendDialog::okCallback) );
1861 actionGroup->add( Gtk::Action::create("Cancel", Gtk::Stock::CANCEL, "Cancel"),
1862 sigc::mem_fun(*this, &FileSendDialog::cancelCallback) );
1865 Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
1867 uiManager->insert_action_group(actionGroup, 0);
1868 add_accel_group(uiManager->get_accel_group());
1870 Glib::ustring ui_info =
1871 "<ui>"
1872 " <menubar name='MenuBar'>"
1873 " <menu action='MenuFile'>"
1874 " <menuitem action='Send'/>"
1875 " <separator/>"
1876 " <menuitem action='Cancel'/>"
1877 " </menu>"
1878 " </menubar>"
1879 "</ui>";
1881 uiManager->add_ui_from_string(ui_info);
1882 Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
1883 get_vbox()->pack_start(*pMenuBar, Gtk::PACK_SHRINK);
1885 table.resize(2, 2);
1886 get_vbox()->pack_start(table);
1888 jidLabel.set_text("User ID");
1889 table.attach(jidLabel, 0, 1, 0, 1);
1890 jidField.set_text("inkscape");
1891 table.attach(jidField, 1, 2, 0, 1);
1893 selectFileButton.set_label("Select");
1894 selectFileButton.signal_clicked().connect(
1895 sigc::mem_fun(*this, &FileSendDialog::buttonCallback) );
1896 table.attach(selectFileButton, 0, 1, 1, 2);
1898 fileName = "";
1899 fileNameField.set_text("No file selected");
1900 fileNameField.set_editable(false);
1901 table.attach(fileNameField, 1, 2, 1, 2);
1903 add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1904 add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
1906 show_all_children();
1908 return true;
1909 }
1912 //#########################################################################
1913 //# F I L E R E C E I V E D I A L O G
1914 //#########################################################################
1917 void FileReceiveDialog::okCallback()
1918 {
1919 response(Gtk::RESPONSE_OK);
1920 hide();
1921 }
1923 void FileReceiveDialog::cancelCallback()
1924 {
1925 response(Gtk::RESPONSE_CANCEL);
1926 hide();
1927 }
1929 void FileReceiveDialog::buttonCallback()
1930 {
1931 Gtk::FileChooserDialog dlg("Select a file to save",
1932 Gtk::FILE_CHOOSER_ACTION_SAVE);
1933 dlg.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1934 dlg.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
1935 int ret = dlg.run();
1936 if (ret == Gtk::RESPONSE_OK || ret == Gtk::RESPONSE_ACCEPT)
1937 {
1938 fileName = dlg.get_filename();
1939 fileNameField.set_text(fileName);
1940 }
1941 }
1944 bool FileReceiveDialog::doSetup()
1945 {
1946 set_title("File being sent by user");
1947 set_size_request(450,250);
1949 Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
1950 actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
1951 actionGroup->add( Gtk::Action::create("Send", Gtk::Stock::NETWORK, "Send File"),
1952 sigc::mem_fun(*this, &FileReceiveDialog::okCallback) );
1953 actionGroup->add( Gtk::Action::create("Cancel", Gtk::Stock::CANCEL, "Cancel"),
1954 sigc::mem_fun(*this, &FileReceiveDialog::cancelCallback) );
1957 Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
1959 uiManager->insert_action_group(actionGroup, 0);
1960 add_accel_group(uiManager->get_accel_group());
1962 Glib::ustring ui_info =
1963 "<ui>"
1964 " <menubar name='MenuBar'>"
1965 " <menu action='MenuFile'>"
1966 " <menuitem action='Send'/>"
1967 " <separator/>"
1968 " <menuitem action='Cancel'/>"
1969 " </menu>"
1970 " </menubar>"
1971 "</ui>";
1973 uiManager->add_ui_from_string(ui_info);
1974 Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
1975 get_vbox()->pack_start(*pMenuBar, Gtk::PACK_SHRINK);
1977 table.resize(6, 2);
1978 get_vbox()->pack_start(table);
1980 jidLabel.set_text("User ID");
1981 table.attach(jidLabel, 0, 1, 0, 1);
1982 jidField.set_text(jid);
1983 jidField.set_editable(false);
1984 table.attach(jidField, 1, 2, 0, 1);
1986 offeredLabel.set_text("File Offered");
1987 table.attach(offeredLabel, 0, 1, 1, 2);
1988 offeredField.set_text(offeredName);
1989 offeredField.set_editable(false);
1990 table.attach(offeredField, 1, 2, 1, 2);
1992 descLabel.set_text("Description");
1993 table.attach(descLabel, 0, 1, 2, 3);
1994 descField.set_text(desc);
1995 descField.set_editable(false);
1996 table.attach(descField, 1, 2, 2, 3);
1998 char buf[32];
1999 snprintf(buf, 31, "%ld", fileSize);
2000 sizeLabel.set_text("Size");
2001 table.attach(sizeLabel, 0, 1, 3, 4);
2002 sizeField.set_text(buf);
2003 sizeField.set_editable(false);
2004 table.attach(sizeField, 1, 2, 3, 4);
2006 hashLabel.set_text("MD5 Hash");
2007 table.attach(hashLabel, 0, 1, 4, 5);
2008 hashField.set_text(hash);
2009 hashField.set_editable(false);
2010 table.attach(hashField, 1, 2, 4, 5);
2012 selectFileButton.set_label("Select");
2013 selectFileButton.signal_clicked().connect(
2014 sigc::mem_fun(*this, &FileReceiveDialog::buttonCallback) );
2015 table.attach(selectFileButton, 0, 1, 5, 6);
2017 fileName = "";
2018 fileNameField.set_text("No file selected");
2019 fileNameField.set_editable(false);
2020 table.attach(fileNameField, 1, 2, 5, 6);
2023 add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
2024 add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
2026 show_all_children();
2028 return true;
2029 }
2032 //#########################################################################
2033 //# M A I N W I N D O W
2034 //#########################################################################
2036 PedroGui::PedroGui()
2037 {
2038 doSetup();
2039 }
2041 PedroGui::~PedroGui()
2042 {
2043 chatDeleteAll();
2044 groupChatDeleteAll();
2045 }
2048 void PedroGui::error(const char *fmt, ...)
2049 {
2050 va_list args;
2051 va_start(args, fmt);
2052 gchar * buffer = g_strdup_vprintf(fmt, args);
2053 va_end(args) ;
2055 Gtk::MessageDialog dlg(buffer,
2056 false,
2057 Gtk::MESSAGE_ERROR,
2058 Gtk::BUTTONS_OK,
2059 true);
2060 dlg.run();
2061 g_free(buffer);
2062 }
2064 void PedroGui::status(const char *fmt, ...)
2065 {
2066 va_list args;
2067 va_start(args, fmt);
2068 gchar * buffer = g_strdup_vprintf(fmt, args);
2069 va_end(args) ;
2070 messageList.postMessage("STATUS", buffer);
2071 g_free(buffer);
2072 }
2074 //################################
2075 //# CHAT WINDOW MANAGEMENT
2076 //################################
2077 bool PedroGui::chatCreate(const DOMString &userJid)
2078 {
2079 std::vector<ChatWindow *>::iterator iter;
2080 for (iter=chats.begin() ; iter != chats.end() ; iter++)
2081 {
2082 if (userJid == (*iter)->getJid())
2083 return false;
2084 }
2085 ChatWindow *chat = new ChatWindow(*this, userJid);
2086 chat->show();
2087 chats.push_back(chat);
2088 return true;
2089 }
2091 bool PedroGui::chatDelete(const DOMString &userJid)
2092 {
2093 std::vector<ChatWindow *>::iterator iter;
2094 for (iter=chats.begin() ; iter != chats.end() ; )
2095 {
2096 if (userJid == (*iter)->getJid())
2097 {
2098 delete(*iter);
2099 iter = chats.erase(iter);
2100 }
2101 else
2102 iter++;
2103 }
2104 return true;
2105 }
2107 bool PedroGui::chatDeleteAll()
2108 {
2109 std::vector<ChatWindow *>::iterator iter;
2110 for (iter=chats.begin() ; iter != chats.end() ; )
2111 {
2112 delete(*iter);
2113 iter = chats.erase(iter);
2114 }
2115 return true;
2116 }
2118 bool PedroGui::chatMessage(const DOMString &from, const DOMString &data)
2119 {
2120 if(data.size() > 0)
2121 {
2122 std::vector<ChatWindow *>::iterator iter;
2123 for (iter=chats.begin() ; iter != chats.end() ; iter++)
2124 {
2125 if (from == (*iter)->getJid())
2126 {
2127 (*iter)->postMessage(data);
2128 return true;
2129 }
2130 }
2131 ChatWindow *chat = new ChatWindow(*this, from);
2132 chat->show();
2133 chats.push_back(chat);
2134 chat->postMessage(data);
2135 }
2136 return true;
2137 }
2140 //################################
2141 //# GROUP CHAT WINDOW MANAGEMENT
2142 //################################
2144 bool PedroGui::groupChatCreate(const DOMString &groupJid, const DOMString &nick)
2145 {
2146 std::vector<GroupChatWindow *>::iterator iter;
2147 for (iter=groupChats.begin() ; iter != groupChats.end() ; iter++)
2148 {
2149 if (groupJid == (*iter)->getGroupJid())
2150 return false;
2151 }
2152 GroupChatWindow *chat = new GroupChatWindow(*this, groupJid, nick);
2153 chat->show();
2154 groupChats.push_back(chat);
2155 return true;
2156 }
2159 bool PedroGui::groupChatDelete(const DOMString &groupJid, const DOMString &nick)
2160 {
2161 std::vector<GroupChatWindow *>::iterator iter;
2162 for (iter=groupChats.begin() ; iter != groupChats.end() ;)
2163 {
2164 if (groupJid == (*iter)->getGroupJid() &&
2165 nick == (*iter)->getNick())
2166 {
2167 delete(*iter);
2168 iter = groupChats.erase(iter);
2169 }
2170 else
2171 iter++;
2172 }
2173 return true;
2174 }
2177 bool PedroGui::groupChatDeleteAll()
2178 {
2179 std::vector<GroupChatWindow *>::iterator iter;
2180 for (iter=groupChats.begin() ; iter != groupChats.end() ; )
2181 {
2182 delete(*iter);
2183 iter = groupChats.erase(iter);
2184 }
2185 return true;
2186 }
2189 bool PedroGui::groupChatMessage(const DOMString &groupJid,
2190 const DOMString &from, const DOMString &data)
2191 {
2192 std::vector<GroupChatWindow *>::iterator iter;
2193 for (iter=groupChats.begin() ; iter != groupChats.end() ; iter++)
2194 {
2195 if (groupJid == (*iter)->getGroupJid())
2196 {
2197 (*iter)->receiveMessage(from, data);
2198 }
2199 }
2200 return true;
2201 }
2203 bool PedroGui::groupChatPresence(const DOMString &groupJid,
2204 const DOMString &nick, bool presence,
2205 const DOMString &show,
2206 const DOMString &status)
2207 {
2208 std::vector<GroupChatWindow *>::iterator iter;
2209 for (iter=groupChats.begin() ; iter != groupChats.end() ; iter++)
2210 {
2211 if (groupJid == (*iter)->getGroupJid())
2212 {
2213 (*iter)->receivePresence(nick, presence, show, status);
2214 }
2215 }
2216 return true;
2217 }
2219 //################################
2220 //# EVENTS
2221 //################################
2223 /**
2224 *
2225 */
2226 void PedroGui::padlockEnable()
2227 {
2228 padlockIcon.set(Gtk::Stock::DIALOG_AUTHENTICATION,
2229 Gtk::ICON_SIZE_MENU);
2230 }
2232 /**
2233 *
2234 */
2235 void PedroGui::padlockDisable()
2236 {
2237 padlockIcon.clear();
2238 }
2241 /**
2242 *
2243 */
2244 void PedroGui::handleConnectEvent()
2245 {
2246 status("##### CONNECTED");
2247 actionEnable("Connect", false);
2248 actionEnable("Chat", true);
2249 actionEnable("GroupChat", true);
2250 actionEnable("Disconnect", true);
2251 actionEnable("RegPass", true);
2252 actionEnable("RegCancel", true);
2253 DOMString title = "Pedro - ";
2254 title.append(client.getJid());
2255 set_title(title);
2256 }
2259 /**
2260 *
2261 */
2262 void PedroGui::handleDisconnectEvent()
2263 {
2264 status("##### DISCONNECTED");
2265 actionEnable("Connect", true);
2266 actionEnable("Chat", false);
2267 actionEnable("GroupChat", false);
2268 actionEnable("Disconnect", false);
2269 actionEnable("RegPass", false);
2270 actionEnable("RegCancel", false);
2271 padlockDisable();
2272 DOMString title = "Pedro";
2273 set_title(title);
2274 chatDeleteAll();
2275 groupChatDeleteAll();
2276 roster.clear();
2277 }
2280 /**
2281 *
2282 */
2283 void PedroGui::doEvent(const XmppEvent &event)
2284 {
2286 int typ = event.getType();
2287 switch (typ)
2288 {
2289 case XmppEvent::EVENT_STATUS:
2290 {
2291 //printf("##### STATUS: %s\n", event.getData().c_str());
2292 status("%s", event.getData().c_str());
2293 break;
2294 }
2295 case XmppEvent::EVENT_ERROR:
2296 {
2297 //printf("##### ERROR: %s\n", event.getData().c_str());
2298 error("%s", event.getData().c_str());
2299 padlockDisable();
2300 break;
2301 }
2302 case XmppEvent::EVENT_SSL_STARTED:
2303 {
2304 padlockEnable();
2305 break;
2306 }
2307 case XmppEvent::EVENT_CONNECTED:
2308 {
2309 handleConnectEvent();
2310 break;
2311 }
2312 case XmppEvent::EVENT_DISCONNECTED:
2313 {
2314 handleDisconnectEvent();
2315 break;
2316 }
2317 case XmppEvent::EVENT_MESSAGE:
2318 {
2319 status("##### MESSAGE: %s\n", event.getFrom().c_str());
2320 chatMessage(event.getFrom(), event.getData());
2321 break;
2322 }
2323 case XmppEvent::EVENT_PRESENCE:
2324 {
2325 status("##### PRESENCE: %s\n", event.getFrom().c_str());
2326 roster.refresh();
2327 break;
2328 }
2329 case XmppEvent::EVENT_ROSTER:
2330 {
2331 status("##### ROSTER\n");
2332 roster.refresh();
2333 break;
2334 }
2335 case XmppEvent::EVENT_MUC_JOIN:
2336 {
2337 status("##### GROUP JOINED: %s\n", event.getGroup().c_str());
2338 break;
2339 }
2340 case XmppEvent::EVENT_MUC_MESSAGE:
2341 {
2342 //printf("##### MUC_MESSAGE: %s\n", event.getGroup().c_str());
2343 groupChatMessage(event.getGroup(),
2344 event.getFrom(), event.getData());
2345 break;
2346 }
2347 case XmppEvent::EVENT_MUC_PRESENCE:
2348 {
2349 //printf("##### MUC_USER LIST: %s\n", event.getFrom().c_str());
2350 groupChatPresence(event.getGroup(),
2351 event.getFrom(),
2352 event.getPresence(),
2353 event.getShow(),
2354 event.getStatus());
2355 break;
2356 }
2357 case XmppEvent::EVENT_MUC_LEAVE:
2358 {
2359 status("##### GROUP LEFT: %s\n", event.getGroup().c_str());
2360 groupChatDelete(event.getGroup(), event.getFrom());
2361 break;
2362 }
2363 case XmppEvent::EVENT_FILE_RECEIVE:
2364 {
2365 status("##### FILE RECEIVE: %s\n", event.getFileName().c_str());
2366 doReceiveFile(event.getFrom(), event.getIqId(), event.getStreamId(),
2367 event.getFileName(), event.getFileDesc(),
2368 event.getFileSize(), event.getFileHash());
2369 break;
2370 }
2371 case XmppEvent::EVENT_REGISTRATION_NEW:
2372 {
2373 status("##### REGISTERED: %s at %s\n",
2374 event.getTo().c_str(), event.getFrom().c_str());
2375 break;
2376 }
2377 case XmppEvent::EVENT_REGISTRATION_CHANGE_PASS:
2378 {
2379 status("##### PASSWORD CHANGED: %s at %s\n",
2380 event.getTo().c_str(), event.getFrom().c_str());
2381 break;
2382 }
2383 case XmppEvent::EVENT_REGISTRATION_CANCEL:
2384 {
2385 //client.disconnect();
2386 status("##### REGISTERATION CANCELLED: %s at %s\n",
2387 event.getTo().c_str(), event.getFrom().c_str());
2388 break;
2389 }
2390 default:
2391 {
2392 printf("unknown event type: %d\n", typ);
2393 break;
2394 }
2395 }
2397 }
2399 /**
2400 *
2401 */
2402 bool PedroGui::checkEventQueue()
2403 {
2404 while (client.eventQueueAvailable() > 0)
2405 {
2406 XmppEvent evt = client.eventQueuePop();
2407 doEvent(evt);
2408 }
2410 while( Gtk::Main::events_pending() )
2411 Gtk::Main::iteration();
2413 return true;
2414 }
2417 //##################
2418 //# COMMANDS
2419 //##################
2420 void PedroGui::doChat(const DOMString &jid)
2421 {
2422 if (jid.size()>0)
2423 {
2424 chatCreate(jid);
2425 return;
2426 }
2428 FileSendDialog dlg(*this);
2429 int ret = dlg.run();
2430 if (ret == Gtk::RESPONSE_OK)
2431 {
2432 chatCreate(dlg.getJid());
2433 }
2435 }
2437 void PedroGui::doSendFile(const DOMString &jid)
2438 {
2439 FileSendDialog dlg(*this);
2440 if (jid.size()>0)
2441 dlg.setJid(jid);
2442 int ret = dlg.run();
2443 if (ret == Gtk::RESPONSE_OK)
2444 {
2445 DOMString fileName = dlg.getFileName();
2446 printf("fileName:%s\n", fileName.c_str());
2447 DOMString offeredName = "";
2448 DOMString desc = "";
2449 client.fileSendBackground(jid, offeredName, fileName, desc);
2450 }
2452 }
2454 void PedroGui::doReceiveFile(
2455 const DOMString &jid,
2456 const DOMString &iqId,
2457 const DOMString &streamId,
2458 const DOMString &offeredName,
2459 const DOMString &desc,
2460 long size,
2461 const DOMString &hash
2462 )
2464 {
2465 FileReceiveDialog dlg(*this, jid, iqId, streamId,
2466 offeredName, desc, size, hash);
2467 int ret = dlg.run();
2468 if (ret == Gtk::RESPONSE_OK)
2469 {
2470 DOMString fileName = dlg.getFileName();
2471 printf("fileName:%s\n", fileName.c_str());
2472 client.fileReceiveBackground(jid, iqId, streamId, fileName, size, hash);
2473 }
2475 }
2477 void PedroGui::doShare(const DOMString &jid)
2478 {
2479 Inkscape::Whiteboard::SessionManager& sm =
2480 Inkscape::Whiteboard::SessionManager::instance();
2481 sm.initialiseSession(jid, Inkscape::Whiteboard::State::WHITEBOARD_PEER);
2482 }
2484 void PedroGui::doGroupShare(const DOMString &groupJid)
2485 {
2486 Inkscape::Whiteboard::SessionManager& sm =
2487 Inkscape::Whiteboard::SessionManager::instance();
2488 sm.initialiseSession(groupJid, Inkscape::Whiteboard::State::WHITEBOARD_MUC);
2489 }
2491 //##################
2492 //# CALLBACKS
2493 //##################
2494 void PedroGui::connectCallback()
2495 {
2496 ConnectDialog dialog(*this);
2497 int result = dialog.run();
2498 dialog.hide();
2499 if (result == Gtk::RESPONSE_OK)
2500 {
2501 client.setHost(dialog.getHost());
2502 client.setPort(dialog.getPort());
2503 client.setUsername(dialog.getUser());
2504 client.setPassword(dialog.getPass());
2505 client.setResource(dialog.getResource());
2506 client.setDoRegister(dialog.getRegister());
2507 client.connect();
2508 }
2509 }
2513 void PedroGui::chatCallback()
2514 {
2515 ChatDialog dialog(*this);
2516 int result = dialog.run();
2517 dialog.hide();
2518 if (result == Gtk::RESPONSE_OK)
2519 {
2520 client.message(dialog.getUser(), dialog.getText());
2521 }
2522 }
2526 void PedroGui::groupChatCallback()
2527 {
2528 GroupChatDialog dialog(*this);
2529 int result = dialog.run();
2530 dialog.hide();
2531 if (result != Gtk::RESPONSE_OK)
2532 return;
2533 DOMString groupJid = dialog.getGroup();
2534 groupJid.append("@");
2535 groupJid.append(dialog.getHost());
2536 if (client.groupChatExists(groupJid))
2537 {
2538 error("Group chat %s already exists", groupJid.c_str());
2539 return;
2540 }
2541 groupChatCreate(groupJid, dialog.getNick());
2542 client.groupChatJoin(groupJid, dialog.getNick(), dialog.getPass() );
2543 config.setMucGroup(dialog.getGroup());
2544 config.setMucHost(dialog.getHost());
2545 config.setMucNick(dialog.getNick());
2546 config.setMucPassword(dialog.getPass());
2548 configSave();
2549 }
2552 void PedroGui::disconnectCallback()
2553 {
2554 client.disconnect();
2555 }
2558 void PedroGui::quitCallback()
2559 {
2560 client.disconnect();
2561 hide();
2562 //Severe overkill! :-)
2563 //Gtk::Main::quit();
2564 }
2567 void PedroGui::fontCallback()
2568 {
2569 Gtk::FontSelectionDialog dlg;
2570 int ret = dlg.run();
2571 if (ret == Gtk::RESPONSE_OK)
2572 {
2573 Glib::ustring fontName = dlg.get_font_name();
2574 Pango::FontDescription fontDesc(fontName);
2575 modify_font(fontDesc);
2576 }
2577 }
2579 void PedroGui::colorCallback()
2580 {
2581 Gtk::ColorSelectionDialog dlg;
2582 int ret = dlg.run();
2583 if (ret == Gtk::RESPONSE_OK)
2584 {
2585 Gdk::Color col = dlg.get_colorsel()->get_current_color();
2586 modify_bg(Gtk::STATE_NORMAL, col);
2587 }
2588 }
2590 void PedroGui::regPassCallback()
2591 {
2592 PasswordDialog dlg(*this);
2593 int ret = dlg.run();
2594 if (ret == Gtk::RESPONSE_OK)
2595 {
2596 DOMString newpass = dlg.getNewPass();
2597 client.inBandRegistrationChangePassword(newpass);
2598 }
2599 }
2602 void PedroGui::regCancelCallback()
2603 {
2604 Gtk::MessageDialog dlg(*this, "Do you want to cancel your registration on the server?",
2605 false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true);
2606 int ret = dlg.run();
2607 if (ret == Gtk::RESPONSE_YES)
2608 {
2609 client.inBandRegistrationCancel();
2610 }
2611 }
2615 void PedroGui::sendFileCallback()
2616 {
2617 doSendFile("");
2618 }
2622 void PedroGui::aboutCallback()
2623 {
2624 Gtk::AboutDialog dlg;
2625 dlg.set_name("Inkboard");
2626 std::vector<Glib::ustring>authors;
2627 authors.push_back("David Yip <yipdw@rose-hulman.edu>");
2628 authors.push_back("Dale Harvey <harveyd@gmail.com>");
2629 dlg.set_authors(authors);
2630 DOMString comments = _("Shared SVG whiteboard tool.");
2631 comments.append(_("Based on the Pedro XMPP client"));
2632 dlg.set_comments(comments);
2633 dlg.set_version("1.0");
2634 dlg.run();
2635 }
2639 void PedroGui::actionEnable(const DOMString &name, bool val)
2640 {
2641 DOMString path = "/ui/MenuBar/";
2642 path.append(name);
2643 Glib::RefPtr<Gtk::Action> action = uiManager->get_action(path);
2644 if (!action)
2645 {
2646 path = "/ui/MenuBar/MenuFile/";
2647 path.append(name);
2648 action = uiManager->get_action(path);
2649 }
2650 if (!action)
2651 {
2652 path = "/ui/MenuBar/MenuEdit/";
2653 path.append(name);
2654 action = uiManager->get_action(path);
2655 }
2656 if (!action)
2657 {
2658 path = "/ui/MenuBar/MenuRegister/";
2659 path.append(name);
2660 action = uiManager->get_action(path);
2661 }
2662 if (!action)
2663 {
2664 path = "/ui/MenuBar/MenuTransfer/";
2665 path.append(name);
2666 action = uiManager->get_action(path);
2667 }
2668 if (!action)
2669 {
2670 path = "/ui/MenuBar/MenuHelp/";
2671 path.append(name);
2672 action = uiManager->get_action(path);
2673 }
2674 if (!action)
2675 return;
2676 action->set_sensitive(val);
2677 }
2680 bool PedroGui::configLoad()
2681 {
2682 if (!config.readFile("pedro.ini"))
2683 return false;
2684 return true;
2685 }
2688 bool PedroGui::configSave()
2689 {
2690 if (!config.writeFile("pedro.ini"))
2691 return false;
2692 return true;
2693 }
2698 bool PedroGui::doSetup()
2699 {
2700 configLoad();
2702 set_title("Pedro XMPP Client");
2703 set_size_request(500, 300);
2704 add(mainBox);
2706 Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
2708 //### FILE MENU
2709 actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
2711 actionGroup->add( Gtk::Action::create("Connect",
2712 Gtk::Stock::CONNECT, "Connect"),
2713 sigc::mem_fun(*this, &PedroGui::connectCallback) );
2715 actionGroup->add( Gtk::Action::create("Chat",
2716 Gtk::Stock::CONNECT, "Chat"),
2717 sigc::mem_fun(*this, &PedroGui::chatCallback) );
2719 actionGroup->add( Gtk::Action::create("GroupChat",
2720 Gtk::Stock::CONNECT, "Group Chat"),
2721 sigc::mem_fun(*this, &PedroGui::groupChatCallback) );
2723 actionGroup->add( Gtk::Action::create("Disconnect",
2724 Gtk::Stock::DISCONNECT, "Disconnect"),
2725 sigc::mem_fun(*this, &PedroGui::disconnectCallback) );
2727 actionGroup->add( Gtk::Action::create("Quit", Gtk::Stock::QUIT),
2728 sigc::mem_fun(*this, &PedroGui::quitCallback) );
2730 //### EDIT MENU
2731 actionGroup->add( Gtk::Action::create("MenuEdit", "_Edit") );
2732 actionGroup->add( Gtk::Action::create("SelectFont",
2733 Gtk::Stock::SELECT_FONT, "Select Font"),
2734 sigc::mem_fun(*this, &PedroGui::fontCallback) );
2735 actionGroup->add( Gtk::Action::create("SelectColor",
2736 Gtk::Stock::SELECT_COLOR, "Select Color"),
2737 sigc::mem_fun(*this, &PedroGui::colorCallback) );
2739 //### REGISTER MENU
2740 actionGroup->add( Gtk::Action::create("MenuRegister", "_Registration") );
2741 actionGroup->add( Gtk::Action::create("RegPass",
2742 Gtk::Stock::DIALOG_AUTHENTICATION, "Change Password"),
2743 sigc::mem_fun(*this, &PedroGui::regPassCallback) );
2744 actionGroup->add( Gtk::Action::create("RegCancel",
2745 Gtk::Stock::CANCEL, "Cancel Registration"),
2746 sigc::mem_fun(*this, &PedroGui::regCancelCallback) );
2748 //### TRANSFER MENU
2749 actionGroup->add( Gtk::Action::create("MenuTransfer", "_Transfer") );
2750 actionGroup->add( Gtk::Action::create("SendFile",
2751 Gtk::Stock::NETWORK, "Send File"),
2752 sigc::mem_fun(*this, &PedroGui::sendFileCallback) );
2754 //### HELP MENU
2755 actionGroup->add( Gtk::Action::create("MenuHelp", "_Help") );
2756 actionGroup->add( Gtk::Action::create("About",
2757 Gtk::Stock::ABOUT, "About Pedro"),
2758 sigc::mem_fun(*this, &PedroGui::aboutCallback) );
2760 uiManager = Gtk::UIManager::create();
2762 uiManager->insert_action_group(actionGroup, 0);
2763 add_accel_group(uiManager->get_accel_group());
2765 Glib::ustring ui_info =
2766 "<ui>"
2767 " <menubar name='MenuBar'>"
2768 " <menu action='MenuFile'>"
2769 " <menuitem action='Connect'/>"
2770 " <separator/>"
2771 " <menuitem action='Chat'/>"
2772 " <menuitem action='GroupChat'/>"
2773 " <separator/>"
2774 " <menuitem action='Disconnect'/>"
2775 " <menuitem action='Quit'/>"
2776 " </menu>"
2777 " <menu action='MenuEdit'>"
2778 " <menuitem action='SelectFont'/>"
2779 " <menuitem action='SelectColor'/>"
2780 " </menu>"
2781 " <menu action='MenuRegister'>"
2782 " <menuitem action='RegPass'/>"
2783 " <menuitem action='RegCancel'/>"
2784 " </menu>"
2785 " <menu action='MenuTransfer'>"
2786 " <menuitem action='SendFile'/>"
2787 " </menu>"
2788 " <menu action='MenuHelp'>"
2789 " <menuitem action='About'/>"
2790 " </menu>"
2791 " </menubar>"
2792 "</ui>";
2794 uiManager->add_ui_from_string(ui_info);
2795 Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
2796 menuBarBox.pack_start(*pMenuBar, Gtk::PACK_SHRINK);
2798 padlockDisable();
2799 menuBarBox.pack_end(padlockIcon, Gtk::PACK_SHRINK);
2801 mainBox.pack_start(menuBarBox, Gtk::PACK_SHRINK);
2803 actionEnable("Connect", true);
2804 actionEnable("Chat", false);
2805 actionEnable("GroupChat", false);
2806 actionEnable("Disconnect", false);
2807 actionEnable("RegPass", false);
2808 actionEnable("RegCancel", false);
2810 mainBox.pack_start(vPaned);
2811 vPaned.add1(roster);
2812 vPaned.add2(messageList);
2813 roster.setParent(this);
2815 show_all_children();
2817 //# Start a timer to check the queue every nn milliseconds
2818 Glib::signal_timeout().connect(
2819 sigc::mem_fun(*this, &PedroGui::checkEventQueue), 20 );
2821 //client.addXmppEventListener(*this);
2822 client.eventQueueEnable(true);
2824 return true;
2825 }
2828 } // namespace Pedro
2832 //########################################################################
2833 //# E N D O F F I L E
2834 //########################################################################