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"
28 #include <stdarg.h>
30 namespace Pedro
31 {
35 //#########################################################################
36 //# I C O N S
37 //#########################################################################
39 static const guint8 icon_available[] =
40 { ""
41 /* Pixbuf magic (0x47646b50) */
42 "GdkP"
43 /* length: header (24) + pixel_data (672) */
44 "\0\0\2\270"
45 /* pixdata_type (0x1010002) */
46 "\1\1\0\2"
47 /* rowstride (48) */
48 "\0\0\0""0"
49 /* width (12) */
50 "\0\0\0\14"
51 /* height (14) */
52 "\0\0\0\16"
53 /* pixel_data: */
54 "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377333"
55 "\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
56 "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377"
57 "\0\377\377\377\0\377\377\377\0\377333\377\377\377\377\0\377\377\377\0"
58 "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377"
59 "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\37733"
60 "3\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377"
61 "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
62 "\377\377\0\377\377\377\0\377333\377\377\377\377\0\377\377\377\0\377\377"
63 "\377\0""333\377\377\377\0\377\377\377\0\377\0\0\0\377\377\377\0\377\0"
64 "\0\0\377\377\377\0\377\377\377\0\377333\377\377\377\377\0\377\377\377"
65 "\0\377\377\377\0""333\377\377\377\0\377\377\377\0\377\0\0\0\377\377\377"
66 "\0\377\0\0\0\377\377\377\0\377\377\377\0\377333\377\377\377\377\0\377"
67 "\377\377\0\377\377\377\0""333\377\377\377\0\377\377\377\0\377\377\377"
68 "\0\377\0\0\0\377\377\377\0\377\377\377\0\377\377\377\0\377333\377\377"
69 "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377"
70 "\0\377\377\377\0\377\0\0\0\377\377\377\0\377\377\377\0\377333\377\377"
71 "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""3"
72 "33\377\377\377\0\377\377\377\0\377\0\0\0\377\377\377\0\377\377\377\0"
73 "\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
74 "\377\377\0\377\377\377\0""333\377\377\377\0\377\377\377\0\377\377\377"
75 "\0\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
76 "\377\377\377\0\377\377\377\0\377\377\377\0LLL\377\0\0\0\377\0\0\0\377"
77 "\0\0\0\377LLL\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
78 "\0\377\377\377\0\377\377\377\0\377\377\377\0LLL\377\0\0\0\377\0\0\0\377"
79 "\0\0\0\377LLL\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
80 "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\0\0\0\377"
81 "\0\0\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
82 "\377\0\377\377\377\0\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"};
87 static const guint8 icon_away[] =
88 { ""
89 /* Pixbuf magic (0x47646b50) */
90 "GdkP"
91 /* length: header (24) + pixel_data (672) */
92 "\0\0\2\270"
93 /* pixdata_type (0x1010002) */
94 "\1\1\0\2"
95 /* rowstride (48) */
96 "\0\0\0""0"
97 /* width (12) */
98 "\0\0\0\14"
99 /* height (14) */
100 "\0\0\0\16"
101 /* pixel_data: */
102 "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
103 "\0""333\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
104 "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
105 "\377\0""333\377\377\377\0\377\377\377\0\377333\377\377\377\377\0\377"
106 "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
107 "\377\377\0""333\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
108 "\0\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
109 "\377\377\377\0\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0"
110 "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\377\377\0\377\377\377"
111 "\0\377\377\377\0\377\0\0\377\377\377\377\377\377\377\377\377\377\377"
112 "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
113 "\377\377\377\377\377\377\0\0\377\377\377\377\0\377\0\0\377\377\377\377"
114 "\377\0\0\0\377\377\377\377\377\377\377\377\377\0\0\0\377\377\377\377"
115 "\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\0\0\377"
116 "\377\0\0\377\377\377\377\377\0\0\0\377\0\0\0\377\377\377\377\377\0\0"
117 "\0\377\0\0\0\377\377\377\377\377\377\377\377\377\0\0\0\377\377\377\377"
118 "\377\377\0\0\377\377\0\0\377\377\377\377\377\0\0\0\377\377\377\377\377"
119 "\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"
120 "\377\377\377\0\0\377\377\0\0\377\377\377\377\377\0\0\0\377\377\377\377"
121 "\377\377\377\377\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377"
122 "\377\0\0\0\377\377\377\377\377\377\0\0\377\377\377\377\0\377\0\0\377"
123 "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
124 "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0"
125 "\377\377\377\377\0\377\377\377\0\377\377\377\0\377\0\0\377\377\0\0\377"
126 "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0"
127 "\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
128 "\377\0\377\377\377\0LLL\377333\377\0\0\0\377\0\0\0\377LLL\377\377\377"
129 "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
130 "\377\0\377\377\377\0\377\377\377\0""333\377333\377333\377\377\377\377"
131 "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\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"};
137 static const guint8 icon_chat[] =
138 { ""
139 /* Pixbuf magic (0x47646b50) */
140 "GdkP"
141 /* length: header (24) + pixel_data (672) */
142 "\0\0\2\270"
143 /* pixdata_type (0x1010002) */
144 "\1\1\0\2"
145 /* rowstride (48) */
146 "\0\0\0""0"
147 /* width (12) */
148 "\0\0\0\14"
149 /* height (14) */
150 "\0\0\0\16"
151 /* pixel_data: */
152 "\377\377\377\0\377\377\377\0\377\377\377\0""333\377333\377333\377\377"
153 "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
154 "\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377\377\377"
155 "\0\377\377\377\0\377333\377\377\377\377\0\377\377\377\0\377\377\377\0"
156 "\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377\377"
157 "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377333\377\377\377\377"
158 "\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377\377"
159 "\377\0\377fff\377\377\377\0\377fff\377\377\377\0\377\377\377\0\37733"
160 "3\377\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377"
161 "fff\377\377\377\0\377fff\377\377\377\0\377fff\377\377\377\0\377333\377"
162 "\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377fff"
163 "\377\377\377\0\377\377\377\0\377\377\377\0\377\0\0\0\377\0\0\0\377\0"
164 "\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""33"
165 "3\377\377\377\0\377fff\377\377\377\0\377\0\0\0\377\377\377\0\377\377"
166 "\377\0\377\377\377\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377\377"
167 "\377\0""333\377\377\377\0\377fff\377\0\0\0\377\377\377\0\377\377\377"
168 "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\0\0\0\377\377\377\377"
169 "\0\377\377\377\0\377\377\377\0""333\377\0\0\0\377\377\377\0\377\377\377"
170 "\0\377\0\0\0\377\377\377\0\377\0\0\0\377\377\377\0\377\377\377\0\377"
171 "\0\0\0\377\377\377\377\0\377\377\377\0""333\377\0\0\0\377\377\377\0\377"
172 "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
173 "\377\377\0\377\0\0\0\377\377\377\377\0\377\377\377\0LLL\377\0\0\0\377"
174 "\377\377\0\377\377\377\0\377\0\0\0\377\377\377\0\377\0\0\0\377\377\377"
175 "\0\377\377\377\0\377\0\0\0\377\377\377\377\0\377\377\377\0LLL\377333"
176 "\377\0\0\0\377\377\377\0\377\377\377\0\377\0\0\0\377\377\377\0\377\377"
177 "\377\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
178 "\377\0""333\377333\377\0\0\0\377\377\377\0\377\377\377\0\377\377\377"
179 "\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
180 "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\0\0\0\377"
181 "\0\0\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0"};
184 static const guint8 icon_dnd[] =
185 { ""
186 /* Pixbuf magic (0x47646b50) */
187 "GdkP"
188 /* length: header (24) + pixel_data (672) */
189 "\0\0\2\270"
190 /* pixdata_type (0x1010002) */
191 "\1\1\0\2"
192 /* rowstride (48) */
193 "\0\0\0""0"
194 /* width (12) */
195 "\0\0\0\14"
196 /* height (14) */
197 "\0\0\0\16"
198 /* pixel_data: */
199 "\377\377\377\0\377\377\377\0\377\377\377\0""333\377333\377333\377\377"
200 "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
201 "\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377\377\377"
202 "\0\377\377\377\0\377333\377\377\377\377\0\377\377\377\0\377\377\377\0"
203 "\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377\377"
204 "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377333\377\377\377\377"
205 "\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377\377"
206 "\377\0\377fff\377\377\377\0\377fff\377\377\377\0\377\377\377\0\37733"
207 "3\377\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377"
208 "fff\377\377\377\0\377fff\377\377\377\0\377fff\377\377\377\0\377333\377"
209 "\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377fff"
210 "\377\377\377\0\377\377\377\0\377\377\377\0\377\177\0\0\377\177\0\0\377"
211 "\177\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
212 "333\377\377\377\0\377fff\377\377\377\0\377\177\0\0\377\377\0\0\377\377"
213 "\0\0\377\377\0\0\377\177\0\0\377\377\377\377\0\377\377\377\0\377\377"
214 "\377\0""333\377\377\377\0\377fff\377\177\0\0\377\377\377\377\377fff\377"
215 "\377\0\0\377fff\377\377\377\377\377\177\0\0\377\377\377\377\0\377\377"
216 "\377\0\377\377\377\0""333\377\177\0\0\377\377\0\0\377fff\377\377\377"
217 "\377\377fff\377\377\377\377\377fff\377\377\0\0\377\177\0\0\377\377\377"
218 "\377\0\377\377\377\0""333\377\177\0\0\377\377\0\0\377\377\0\0\377fff"
219 "\377\377\377\377\377fff\377\377\0\0\377\377\0\0\377\177\0\0\377\377\377"
220 "\377\0\377\377\377\0LLL\377\177\0\0\377\377\0\0\377fff\377\377\377\377"
221 "\377fff\377\377\377\377\377fff\377\377\0\0\377\177\0\0\377\377\377\377"
222 "\0\377\377\377\0LLL\377333\377\177\0\0\377\377\377\377\377fff\377\377"
223 "\0\0\377fff\377\377\377\377\377\177\0\0\377\377\377\377\0\377\377\377"
224 "\0\377\377\377\0\377\377\377\0""333\377333\377\177\0\0\377\377\0\0\377"
225 "\377\0\0\377\377\0\0\377\177\0\0\377\377\377\377\0\377\377\377\0\377"
226 "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
227 "\377\377\0\177\0\0\377\177\0\0\377\177\0\0\377\377\377\377\0\377\377"
228 "\377\0\377\377\377\0"};
231 static const guint8 icon_error[] =
232 { ""
233 /* Pixbuf magic (0x47646b50) */
234 "GdkP"
235 /* length: header (24) + pixel_data (672) */
236 "\0\0\2\270"
237 /* pixdata_type (0x1010002) */
238 "\1\1\0\2"
239 /* rowstride (48) */
240 "\0\0\0""0"
241 /* width (12) */
242 "\0\0\0\14"
243 /* height (14) */
244 "\0\0\0\16"
245 /* pixel_data: */
246 "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
247 "\0""333\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
248 "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377"
249 "\377\377\377\0\0\0\0\377\350\350\350\377333\377\377\377\377\0\377\377"
250 "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377"
251 "\350\350\350\377fff\377\0\0\0\377\350\350\350\377\350\350\350\377333"
252 "\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377"
253 "\350\350\350\377\350\350\350\377\350\350\350\377\0\0\0\377\350\350\350"
254 "\377\350\350\350\377\350\350\350\377333\377\377\377\377\0\377\377\377"
255 "\0\377\377\377\0""333\377\350\350\350\377\350\350\350\377\0\0\0\377\0"
256 "\0\0\377fff\377\350\350\350\377\350\350\350\377333\377\377\377\377\0"
257 "\377\377\377\0\377\377\377\0""333\377\350\350\350\377\350\350\350\377"
258 "\0\0\0\377\350\350\350\377\0\0\0\377\0\0\0\377\0\0\0\377333\377\377\377"
259 "\377\0\377\377\377\0\377\377\377\0""333\377\350\350\350\377\0\0\0\377"
260 "\350\350\350\377\0\0\0\377\350\350\350\377\350\350\350\377\350\350\350"
261 "\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""3"
262 "33\377\350\350\350\377\0\0\0\377\0\0\0\377\0\0\0\377\350\350\350\377"
263 "fff\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
264 "\377\0""333\377\0\0\0\377\350\350\350\377\350\350\350\377\350\350\350"
265 "\377\0\0\0\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
266 "\377\0\377\377\377\0\377\377\377\0""333\377\350\350\350\377\350\350\350"
267 "\377\350\350\350\377333\377\377\377\377\0\377\377\377\0\377\377\377\0"
268 "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0LLL\377\0\0\0"
269 "\377\0\0\0\377\0\0\0\377LLL\377\377\377\377\0\377\377\377\0\377\377\377"
270 "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0LLL\377\0\0"
271 "\0\377\0\0\0\377\0\0\0\377LLL\377\377\377\377\0\377\377\377\0\377\377"
272 "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
273 "\377\0\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377"
274 "\377\377\0\377\377\377\0\377\377\377\0\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"};
279 static const guint8 icon_offline[] =
280 { ""
281 /* Pixbuf magic (0x47646b50) */
282 "GdkP"
283 /* length: header (24) + pixel_data (672) */
284 "\0\0\2\270"
285 /* pixdata_type (0x1010002) */
286 "\1\1\0\2"
287 /* rowstride (48) */
288 "\0\0\0""0"
289 /* width (12) */
290 "\0\0\0\14"
291 /* height (14) */
292 "\0\0\0\16"
293 /* pixel_data: */
294 "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377333"
295 "\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
296 "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377"
297 "\377\377\377\377\377\377\377\377\377\377333\377\377\377\377\0\377\377"
298 "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377"
299 "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
300 "\377\377\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
301 "\377\0""333\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
302 "\377\377\377\377\377\377\377\377\377\377\377\377\377\377333\377\377\377"
303 "\377\0\377\377\377\0\377\377\377\0""333\377\377\377\377\377\377\377\377"
304 "\377\0\0\0\377\377\377\377\377\0\0\0\377\377\377\377\377\377\377\377"
305 "\377333\377\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377"
306 "\377\377\377\377\377\377\0\0\0\377\377\377\377\377\0\0\0\377\377\377"
307 "\377\377\377\377\377\377333\377\377\377\377\0\377\377\377\0\377\377\377"
308 "\0""333\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377"
309 "\377\377\377\377\377\377\377\377\377\377\377\377333\377\377\377\377\0"
310 "\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\377\377\377"
311 "\377\377\377\0\0\0\377\377\377\377\377\377\377\377\377333\377\377\377"
312 "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377"
313 "\377\377\377\377\377\377\377\377\0\0\0\377\377\377\377\377\377\377\377"
314 "\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
315 "\377\377\0\377\377\377\0""333\377\377\377\377\377\377\377\377\377\377"
316 "\377\377\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
317 "\377\0\377\377\377\0\377\377\377\0\377\377\377\0LLL\377\0\0\0\377\0\0"
318 "\0\377\0\0\0\377LLL\377\377\377\377\0\377\377\377\0\377\377\377\0\377"
319 "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0LLL\377\0\0\0\377"
320 "\0\0\0\377\0\0\0\377LLL\377\377\377\377\0\377\377\377\0\377\377\377\0"
321 "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
322 "\0\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377\377"
323 "\377\0\377\377\377\0\377\377\377\0\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"};
328 static const guint8 icon_xa[] =
329 { ""
330 /* Pixbuf magic (0x47646b50) */
331 "GdkP"
332 /* length: header (24) + pixel_data (672) */
333 "\0\0\2\270"
334 /* pixdata_type (0x1010002) */
335 "\1\1\0\2"
336 /* rowstride (48) */
337 "\0\0\0""0"
338 /* width (12) */
339 "\0\0\0\14"
340 /* height (14) */
341 "\0\0\0\16"
342 /* pixel_data: */
343 "\377\377\377\0\377\377\377\0\377\377\377\0\377\0\0\377333\377333\377"
344 "333\377\377\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
345 "\377\0\377\377\377\0\377\377\377\0\377\0\0\377333\377\377\377\0\377\377"
346 "\377\0\377\377\377\0\377333\377\377\0\0\377\377\377\377\0\377\377\377"
347 "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\0\0\377\377\377\0\377"
348 "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\0\0\377"
349 "\177\0\0\377\177\0\0\377\377\377\377\0\377\377\377\0""333\377\377\0\0"
350 "\377\377\377\0\377fff\377\377\377\0\377\177\0\0\377\177\0\0\377\377\0"
351 "\0\377\377\377\377\377\177\0\0\377\377\377\377\0\377\377\377\0""333\377"
352 "\377\0\0\377\177\0\0\377\177\0\0\377\177\0\0\377\377\377\377\377\377"
353 "\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\177\0\0\377\177\0\0"
354 "\377\177\0\0\377\377\0\0\377\377\377\377\377\377\377\377\377\377\377"
355 "\377\377\262\262\262\377\377\377\377\377\0\0\0\377\0\0\0\377\377\377"
356 "\377\377\177\0\0\377\177\0\0\377\377\377\377\377\262\262\262\377\0\0"
357 "\0\377\262\262\262\377\0\0\0\377\377\377\377\377\0\0\0\377\377\377\377"
358 "\377\262\262\262\377\0\0\0\377\177\0\0\377\177\0\0\377\377\377\377\377"
359 "\0\0\0\377\377\377\377\377\0\0\0\377\0\0\0\377\377\377\377\377\0\0\0"
360 "\377\0\0\0\377\377\377\377\377\0\0\0\377\177\0\0\377\177\0\0\377\377"
361 "\377\377\377\0\0\0\377\377\377\377\377\0\0\0\377\377\377\377\377\0\0"
362 "\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\177"
363 "\0\0\377\377\377\377\0\177\0\0\377\262\262\262\377\0\0\0\377\262\262"
364 "\262\377\377\377\377\377\377\377\377\377\377\377\377\377\177\0\0\377"
365 "\177\0\0\377\177\0\0\377\377\377\377\0\377\377\377\0\177\0\0\377\377"
366 "\377\377\377\377\377\377\377\177\0\0\377\177\0\0\377\177\0\0\377\177"
367 "\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
368 "\377\377\0\177\0\0\377\177\0\0\377\177\0\0\377333\377\0\0\0\377\0\0\0"
369 "\377LLL\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
370 "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377333\377"
371 "333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
372 "\377\0\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 //#########################################################################
378 //# R O S T E R
379 //#########################################################################
382 void Roster::doubleClickCallback(const Gtk::TreeModel::Path &path,
383 Gtk::TreeViewColumn *col)
384 {
385 Glib::RefPtr<Gtk::TreeModel> model = rosterView.get_model();
386 Glib::RefPtr<Gtk::TreeSelection> sel = rosterView.get_selection();
387 Gtk::TreeModel::iterator iter = sel->get_selected();
388 DOMString nick = iter->get_value(rosterColumns.userColumn);
389 //printf("Double clicked:%s\n", nick.c_str());
390 if (parent)
391 parent->doChat(nick);
393 }
395 void Roster::chatCallback()
396 {
397 Glib::RefPtr<Gtk::TreeModel> model = rosterView.get_model();
398 Glib::RefPtr<Gtk::TreeSelection> sel = rosterView.get_selection();
399 Gtk::TreeModel::iterator iter = sel->get_selected();
400 DOMString nick = iter->get_value(rosterColumns.userColumn);
401 //printf("Chat with:%s\n", nick.c_str());
402 if (parent)
403 parent->doChat(nick);
404 }
406 void Roster::sendFileCallback()
407 {
408 Glib::RefPtr<Gtk::TreeModel> model = rosterView.get_model();
409 Glib::RefPtr<Gtk::TreeSelection> sel = rosterView.get_selection();
410 Gtk::TreeModel::iterator iter = sel->get_selected();
411 DOMString nick = iter->get_value(rosterColumns.userColumn);
412 //printf("Send file to:%s\n", nick.c_str());
413 if (parent)
414 parent->doSendFile(nick);
415 }
417 void Roster::shareCallback()
418 {
419 Glib::RefPtr<Gtk::TreeModel> model = rosterView.get_model();
420 Glib::RefPtr<Gtk::TreeSelection> sel = rosterView.get_selection();
421 Gtk::TreeModel::iterator iter = sel->get_selected();
422 DOMString nick = iter->get_value(rosterColumns.userColumn);
423 //printf("share to:%s\n", nick.c_str());
424 if (parent)
425 parent->doShare(nick);
426 }
428 bool Roster::buttonPressCallback(GdkEventButton* event)
429 {
430 if( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) )
431 {
432 Gtk::Widget *wid = uiManager->get_widget("/PopupMenu");
433 Gtk::Menu *popupMenu = dynamic_cast<Gtk::Menu*>(wid);
434 popupMenu->popup(event->button, event->time);
435 return true;
436 }
437 else
438 return false;
439 }
441 bool Roster::doSetup()
442 {
443 set_size_request(200,200);
445 pixbuf_available = Gdk::Pixbuf::create_from_inline(
446 sizeof(icon_available), icon_available, false);
447 pixbuf_away = Gdk::Pixbuf::create_from_inline(
448 sizeof(icon_away), icon_away, false);
449 pixbuf_chat = Gdk::Pixbuf::create_from_inline(
450 sizeof(icon_chat), icon_chat, false);
451 pixbuf_dnd = Gdk::Pixbuf::create_from_inline(
452 sizeof(icon_dnd), icon_dnd, false);
453 pixbuf_error = Gdk::Pixbuf::create_from_inline(
454 sizeof(icon_error), icon_error, false);
455 pixbuf_offline = Gdk::Pixbuf::create_from_inline(
456 sizeof(icon_offline), icon_offline, false);
457 pixbuf_xa = Gdk::Pixbuf::create_from_inline(
458 sizeof(icon_xa), icon_xa, false);
460 rosterView.setParent(this);
461 treeStore = Gtk::TreeStore::create(rosterColumns);
462 rosterView.set_model(treeStore);
464 Gtk::CellRendererText *rend0 = new Gtk::CellRendererText();
465 //rend0->property_background() = "gray";
466 //rend0->property_foreground() = "black";
467 rosterView.append_column("Group", *rend0);
468 Gtk::TreeViewColumn *col0 = rosterView.get_column(0);
469 col0->add_attribute(*rend0, "text", 0);
471 Gtk::CellRendererPixbuf *rend1 = new Gtk::CellRendererPixbuf();
472 rosterView.append_column("Status", *rend1);
473 Gtk::TreeViewColumn *col1 = rosterView.get_column(1);
474 col1->add_attribute(*rend1, "pixbuf", 1);
476 Gtk::CellRendererText *rend2 = new Gtk::CellRendererText();
477 rosterView.append_column("Item", *rend2);
478 Gtk::TreeViewColumn *col2 = rosterView.get_column(2);
479 col2->add_attribute(*rend2, "text", 2);
481 Gtk::CellRendererText *rend3 = new Gtk::CellRendererText();
482 rosterView.append_column("Name", *rend3);
483 Gtk::TreeViewColumn *col3 = rosterView.get_column(3);
484 col3->add_attribute(*rend3, "text", 3);
486 Gtk::CellRendererText *rend4 = new Gtk::CellRendererText();
487 rosterView.append_column("Subscription", *rend4);
488 Gtk::TreeViewColumn *col4 = rosterView.get_column(4);
489 col4->add_attribute(*rend4, "text", 4);
491 rosterView.signal_row_activated().connect(
492 sigc::mem_fun(*this, &Roster::doubleClickCallback) );
494 add(rosterView);
495 set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS);
497 //##### POPUP MENU
498 Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
500 actionGroup->add( Gtk::Action::create("UserMenu", "_User Menu") );
502 actionGroup->add( Gtk::Action::create("Chat",
503 Gtk::Stock::CONNECT, "Chat"),
504 sigc::mem_fun(*this, &Roster::chatCallback) );
505 actionGroup->add( Gtk::Action::create("SendFile",
506 Gtk::Stock::CONNECT, "Send file"),
507 sigc::mem_fun(*this, &Roster::sendFileCallback) );
508 actionGroup->add( Gtk::Action::create("Share",
509 Gtk::Stock::CONNECT, "Share whiteboard"),
510 sigc::mem_fun(*this, &Roster::shareCallback) );
513 uiManager = Gtk::UIManager::create();
515 uiManager->insert_action_group(actionGroup, 0);
517 Glib::ustring ui_info =
518 "<ui>"
519 " <popup name='PopupMenu'>"
520 " <menuitem action='Chat'/>"
521 " <menuitem action='SendFile'/>"
522 " <menuitem action='Share'/>"
523 " </popup>"
524 "</ui>";
526 uiManager->add_ui_from_string(ui_info);
529 show_all_children();
531 return true;
532 }
535 /**
536 * Clear the roster
537 */
538 void Roster::clear()
539 {
540 treeStore->clear();
541 }
543 /**
544 * Regenerate the roster
545 */
546 void Roster::refresh()
547 {
548 if (!parent)
549 return;
550 treeStore->clear();
551 std::vector<XmppUser> items = parent->client.getRoster();
553 //## Add in tree fashion
554 DOMString lastGroup = "";
555 Gtk::TreeModel::Row row = *(treeStore->append());
556 row[rosterColumns.groupColumn] = "";
557 for (unsigned int i=0 ; i<items.size() ; i++)
558 {
559 XmppUser user = items[i];
560 if (user.group != lastGroup)
561 {
562 if (lastGroup.size()>0)
563 row = *(treeStore->append());
564 row[rosterColumns.groupColumn] = user.group;
565 lastGroup = user.group;
566 }
567 Glib::RefPtr<Gdk::Pixbuf> pb = pixbuf_offline;
568 if (user.show == "available")
569 pb = pixbuf_available;
570 else if (user.show == "away")
571 pb = pixbuf_away;
572 else if (user.show == "chat")
573 pb = pixbuf_chat;
574 else if (user.show == "dnd")
575 pb = pixbuf_dnd;
576 else if (user.show == "xa")
577 pb = pixbuf_xa;
578 else
579 {
580 //printf("Unknown show for %s:'%s'\n", user.c_str(), show.c_str());
581 }
582 Gtk::TreeModel::Row childRow = *(treeStore->append(row.children()));
583 childRow[rosterColumns.statusColumn] = pb;
584 childRow[rosterColumns.userColumn] = user.jid;
585 childRow[rosterColumns.nameColumn] = user.nick;
586 childRow[rosterColumns.subColumn] = user.subscription;
587 }
588 rosterView.expand_all();
589 }
591 //#########################################################################
592 //# M E S S A G E L I S T
593 //#########################################################################
595 bool MessageList::doSetup()
596 {
597 set_size_request(400,200);
599 messageListBuffer = Gtk::TextBuffer::create();
600 messageList.set_buffer(messageListBuffer);
601 messageList.set_editable(false);
602 messageList.set_wrap_mode(Gtk::WRAP_WORD_CHAR);
604 Glib::RefPtr<Gtk::TextBuffer::TagTable> table =
605 messageListBuffer->get_tag_table();
606 Glib::RefPtr<Gtk::TextBuffer::Tag> color0 =
607 Gtk::TextBuffer::Tag::create("color0");
608 color0->property_foreground() = "DarkGreen";
609 color0->property_weight() = Pango::WEIGHT_BOLD;
610 table->add(color0);
611 Glib::RefPtr<Gtk::TextBuffer::Tag> color1 =
612 Gtk::TextBuffer::Tag::create("color1");
613 color1->property_foreground() = "chocolate4";
614 color1->property_weight() = Pango::WEIGHT_BOLD;
615 table->add(color1);
616 Glib::RefPtr<Gtk::TextBuffer::Tag> color2 =
617 Gtk::TextBuffer::Tag::create("color2");
618 color2->property_foreground() = "red4";
619 color2->property_weight() = Pango::WEIGHT_BOLD;
620 table->add(color2);
621 Glib::RefPtr<Gtk::TextBuffer::Tag> color3 =
622 Gtk::TextBuffer::Tag::create("color3");
623 color3->property_foreground() = "MidnightBlue";
624 color3->property_weight() = Pango::WEIGHT_BOLD;
625 table->add(color3);
626 Glib::RefPtr<Gtk::TextBuffer::Tag> color4 =
627 Gtk::TextBuffer::Tag::create("color4");
628 color4->property_foreground() = "turquoise4";
629 color4->property_weight() = Pango::WEIGHT_BOLD;
630 table->add(color4);
631 Glib::RefPtr<Gtk::TextBuffer::Tag> color5 =
632 Gtk::TextBuffer::Tag::create("color5");
633 color5->property_foreground() = "OliveDrab";
634 color5->property_weight() = Pango::WEIGHT_BOLD;
635 table->add(color5);
636 Glib::RefPtr<Gtk::TextBuffer::Tag> color6 =
637 Gtk::TextBuffer::Tag::create("color6");
638 color6->property_foreground() = "purple4";
639 color6->property_weight() = Pango::WEIGHT_BOLD;
640 table->add(color6);
641 Glib::RefPtr<Gtk::TextBuffer::Tag> color7 =
642 Gtk::TextBuffer::Tag::create("color7");
643 color7->property_foreground() = "VioletRed4";
644 color7->property_weight() = Pango::WEIGHT_BOLD;
645 table->add(color7);
647 add(messageList);
648 set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS);
651 show_all_children();
653 return true;
654 }
656 /**
657 * Clear all messages from the list
658 */
659 void MessageList::clear()
660 {
661 messageListBuffer->erase(messageListBuffer->begin(),
662 messageListBuffer->end());
663 }
666 /**
667 * Post a message to the list
668 */
669 void MessageList::postMessage(const DOMString &from, const DOMString &msg)
670 {
671 DOMString out = "<";
672 out.append(from);
673 out.append("> ");
675 int val = 0;
676 for (unsigned int i=0 ; i<from.size() ; i++)
677 val += from[i];
678 val = val % 8;
680 char buf[16];
681 sprintf(buf, "color%d", val);
682 DOMString tagName = buf;
684 messageListBuffer->insert_with_tag(
685 messageListBuffer->end(), out, tagName);
686 messageListBuffer->insert(messageListBuffer->end(), msg);
687 messageListBuffer->insert(messageListBuffer->end(), "\n");
688 //Gtk::Adjustment *adj = get_vadjustment();
689 //adj->set_value(adj->get_upper()-adj->get_page_size());
690 Glib::RefPtr<Gtk::TextBuffer::Mark> mark =
691 messageListBuffer->create_mark("temp", messageListBuffer->end());
692 messageList.scroll_mark_onscreen(mark);
693 messageListBuffer->delete_mark(mark);
694 }
698 //#########################################################################
699 //# U S E R L I S T
700 //#########################################################################
701 void UserList::doubleClickCallback(const Gtk::TreeModel::Path &path,
702 Gtk::TreeViewColumn *col)
703 {
704 Glib::RefPtr<Gtk::TreeModel> model = userList.get_model();
705 Glib::RefPtr<Gtk::TreeSelection> sel = userList.get_selection();
706 Gtk::TreeModel::iterator iter = sel->get_selected();
707 DOMString nick = iter->get_value(userListColumns.userColumn);
708 //printf("Double clicked:%s\n", nick.c_str());
709 if (parent)
710 parent->doChat(nick);
712 }
714 void UserList::chatCallback()
715 {
716 Glib::RefPtr<Gtk::TreeModel> model = userList.get_model();
717 Glib::RefPtr<Gtk::TreeSelection> sel = userList.get_selection();
718 Gtk::TreeModel::iterator iter = sel->get_selected();
719 DOMString nick = iter->get_value(userListColumns.userColumn);
720 //printf("Chat with:%s\n", nick.c_str());
721 if (parent)
722 parent->doChat(nick);
723 }
725 void UserList::sendFileCallback()
726 {
727 Glib::RefPtr<Gtk::TreeModel> model = userList.get_model();
728 Glib::RefPtr<Gtk::TreeSelection> sel = userList.get_selection();
729 Gtk::TreeModel::iterator iter = sel->get_selected();
730 DOMString nick = iter->get_value(userListColumns.userColumn);
731 //printf("Send file to:%s\n", nick.c_str());
732 if (parent)
733 parent->doSendFile(nick);
734 }
736 void UserList::shareCallback()
737 {
738 Glib::RefPtr<Gtk::TreeModel> model = userList.get_model();
739 Glib::RefPtr<Gtk::TreeSelection> sel = userList.get_selection();
740 Gtk::TreeModel::iterator iter = sel->get_selected();
741 DOMString nick = iter->get_value(userListColumns.userColumn);
742 //printf("Send file to:%s\n", nick.c_str());
743 if (parent)
744 parent->doShare(nick);
745 }
747 bool UserList::buttonPressCallback(GdkEventButton* event)
748 {
749 if( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) )
750 {
751 Gtk::Widget *wid = uiManager->get_widget("/PopupMenu");
752 Gtk::Menu *popupMenu = dynamic_cast<Gtk::Menu*>(wid);
753 popupMenu->popup(event->button, event->time);
754 return true;
755 }
756 else
757 return false;
758 }
760 bool UserList::doSetup()
761 {
762 set_size_request(200,200);
764 setParent(NULL);
766 pixbuf_available = Gdk::Pixbuf::create_from_inline(
767 sizeof(icon_available), icon_available, false);
768 pixbuf_away = Gdk::Pixbuf::create_from_inline(
769 sizeof(icon_away), icon_away, false);
770 pixbuf_chat = Gdk::Pixbuf::create_from_inline(
771 sizeof(icon_chat), icon_chat, false);
772 pixbuf_dnd = Gdk::Pixbuf::create_from_inline(
773 sizeof(icon_dnd), icon_dnd, false);
774 pixbuf_error = Gdk::Pixbuf::create_from_inline(
775 sizeof(icon_error), icon_error, false);
776 pixbuf_offline = Gdk::Pixbuf::create_from_inline(
777 sizeof(icon_offline), icon_offline, false);
778 pixbuf_xa = Gdk::Pixbuf::create_from_inline(
779 sizeof(icon_xa), icon_xa, false);
781 userList.setParent(this);
782 userListStore = Gtk::ListStore::create(userListColumns);
783 userList.set_model(userListStore);
785 Gtk::CellRendererPixbuf *rend0 = new Gtk::CellRendererPixbuf();
786 userList.append_column("Status", *rend0);
787 Gtk::TreeViewColumn *col0 = userList.get_column(0);
788 col0->add_attribute(*rend0, "pixbuf", 0);
790 Gtk::CellRendererText *rend1 = new Gtk::CellRendererText();
791 //rend1->property_background() = "gray";
792 //rend1->property_foreground() = "black";
793 userList.append_column("User", *rend1);
794 Gtk::TreeViewColumn *col1 = userList.get_column(1);
795 col1->add_attribute(*rend1, "text", 1);
797 userList.set_headers_visible(false);
799 userList.signal_row_activated().connect(
800 sigc::mem_fun(*this, &UserList::doubleClickCallback) );
802 add(userList);
803 set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS);
805 //##### POPUP MENU
806 Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
808 actionGroup->add( Gtk::Action::create("UserMenu", "_User Menu") );
810 actionGroup->add( Gtk::Action::create("Chat",
811 Gtk::Stock::CONNECT, "Chat"),
812 sigc::mem_fun(*this, &UserList::chatCallback) );
813 actionGroup->add( Gtk::Action::create("SendFile",
814 Gtk::Stock::CONNECT, "Send file"),
815 sigc::mem_fun(*this, &UserList::sendFileCallback) );
816 actionGroup->add( Gtk::Action::create("Share",
817 Gtk::Stock::CONNECT, "Share whiteboard"),
818 sigc::mem_fun(*this, &UserList::shareCallback) );
821 uiManager = Gtk::UIManager::create();
823 uiManager->insert_action_group(actionGroup, 0);
825 Glib::ustring ui_info =
826 "<ui>"
827 " <popup name='PopupMenu'>"
828 " <menuitem action='Chat'/>"
829 " <menuitem action='SendFile'/>"
830 " <menuitem action='Share'/>"
831 " </popup>"
832 "</ui>";
834 uiManager->add_ui_from_string(ui_info);
836 show_all_children();
838 return true;
839 }
841 /**
842 * Clear all messages from the list
843 */
844 void UserList::clear()
845 {
846 userListStore->clear();
847 }
850 /**
851 * Add a user to the list
852 */
853 void UserList::addUser(const DOMString &user, const DOMString &show)
854 {
855 Glib::RefPtr<Gdk::Pixbuf> pb = pixbuf_offline;
856 if (show == "available")
857 pb = pixbuf_available;
858 else if (show == "away")
859 pb = pixbuf_away;
860 else if (show == "chat")
861 pb = pixbuf_chat;
862 else if (show == "dnd")
863 pb = pixbuf_dnd;
864 else if (show == "xa")
865 pb = pixbuf_xa;
866 else
867 {
868 //printf("Unknown show for %s:'%s'\n", user.c_str(), show.c_str());
869 }
870 Gtk::TreeModel::Row row = *(userListStore->append());
871 row[userListColumns.userColumn] = user;
872 row[userListColumns.statusColumn] = pb;
873 }
878 //#########################################################################
879 //# C H A T W I N D O W
880 //#########################################################################
881 ChatWindow::ChatWindow(PedroGui &par, const DOMString jidArg)
882 : parent(par)
883 {
884 jid = jidArg;
885 doSetup();
886 }
888 ChatWindow::~ChatWindow()
889 {
890 }
892 void ChatWindow::leaveCallback()
893 {
894 hide();
895 parent.chatDelete(jid);
896 }
899 void ChatWindow::hideCallback()
900 {
901 hide();
902 parent.chatDelete(jid);
903 }
905 void ChatWindow::shareCallback()
906 {
907 // hide();
908 parent.doShare(this->jid);
909 }
911 void ChatWindow::textEnterCallback()
912 {
913 DOMString str = inputTxt.get_text();
914 if (str.size() > 0)
915 parent.client.message(jid, str);
916 inputTxt.set_text("");
917 messageList.postMessage(parent.client.getJid(), str);
918 }
920 bool ChatWindow::doSetup()
921 {
922 DOMString title = "Private Chat - ";
923 title.append(jid);
924 set_title(title);
926 set_size_request(500,300);
928 signal_hide().connect(
929 sigc::mem_fun(*this, &ChatWindow::hideCallback) );
931 Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
932 actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
933 actionGroup->add( Gtk::Action::create("Leave", Gtk::Stock::CANCEL),
934 sigc::mem_fun(*this, &ChatWindow::leaveCallback) );
935 actionGroup->add( Gtk::Action::create("Share", Gtk::Stock::CONNECT,
936 "Share whiteboard"), sigc::mem_fun(*this, &ChatWindow::shareCallback) );
939 Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
941 uiManager->insert_action_group(actionGroup, 0);
942 add_accel_group(uiManager->get_accel_group());
944 Glib::ustring ui_info =
945 "<ui>"
946 " <menubar name='MenuBar'>"
947 " <menu action='MenuFile'>"
948 " <menuitem action='Leave'/>"
949 " <menuitem action='Share'/>"
950 " </menu>"
951 " </menubar>"
952 "</ui>";
954 add(vbox);
956 uiManager->add_ui_from_string(ui_info);
957 Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
958 vbox.pack_start(*pMenuBar, Gtk::PACK_SHRINK);
960 vbox.pack_end(vPaned);
962 vPaned.add1(messageList);
963 vPaned.add2(inputTxt);
965 inputTxt.signal_activate().connect(
966 sigc::mem_fun(*this, &ChatWindow::textEnterCallback) );
968 show_all_children();
970 return true;
971 }
973 bool ChatWindow::postMessage(const DOMString &data)
974 {
975 messageList.postMessage(jid, data);
976 return true;
977 }
979 //#########################################################################
980 //# G R O U P C H A T W I N D O W
981 //#########################################################################
983 GroupChatWindow::GroupChatWindow(PedroGui &par,
984 const DOMString &groupJidArg,
985 const DOMString &nickArg)
986 : parent(par)
987 {
988 groupJid = groupJidArg;
989 nick = nickArg;
990 doSetup();
991 }
993 GroupChatWindow::~GroupChatWindow()
994 {
995 }
998 void GroupChatWindow::leaveCallback()
999 {
1000 parent.client.groupChatLeave(groupJid, nick);
1001 hide();
1002 parent.groupChatDelete(groupJid, nick);
1003 }
1005 void GroupChatWindow::hideCallback()
1006 {
1007 parent.client.groupChatLeave(groupJid, nick);
1008 hide();
1009 parent.groupChatDelete(groupJid, nick);
1010 }
1012 void GroupChatWindow::textEnterCallback()
1013 {
1014 DOMString str = inputTxt.get_text();
1015 if (str.size() > 0)
1016 parent.client.groupChatMessage(groupJid, str);
1017 inputTxt.set_text("");
1018 }
1020 void GroupChatWindow::shareCallback()
1021 {
1022 parent.doGroupShare(groupJid);
1023 }
1025 bool GroupChatWindow::doSetup()
1026 {
1027 DOMString title = "Group Chat - ";
1028 title.append(groupJid);
1029 set_title(title);
1031 userList.setParent(this);
1033 set_size_request(500,300);
1035 signal_hide().connect(
1036 sigc::mem_fun(*this, &GroupChatWindow::hideCallback) );
1038 Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
1039 actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
1040 actionGroup->add( Gtk::Action::create("Leave", Gtk::Stock::CANCEL),
1041 sigc::mem_fun(*this, &GroupChatWindow::leaveCallback) );
1042 actionGroup->add( Gtk::Action::create("Share", Gtk::Stock::CONNECT, "Share whiteboard"),
1043 sigc::mem_fun(*this, &GroupChatWindow::shareCallback) );
1046 Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
1048 uiManager->insert_action_group(actionGroup, 0);
1049 add_accel_group(uiManager->get_accel_group());
1051 Glib::ustring ui_info =
1052 "<ui>"
1053 " <menubar name='MenuBar'>"
1054 " <menu action='MenuFile'>"
1055 " <menuitem action='Leave'/>"
1056 " <menuitem action='Share'/>"
1057 " </menu>"
1058 " </menubar>"
1059 "</ui>";
1061 add(vbox);
1062 uiManager->add_ui_from_string(ui_info);
1063 Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
1064 vbox.pack_start(*pMenuBar, Gtk::PACK_SHRINK);
1066 vbox.pack_end(vPaned);
1068 vPaned.add1(hPaned);
1069 vPaned.add2(inputTxt);
1070 inputTxt.signal_activate().connect(
1071 sigc::mem_fun(*this, &GroupChatWindow::textEnterCallback) );
1074 hPaned.add1(messageList);
1075 hPaned.add2(userList);
1078 show_all_children();
1081 return true;
1082 }
1084 bool GroupChatWindow::receiveMessage(const DOMString &from,
1085 const DOMString &data)
1086 {
1087 messageList.postMessage(from, data);
1088 return true;
1089 }
1091 bool GroupChatWindow::receivePresence(const DOMString &fromNick,
1092 bool presence,
1093 const DOMString &show,
1094 const DOMString &status)
1095 {
1097 DOMString presStr = "";
1098 presStr.append(fromNick);
1099 if (!presence)
1100 presStr.append(" left the group");
1101 else
1102 {
1103 if (show.size()<1)
1104 presStr.append(" joined the group");
1105 else
1106 {
1107 presStr.append(" : ");
1108 presStr.append(show);
1109 }
1110 }
1112 if (presStr != "xa")
1113 messageList.postMessage("*", presStr);
1115 userList.clear();
1116 std::vector<XmppUser> memberList =
1117 parent.client.groupChatGetUserList(groupJid);
1118 for (unsigned int i=0 ; i<memberList.size() ; i++)
1119 {
1120 XmppUser user = memberList[i];
1121 userList.addUser(user.nick, user.show);
1122 }
1123 return true;
1124 }
1127 void GroupChatWindow::doChat(const DOMString &nick)
1128 {
1129 printf("##Chat with %s\n", nick.c_str());
1130 DOMString fullJid = groupJid;
1131 fullJid.append("/");
1132 fullJid.append(nick);
1133 parent.doChat(fullJid);
1134 }
1136 void GroupChatWindow::doSendFile(const DOMString &nick)
1137 {
1138 printf("##Send file to %s\n", nick.c_str());
1139 DOMString fullJid = groupJid;
1140 fullJid.append("/");
1141 fullJid.append(nick);
1142 parent.doSendFile(fullJid);
1144 }
1146 void GroupChatWindow::doShare(const DOMString &nick)
1147 {
1148 printf("##Share inkboard with %s\n", nick.c_str());
1149 DOMString fullJid = groupJid;
1150 fullJid.append("/");
1151 fullJid.append(nick);
1152 parent.doShare(fullJid);
1154 }
1157 //#########################################################################
1158 //# C O N F I G D I A L O G
1159 //#########################################################################
1162 void ConfigDialog::okCallback()
1163 {
1164 Glib::ustring pass = passField.get_text();
1165 Glib::ustring newpass = newField.get_text();
1166 Glib::ustring confpass = confField.get_text();
1167 if ((pass.size() < 5 || pass.size() > 12 ) ||
1168 (newpass.size() < 5 || newpass.size() > 12 ) ||
1169 (confpass.size() < 5 || confpass.size()> 12 ))
1170 {
1171 Gtk::MessageDialog dlg(*this, "Password must be 5 to 12 characters",
1172 false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
1173 dlg.run();
1174 }
1175 else if (newpass != confpass)
1176 {
1177 Gtk::MessageDialog dlg(*this, "New password and confirmation do not match",
1178 false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
1179 dlg.run();
1180 }
1181 else
1182 {
1183 //response(Gtk::RESPONSE_OK);
1184 hide();
1185 }
1186 }
1188 void ConfigDialog::cancelCallback()
1189 {
1190 //response(Gtk::RESPONSE_CANCEL);
1191 hide();
1192 }
1194 void ConfigDialog::on_response(int response_id)
1195 {
1196 if (response_id == Gtk::RESPONSE_OK)
1197 okCallback();
1198 else
1199 cancelCallback();
1200 }
1202 bool ConfigDialog::doSetup()
1203 {
1204 set_title("Change Password");
1205 set_size_request(300,200);
1207 Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
1208 actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
1209 actionGroup->add( Gtk::Action::create("Change", Gtk::Stock::OK, "Change Password"),
1210 sigc::mem_fun(*this, &ConfigDialog::okCallback) );
1211 actionGroup->add( Gtk::Action::create("Cancel", Gtk::Stock::CANCEL, "Cancel"),
1212 sigc::mem_fun(*this, &ConfigDialog::cancelCallback) );
1215 Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
1217 uiManager->insert_action_group(actionGroup, 0);
1218 add_accel_group(uiManager->get_accel_group());
1220 Glib::ustring ui_info =
1221 "<ui>"
1222 " <menubar name='MenuBar'>"
1223 " <menu action='MenuFile'>"
1224 " <menuitem action='Change'/>"
1225 " <separator/>"
1226 " <menuitem action='Cancel'/>"
1227 " </menu>"
1228 " </menubar>"
1229 "</ui>";
1231 uiManager->add_ui_from_string(ui_info);
1232 Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
1233 get_vbox()->pack_start(*pMenuBar, Gtk::PACK_SHRINK);
1235 table.resize(3, 2);
1236 get_vbox()->pack_start(table);
1238 passLabel.set_text("Current Password");
1239 table.attach(passLabel, 0, 1, 0, 1);
1240 passField.set_visibility(false);
1241 passField.set_text(parent.client.getPassword());
1242 table.attach(passField, 1, 2, 0, 1);
1244 newLabel.set_text("New Password");
1245 table.attach(newLabel, 0, 1, 1, 2);
1246 newField.set_visibility(false);
1247 table.attach(newField, 1, 2, 1, 2);
1249 confLabel.set_text("Confirm New Password");
1250 table.attach(confLabel, 0, 1, 2, 3);
1251 confField.set_visibility(false);
1252 confField.signal_activate().connect(
1253 sigc::mem_fun(*this, &ConfigDialog::okCallback) );
1254 table.attach(confField, 1, 2, 2, 3);
1256 add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1257 add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
1259 show_all_children();
1261 return true;
1262 }
1264 //#########################################################################
1265 //# P A S S W O R D D I A L O G
1266 //#########################################################################
1269 void PasswordDialog::okCallback()
1270 {
1271 Glib::ustring pass = passField.get_text();
1272 Glib::ustring newpass = newField.get_text();
1273 Glib::ustring confpass = confField.get_text();
1274 if ((pass.size() < 5 || pass.size() > 12 ) ||
1275 (newpass.size() < 5 || newpass.size() > 12 ) ||
1276 (confpass.size() < 5 || confpass.size()> 12 ))
1277 {
1278 Gtk::MessageDialog dlg(*this, "Password must be 5 to 12 characters",
1279 false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
1280 dlg.run();
1281 }
1282 else if (newpass != confpass)
1283 {
1284 Gtk::MessageDialog dlg(*this, "New password and confirmation do not match",
1285 false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
1286 dlg.run();
1287 }
1288 else
1289 {
1290 //response(Gtk::RESPONSE_OK);
1291 hide();
1292 }
1293 }
1295 void PasswordDialog::cancelCallback()
1296 {
1297 //response(Gtk::RESPONSE_CANCEL);
1298 hide();
1299 }
1301 void PasswordDialog::on_response(int response_id)
1302 {
1303 if (response_id == Gtk::RESPONSE_OK)
1304 okCallback();
1305 else
1306 cancelCallback();
1307 }
1309 bool PasswordDialog::doSetup()
1310 {
1311 set_title("Change Password");
1312 set_size_request(300,200);
1314 Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
1315 actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
1316 actionGroup->add( Gtk::Action::create("Change", Gtk::Stock::OK, "Change Password"),
1317 sigc::mem_fun(*this, &PasswordDialog::okCallback) );
1318 actionGroup->add( Gtk::Action::create("Cancel", Gtk::Stock::CANCEL, "Cancel"),
1319 sigc::mem_fun(*this, &PasswordDialog::cancelCallback) );
1322 Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
1324 uiManager->insert_action_group(actionGroup, 0);
1325 add_accel_group(uiManager->get_accel_group());
1327 Glib::ustring ui_info =
1328 "<ui>"
1329 " <menubar name='MenuBar'>"
1330 " <menu action='MenuFile'>"
1331 " <menuitem action='Change'/>"
1332 " <separator/>"
1333 " <menuitem action='Cancel'/>"
1334 " </menu>"
1335 " </menubar>"
1336 "</ui>";
1338 uiManager->add_ui_from_string(ui_info);
1339 Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
1340 get_vbox()->pack_start(*pMenuBar, Gtk::PACK_SHRINK);
1342 table.resize(3, 2);
1343 get_vbox()->pack_start(table);
1345 passLabel.set_text("Current Password");
1346 table.attach(passLabel, 0, 1, 0, 1);
1347 passField.set_visibility(false);
1348 passField.set_text(parent.client.getPassword());
1349 table.attach(passField, 1, 2, 0, 1);
1351 newLabel.set_text("New Password");
1352 table.attach(newLabel, 0, 1, 1, 2);
1353 newField.set_visibility(false);
1354 table.attach(newField, 1, 2, 1, 2);
1356 confLabel.set_text("Confirm New Password");
1357 table.attach(confLabel, 0, 1, 2, 3);
1358 confField.set_visibility(false);
1359 confField.signal_activate().connect(
1360 sigc::mem_fun(*this, &PasswordDialog::okCallback) );
1361 table.attach(confField, 1, 2, 2, 3);
1363 add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1364 add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
1366 show_all_children();
1368 return true;
1369 }
1371 //#########################################################################
1372 //# C H A T D I A L O G
1373 //#########################################################################
1376 void ChatDialog::okCallback()
1377 {
1378 response(Gtk::RESPONSE_OK);
1379 hide();
1380 }
1382 void ChatDialog::cancelCallback()
1383 {
1384 response(Gtk::RESPONSE_CANCEL);
1385 hide();
1386 }
1389 bool ChatDialog::doSetup()
1390 {
1391 set_title("Chat with User");
1392 set_size_request(300,200);
1394 Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
1395 actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
1396 actionGroup->add( Gtk::Action::create("Chat", Gtk::Stock::CONNECT, "Chat"),
1397 sigc::mem_fun(*this, &ChatDialog::okCallback) );
1398 actionGroup->add( Gtk::Action::create("Cancel", Gtk::Stock::CANCEL, "Cancel"),
1399 sigc::mem_fun(*this, &ChatDialog::cancelCallback) );
1402 Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
1404 uiManager->insert_action_group(actionGroup, 0);
1405 add_accel_group(uiManager->get_accel_group());
1407 Glib::ustring ui_info =
1408 "<ui>"
1409 " <menubar name='MenuBar'>"
1410 " <menu action='MenuFile'>"
1411 " <menuitem action='Chat'/>"
1412 " <separator/>"
1413 " <menuitem action='Cancel'/>"
1414 " </menu>"
1415 " </menubar>"
1416 "</ui>";
1418 uiManager->add_ui_from_string(ui_info);
1419 Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
1420 get_vbox()->pack_start(*pMenuBar, Gtk::PACK_SHRINK);
1422 table.resize(2, 2);
1423 get_vbox()->pack_start(table);
1425 userLabel.set_text("User");
1426 table.attach(userLabel, 0, 1, 0, 1);
1427 //userField.set_text("");
1428 table.attach(userField, 1, 2, 0, 1);
1430 //userField.set_text("");
1431 table.attach(textField, 0, 2, 1, 2);
1433 add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1434 add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
1436 show_all_children();
1438 return true;
1439 }
1441 //#########################################################################
1442 //# G R O U P C H A T D I A L O G
1443 //#########################################################################
1446 void GroupChatDialog::okCallback()
1447 {
1448 response(Gtk::RESPONSE_OK);
1449 hide();
1450 }
1452 void GroupChatDialog::cancelCallback()
1453 {
1454 response(Gtk::RESPONSE_CANCEL);
1455 hide();
1456 }
1459 bool GroupChatDialog::doSetup()
1460 {
1461 set_title("Join Group Chat");
1462 set_size_request(300,200);
1464 Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
1465 actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
1466 actionGroup->add( Gtk::Action::create("Join", Gtk::Stock::CONNECT, "Join Group"),
1467 sigc::mem_fun(*this, &GroupChatDialog::okCallback) );
1468 actionGroup->add( Gtk::Action::create("Cancel", Gtk::Stock::CANCEL, "Cancel"),
1469 sigc::mem_fun(*this, &GroupChatDialog::cancelCallback) );
1472 Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
1474 uiManager->insert_action_group(actionGroup, 0);
1475 add_accel_group(uiManager->get_accel_group());
1477 Glib::ustring ui_info =
1478 "<ui>"
1479 " <menubar name='MenuBar'>"
1480 " <menu action='MenuFile'>"
1481 " <menuitem action='Join'/>"
1482 " <separator/>"
1483 " <menuitem action='Cancel'/>"
1484 " </menu>"
1485 " </menubar>"
1486 "</ui>";
1488 uiManager->add_ui_from_string(ui_info);
1489 Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
1490 get_vbox()->pack_start(*pMenuBar, Gtk::PACK_SHRINK);
1492 table.resize(4, 2);
1493 get_vbox()->pack_start(table);
1495 groupLabel.set_text("Group");
1496 table.attach(groupLabel, 0, 1, 0, 1);
1497 groupField.set_text(parent.config.getMucGroup());
1498 table.attach(groupField, 1, 2, 0, 1);
1500 hostLabel.set_text("Host");
1501 table.attach(hostLabel, 0, 1, 1, 2);
1502 hostField.set_text(parent.config.getMucHost());
1503 table.attach(hostField, 1, 2, 1, 2);
1505 nickLabel.set_text("Alt Name");
1506 table.attach(nickLabel, 0, 1, 2, 3);
1507 nickField.set_text(parent.config.getMucNick());
1508 table.attach(nickField, 1, 2, 2, 3);
1510 passLabel.set_text("Password");
1511 table.attach(passLabel, 0, 1, 3, 4);
1512 passField.set_visibility(false);
1513 passField.set_text(parent.config.getMucPassword());
1514 table.attach(passField, 1, 2, 3, 4);
1517 add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1518 add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
1520 show_all_children();
1522 return true;
1523 }
1528 //#########################################################################
1529 //# C O N N E C T D I A L O G
1530 //#########################################################################
1533 void ConnectDialog::okCallback()
1534 {
1535 response(Gtk::RESPONSE_OK);
1536 hide();
1537 }
1539 void ConnectDialog::saveCallback()
1540 {
1541 Gtk::Entry txtField;
1542 Gtk::Dialog dlg("Account name", *this, true, true);
1543 dlg.get_vbox()->pack_start(txtField);
1544 txtField.signal_activate().connect(
1545 sigc::bind(sigc::mem_fun(dlg, &Gtk::Dialog::response),
1546 Gtk::RESPONSE_OK ));
1547 dlg.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1548 dlg.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
1549 dlg.show_all_children();
1550 int ret = dlg.run();
1551 if (ret != Gtk::RESPONSE_OK)
1552 return;
1554 Glib::ustring name = txtField.get_text();
1555 if (name.size() < 1)
1556 {
1557 parent.error("Account name too short");
1558 return;
1559 }
1561 if (parent.config.accountExists(name))
1562 {
1563 parent.config.accountRemove(name);
1564 }
1566 XmppAccount account;
1567 account.setName(name);
1568 account.setHost(getHost());
1569 account.setPort(getPort());
1570 account.setUsername(getUser());
1571 account.setPassword(getPass());
1572 parent.config.accountAdd(account);
1574 refresh();
1576 parent.configSave();
1577 }
1579 void ConnectDialog::cancelCallback()
1580 {
1581 response(Gtk::RESPONSE_CANCEL);
1582 hide();
1583 }
1586 void ConnectDialog::doubleClickCallback(
1587 const Gtk::TreeModel::Path &path,
1588 Gtk::TreeViewColumn *col)
1589 {
1590 Glib::RefPtr<Gtk::TreeModel> model = accountView.get_model();
1591 Glib::RefPtr<Gtk::TreeSelection> sel = accountView.get_selection();
1592 Gtk::TreeModel::iterator iter = sel->get_selected();
1593 DOMString name = iter->get_value(accountColumns.nameColumn);
1594 //printf("Double clicked:%s\n", name.c_str());
1595 XmppAccount account;
1596 if (!parent.config.accountFind(name, account))
1597 return;
1598 setHost(account.getHost());
1599 setPort(account.getPort());
1600 setUser(account.getUsername());
1601 setPass(account.getPassword());
1603 response(Gtk::RESPONSE_OK);
1604 hide();
1605 }
1607 void ConnectDialog::selectedCallback()
1608 {
1609 Glib::RefPtr<Gtk::TreeModel> model = accountView.get_model();
1610 Glib::RefPtr<Gtk::TreeSelection> sel = accountView.get_selection();
1611 Gtk::TreeModel::iterator iter = sel->get_selected();
1612 DOMString name = iter->get_value(accountColumns.nameColumn);
1613 //printf("Single clicked:%s\n", name.c_str());
1614 XmppAccount account;
1615 if (!parent.config.accountFind(name, account))
1616 return;
1617 setHost(account.getHost());
1618 setPort(account.getPort());
1619 setUser(account.getUsername());
1620 setPass(account.getPassword());
1621 }
1623 void ConnectDialog::deleteCallback()
1624 {
1625 Glib::RefPtr<Gtk::TreeModel> model = accountView.get_model();
1626 Glib::RefPtr<Gtk::TreeSelection> sel = accountView.get_selection();
1627 Gtk::TreeModel::iterator iter = sel->get_selected();
1628 DOMString name = iter->get_value(accountColumns.nameColumn);
1630 parent.config.accountRemove(name);
1631 refresh();
1632 parent.configSave();
1634 }
1638 void ConnectDialog::buttonPressCallback(GdkEventButton* event)
1639 {
1640 if( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) )
1641 {
1642 Gtk::Widget *wid = accountUiManager->get_widget("/PopupMenu");
1643 Gtk::Menu *popupMenu = dynamic_cast<Gtk::Menu*>(wid);
1644 popupMenu->popup(event->button, event->time);
1645 }
1646 }
1649 bool ConnectDialog::doSetup()
1650 {
1651 set_title("Connect");
1652 set_size_request(300,400);
1654 Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
1655 actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
1656 actionGroup->add( Gtk::Action::create("Connect",
1657 Gtk::Stock::CONNECT, "Connect"),
1658 sigc::mem_fun(*this, &ConnectDialog::okCallback) );
1659 actionGroup->add( Gtk::Action::create("Save",
1660 Gtk::Stock::CONNECT, "Save as account"),
1661 sigc::mem_fun(*this, &ConnectDialog::saveCallback) );
1662 actionGroup->add( Gtk::Action::create("Cancel",
1663 Gtk::Stock::CANCEL, "Cancel"),
1664 sigc::mem_fun(*this, &ConnectDialog::cancelCallback) );
1667 Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
1669 uiManager->insert_action_group(actionGroup, 0);
1670 add_accel_group(uiManager->get_accel_group());
1672 Glib::ustring ui_info =
1673 "<ui>"
1674 " <menubar name='MenuBar'>"
1675 " <menu action='MenuFile'>"
1676 " <menuitem action='Connect'/>"
1677 " <separator/>"
1678 " <menuitem action='Save'/>"
1679 " <separator/>"
1680 " <menuitem action='Cancel'/>"
1681 " </menu>"
1682 " </menubar>"
1683 "</ui>";
1685 uiManager->add_ui_from_string(ui_info);
1686 Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
1687 get_vbox()->pack_start(*pMenuBar, Gtk::PACK_SHRINK);
1689 table.resize(6, 2);
1690 get_vbox()->pack_start(table);
1692 parent.client.setHost("broadway.dynalias.com");
1693 parent.client.setPort(5222);
1694 parent.client.setUsername("");
1695 parent.client.setPassword("");
1696 parent.client.setResource("pedroXmpp");
1698 hostLabel.set_text("Host");
1699 table.attach(hostLabel, 0, 1, 0, 1);
1700 hostField.set_text(parent.client.getHost());
1701 table.attach(hostField, 1, 2, 0, 1);
1703 portLabel.set_text("Port");
1704 table.attach(portLabel, 0, 1, 1, 2);
1705 portSpinner.set_digits(0);
1706 portSpinner.set_range(1, 65000);
1707 portSpinner.set_value(parent.client.getPort());
1708 table.attach(portSpinner, 1, 2, 1, 2);
1710 userLabel.set_text("Username");
1711 table.attach(userLabel, 0, 1, 2, 3);
1712 userField.set_text(parent.client.getUsername());
1713 table.attach(userField, 1, 2, 2, 3);
1715 passLabel.set_text("Password");
1716 table.attach(passLabel, 0, 1, 3, 4);
1717 passField.set_visibility(false);
1718 passField.set_text(parent.client.getPassword());
1719 passField.signal_activate().connect(
1720 sigc::mem_fun(*this, &ConnectDialog::okCallback) );
1721 table.attach(passField, 1, 2, 3, 4);
1723 resourceLabel.set_text("Resource");
1724 table.attach(resourceLabel, 0, 1, 4, 5);
1725 resourceField.set_text(parent.client.getResource());
1726 table.attach(resourceField, 1, 2, 4, 5);
1728 registerLabel.set_text("Register");
1729 table.attach(registerLabel, 0, 1, 5, 6);
1730 registerButton.set_active(false);
1731 table.attach(registerButton, 1, 2, 5, 6);
1733 add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1734 add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
1737 //######################
1738 //# ACCOUNT LIST
1739 //######################
1742 accountListStore = Gtk::ListStore::create(accountColumns);
1743 accountView.set_model(accountListStore);
1745 accountView.signal_row_activated().connect(
1746 sigc::mem_fun(*this, &ConnectDialog::doubleClickCallback) );
1748 accountView.get_selection()->signal_changed().connect(
1749 sigc::mem_fun(*this, &ConnectDialog::selectedCallback) );
1751 accountView.append_column("Account", accountColumns.nameColumn);
1752 accountView.append_column("Host", accountColumns.hostColumn);
1754 //accountView.signal_row_activated().connect(
1755 // sigc::mem_fun(*this, &AccountDialog::connectCallback) );
1757 accountScroll.add(accountView);
1758 accountScroll.set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS);
1760 get_vbox()->pack_start(accountScroll);
1762 //##### POPUP MENU
1763 accountView.signal_button_press_event().connect_notify(
1764 sigc::mem_fun(*this, &ConnectDialog::buttonPressCallback) );
1766 Glib::RefPtr<Gtk::ActionGroup> accountActionGroup =
1767 Gtk::ActionGroup::create();
1769 accountActionGroup->add( Gtk::Action::create("PopupMenu", "_Account") );
1771 accountActionGroup->add( Gtk::Action::create("Delete",
1772 Gtk::Stock::DELETE, "Delete"),
1773 sigc::mem_fun(*this, &ConnectDialog::deleteCallback) );
1776 accountUiManager = Gtk::UIManager::create();
1778 accountUiManager->insert_action_group(accountActionGroup, 0);
1780 Glib::ustring account_ui_info =
1781 "<ui>"
1782 " <popup name='PopupMenu'>"
1783 " <menuitem action='Delete'/>"
1784 " </popup>"
1785 "</ui>";
1787 accountUiManager->add_ui_from_string(account_ui_info);
1788 //Gtk::Widget* accountMenuBar = uiManager->get_widget("/PopupMenu");
1789 //get_vbox()->pack_start(*accountMenuBar, Gtk::PACK_SHRINK);
1791 refresh();
1793 show_all_children();
1795 return true;
1796 }
1799 /**
1800 * Regenerate the account list
1801 */
1802 void ConnectDialog::refresh()
1803 {
1804 accountListStore->clear();
1806 std::vector<XmppAccount> accounts = parent.config.getAccounts();
1807 for (unsigned int i=0 ; i<accounts.size() ; i++)
1808 {
1809 XmppAccount account = accounts[i];
1810 Gtk::TreeModel::Row row = *(accountListStore->append());
1811 row[accountColumns.nameColumn] = account.getName();
1812 row[accountColumns.hostColumn] = account.getHost();
1813 }
1814 accountView.expand_all();
1815 }
1819 //#########################################################################
1820 //# F I L E S E N D D I A L O G
1821 //#########################################################################
1824 void FileSendDialog::okCallback()
1825 {
1826 response(Gtk::RESPONSE_OK);
1827 hide();
1828 }
1830 void FileSendDialog::cancelCallback()
1831 {
1832 response(Gtk::RESPONSE_CANCEL);
1833 hide();
1834 }
1837 void FileSendDialog::buttonCallback()
1838 {
1839 Gtk::FileChooserDialog dlg("Select a file to send",
1840 Gtk::FILE_CHOOSER_ACTION_OPEN);
1841 dlg.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1842 dlg.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
1843 int ret = dlg.run();
1844 if (ret == Gtk::RESPONSE_OK || ret == Gtk::RESPONSE_ACCEPT)
1845 {
1846 fileName = dlg.get_filename();
1847 fileNameField.set_text(fileName);
1848 }
1849 }
1851 bool FileSendDialog::doSetup()
1852 {
1853 set_title("Send file to user");
1854 set_size_request(400,150);
1856 Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
1857 actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
1858 actionGroup->add( Gtk::Action::create("Send", Gtk::Stock::NETWORK, "Send File"),
1859 sigc::mem_fun(*this, &FileSendDialog::okCallback) );
1860 actionGroup->add( Gtk::Action::create("Cancel", Gtk::Stock::CANCEL, "Cancel"),
1861 sigc::mem_fun(*this, &FileSendDialog::cancelCallback) );
1864 Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
1866 uiManager->insert_action_group(actionGroup, 0);
1867 add_accel_group(uiManager->get_accel_group());
1869 Glib::ustring ui_info =
1870 "<ui>"
1871 " <menubar name='MenuBar'>"
1872 " <menu action='MenuFile'>"
1873 " <menuitem action='Send'/>"
1874 " <separator/>"
1875 " <menuitem action='Cancel'/>"
1876 " </menu>"
1877 " </menubar>"
1878 "</ui>";
1880 uiManager->add_ui_from_string(ui_info);
1881 Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
1882 get_vbox()->pack_start(*pMenuBar, Gtk::PACK_SHRINK);
1884 table.resize(2, 2);
1885 get_vbox()->pack_start(table);
1887 jidLabel.set_text("User ID");
1888 table.attach(jidLabel, 0, 1, 0, 1);
1889 jidField.set_text("inkscape");
1890 table.attach(jidField, 1, 2, 0, 1);
1892 selectFileButton.set_label("Select");
1893 selectFileButton.signal_clicked().connect(
1894 sigc::mem_fun(*this, &FileSendDialog::buttonCallback) );
1895 table.attach(selectFileButton, 0, 1, 1, 2);
1897 fileName = "";
1898 fileNameField.set_text("No file selected");
1899 fileNameField.set_editable(false);
1900 table.attach(fileNameField, 1, 2, 1, 2);
1902 add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1903 add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
1905 show_all_children();
1907 return true;
1908 }
1911 //#########################################################################
1912 //# F I L E R E C E I V E D I A L O G
1913 //#########################################################################
1916 void FileReceiveDialog::okCallback()
1917 {
1918 response(Gtk::RESPONSE_OK);
1919 hide();
1920 }
1922 void FileReceiveDialog::cancelCallback()
1923 {
1924 response(Gtk::RESPONSE_CANCEL);
1925 hide();
1926 }
1928 void FileReceiveDialog::buttonCallback()
1929 {
1930 Gtk::FileChooserDialog dlg("Select a file to save",
1931 Gtk::FILE_CHOOSER_ACTION_SAVE);
1932 dlg.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1933 dlg.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
1934 int ret = dlg.run();
1935 if (ret == Gtk::RESPONSE_OK || ret == Gtk::RESPONSE_ACCEPT)
1936 {
1937 fileName = dlg.get_filename();
1938 fileNameField.set_text(fileName);
1939 }
1940 }
1943 bool FileReceiveDialog::doSetup()
1944 {
1945 set_title("File being sent by user");
1946 set_size_request(450,250);
1948 Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
1949 actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
1950 actionGroup->add( Gtk::Action::create("Send", Gtk::Stock::NETWORK, "Send File"),
1951 sigc::mem_fun(*this, &FileReceiveDialog::okCallback) );
1952 actionGroup->add( Gtk::Action::create("Cancel", Gtk::Stock::CANCEL, "Cancel"),
1953 sigc::mem_fun(*this, &FileReceiveDialog::cancelCallback) );
1956 Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
1958 uiManager->insert_action_group(actionGroup, 0);
1959 add_accel_group(uiManager->get_accel_group());
1961 Glib::ustring ui_info =
1962 "<ui>"
1963 " <menubar name='MenuBar'>"
1964 " <menu action='MenuFile'>"
1965 " <menuitem action='Send'/>"
1966 " <separator/>"
1967 " <menuitem action='Cancel'/>"
1968 " </menu>"
1969 " </menubar>"
1970 "</ui>";
1972 uiManager->add_ui_from_string(ui_info);
1973 Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
1974 get_vbox()->pack_start(*pMenuBar, Gtk::PACK_SHRINK);
1976 table.resize(6, 2);
1977 get_vbox()->pack_start(table);
1979 jidLabel.set_text("User ID");
1980 table.attach(jidLabel, 0, 1, 0, 1);
1981 jidField.set_text(jid);
1982 jidField.set_editable(false);
1983 table.attach(jidField, 1, 2, 0, 1);
1985 offeredLabel.set_text("File Offered");
1986 table.attach(offeredLabel, 0, 1, 1, 2);
1987 offeredField.set_text(offeredName);
1988 offeredField.set_editable(false);
1989 table.attach(offeredField, 1, 2, 1, 2);
1991 descLabel.set_text("Description");
1992 table.attach(descLabel, 0, 1, 2, 3);
1993 descField.set_text(desc);
1994 descField.set_editable(false);
1995 table.attach(descField, 1, 2, 2, 3);
1997 char buf[32];
1998 snprintf(buf, 31, "%ld", fileSize);
1999 sizeLabel.set_text("Size");
2000 table.attach(sizeLabel, 0, 1, 3, 4);
2001 sizeField.set_text(buf);
2002 sizeField.set_editable(false);
2003 table.attach(sizeField, 1, 2, 3, 4);
2005 hashLabel.set_text("MD5 Hash");
2006 table.attach(hashLabel, 0, 1, 4, 5);
2007 hashField.set_text(hash);
2008 hashField.set_editable(false);
2009 table.attach(hashField, 1, 2, 4, 5);
2011 selectFileButton.set_label("Select");
2012 selectFileButton.signal_clicked().connect(
2013 sigc::mem_fun(*this, &FileReceiveDialog::buttonCallback) );
2014 table.attach(selectFileButton, 0, 1, 5, 6);
2016 fileName = "";
2017 fileNameField.set_text("No file selected");
2018 fileNameField.set_editable(false);
2019 table.attach(fileNameField, 1, 2, 5, 6);
2022 add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
2023 add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
2025 show_all_children();
2027 return true;
2028 }
2031 //#########################################################################
2032 //# M A I N W I N D O W
2033 //#########################################################################
2035 PedroGui::PedroGui()
2036 {
2037 doSetup();
2038 }
2040 PedroGui::~PedroGui()
2041 {
2042 chatDeleteAll();
2043 groupChatDeleteAll();
2044 }
2047 void PedroGui::error(const char *fmt, ...)
2048 {
2049 va_list args;
2050 va_start(args, fmt);
2051 gchar * buffer = g_strdup_vprintf(fmt, args);
2052 va_end(args) ;
2054 Gtk::MessageDialog dlg(buffer,
2055 false,
2056 Gtk::MESSAGE_ERROR,
2057 Gtk::BUTTONS_OK,
2058 true);
2059 dlg.run();
2060 g_free(buffer);
2061 }
2063 void PedroGui::status(const char *fmt, ...)
2064 {
2065 va_list args;
2066 va_start(args, fmt);
2067 gchar * buffer = g_strdup_vprintf(fmt, args);
2068 va_end(args) ;
2069 messageList.postMessage("STATUS", buffer);
2070 g_free(buffer);
2071 }
2073 //################################
2074 //# CHAT WINDOW MANAGEMENT
2075 //################################
2076 bool PedroGui::chatCreate(const DOMString &userJid)
2077 {
2078 std::vector<ChatWindow *>::iterator iter;
2079 for (iter=chats.begin() ; iter != chats.end() ; iter++)
2080 {
2081 if (userJid == (*iter)->getJid())
2082 return false;
2083 }
2084 ChatWindow *chat = new ChatWindow(*this, userJid);
2085 chat->show();
2086 chats.push_back(chat);
2087 return true;
2088 }
2090 bool PedroGui::chatDelete(const DOMString &userJid)
2091 {
2092 std::vector<ChatWindow *>::iterator iter;
2093 for (iter=chats.begin() ; iter != chats.end() ; )
2094 {
2095 if (userJid == (*iter)->getJid())
2096 {
2097 delete(*iter);
2098 iter = chats.erase(iter);
2099 }
2100 else
2101 iter++;
2102 }
2103 return true;
2104 }
2106 bool PedroGui::chatDeleteAll()
2107 {
2108 std::vector<ChatWindow *>::iterator iter;
2109 for (iter=chats.begin() ; iter != chats.end() ; )
2110 {
2111 delete(*iter);
2112 iter = chats.erase(iter);
2113 }
2114 return true;
2115 }
2117 bool PedroGui::chatMessage(const DOMString &from, const DOMString &data)
2118 {
2119 if(data.size() > 0)
2120 {
2121 std::vector<ChatWindow *>::iterator iter;
2122 for (iter=chats.begin() ; iter != chats.end() ; iter++)
2123 {
2124 if (from == (*iter)->getJid())
2125 {
2126 (*iter)->postMessage(data);
2127 return true;
2128 }
2129 }
2130 ChatWindow *chat = new ChatWindow(*this, from);
2131 chat->show();
2132 chats.push_back(chat);
2133 chat->postMessage(data);
2134 }
2135 return true;
2136 }
2139 //################################
2140 //# GROUP CHAT WINDOW MANAGEMENT
2141 //################################
2143 bool PedroGui::groupChatCreate(const DOMString &groupJid, const DOMString &nick)
2144 {
2145 std::vector<GroupChatWindow *>::iterator iter;
2146 for (iter=groupChats.begin() ; iter != groupChats.end() ; iter++)
2147 {
2148 if (groupJid == (*iter)->getGroupJid())
2149 return false;
2150 }
2151 GroupChatWindow *chat = new GroupChatWindow(*this, groupJid, nick);
2152 chat->show();
2153 groupChats.push_back(chat);
2154 return true;
2155 }
2158 bool PedroGui::groupChatDelete(const DOMString &groupJid, const DOMString &nick)
2159 {
2160 std::vector<GroupChatWindow *>::iterator iter;
2161 for (iter=groupChats.begin() ; iter != groupChats.end() ;)
2162 {
2163 if (groupJid == (*iter)->getGroupJid() &&
2164 nick == (*iter)->getNick())
2165 {
2166 delete(*iter);
2167 iter = groupChats.erase(iter);
2168 }
2169 else
2170 iter++;
2171 }
2172 return true;
2173 }
2176 bool PedroGui::groupChatDeleteAll()
2177 {
2178 std::vector<GroupChatWindow *>::iterator iter;
2179 for (iter=groupChats.begin() ; iter != groupChats.end() ; )
2180 {
2181 delete(*iter);
2182 iter = groupChats.erase(iter);
2183 }
2184 return true;
2185 }
2188 bool PedroGui::groupChatMessage(const DOMString &groupJid,
2189 const DOMString &from, const DOMString &data)
2190 {
2191 std::vector<GroupChatWindow *>::iterator iter;
2192 for (iter=groupChats.begin() ; iter != groupChats.end() ; iter++)
2193 {
2194 if (groupJid == (*iter)->getGroupJid())
2195 {
2196 (*iter)->receiveMessage(from, data);
2197 }
2198 }
2199 return true;
2200 }
2202 bool PedroGui::groupChatPresence(const DOMString &groupJid,
2203 const DOMString &nick, bool presence,
2204 const DOMString &show,
2205 const DOMString &status)
2206 {
2207 std::vector<GroupChatWindow *>::iterator iter;
2208 for (iter=groupChats.begin() ; iter != groupChats.end() ; iter++)
2209 {
2210 if (groupJid == (*iter)->getGroupJid())
2211 {
2212 (*iter)->receivePresence(nick, presence, show, status);
2213 }
2214 }
2215 return true;
2216 }
2218 //################################
2219 //# EVENTS
2220 //################################
2222 /**
2223 *
2224 */
2225 void PedroGui::padlockEnable()
2226 {
2227 padlockIcon.set(Gtk::Stock::DIALOG_AUTHENTICATION,
2228 Gtk::ICON_SIZE_MENU);
2229 }
2231 /**
2232 *
2233 */
2234 void PedroGui::padlockDisable()
2235 {
2236 padlockIcon.clear();
2237 }
2240 /**
2241 *
2242 */
2243 void PedroGui::handleConnectEvent()
2244 {
2245 status("##### CONNECTED");
2246 actionEnable("Connect", false);
2247 actionEnable("Chat", true);
2248 actionEnable("GroupChat", true);
2249 actionEnable("Disconnect", true);
2250 actionEnable("RegPass", true);
2251 actionEnable("RegCancel", true);
2252 DOMString title = "Pedro - ";
2253 title.append(client.getJid());
2254 set_title(title);
2255 }
2258 /**
2259 *
2260 */
2261 void PedroGui::handleDisconnectEvent()
2262 {
2263 status("##### DISCONNECTED");
2264 actionEnable("Connect", true);
2265 actionEnable("Chat", false);
2266 actionEnable("GroupChat", false);
2267 actionEnable("Disconnect", false);
2268 actionEnable("RegPass", false);
2269 actionEnable("RegCancel", false);
2270 padlockDisable();
2271 DOMString title = "Pedro";
2272 set_title(title);
2273 chatDeleteAll();
2274 groupChatDeleteAll();
2275 roster.clear();
2276 }
2279 /**
2280 *
2281 */
2282 void PedroGui::doEvent(const XmppEvent &event)
2283 {
2285 int typ = event.getType();
2286 switch (typ)
2287 {
2288 case XmppEvent::EVENT_STATUS:
2289 {
2290 //printf("##### STATUS: %s\n", event.getData().c_str());
2291 status("%s", event.getData().c_str());
2292 break;
2293 }
2294 case XmppEvent::EVENT_ERROR:
2295 {
2296 //printf("##### ERROR: %s\n", event.getData().c_str());
2297 error("%s", event.getData().c_str());
2298 padlockDisable();
2299 break;
2300 }
2301 case XmppEvent::EVENT_SSL_STARTED:
2302 {
2303 padlockEnable();
2304 break;
2305 }
2306 case XmppEvent::EVENT_CONNECTED:
2307 {
2308 handleConnectEvent();
2309 break;
2310 }
2311 case XmppEvent::EVENT_DISCONNECTED:
2312 {
2313 handleDisconnectEvent();
2314 break;
2315 }
2316 case XmppEvent::EVENT_MESSAGE:
2317 {
2318 status("##### MESSAGE: %s\n", event.getFrom().c_str());
2319 chatMessage(event.getFrom(), event.getData());
2320 break;
2321 }
2322 case XmppEvent::EVENT_PRESENCE:
2323 {
2324 status("##### PRESENCE: %s\n", event.getFrom().c_str());
2325 roster.refresh();
2326 break;
2327 }
2328 case XmppEvent::EVENT_ROSTER:
2329 {
2330 status("##### ROSTER\n");
2331 roster.refresh();
2332 break;
2333 }
2334 case XmppEvent::EVENT_MUC_JOIN:
2335 {
2336 status("##### GROUP JOINED: %s\n", event.getGroup().c_str());
2337 break;
2338 }
2339 case XmppEvent::EVENT_MUC_MESSAGE:
2340 {
2341 //printf("##### MUC_MESSAGE: %s\n", event.getGroup().c_str());
2342 groupChatMessage(event.getGroup(),
2343 event.getFrom(), event.getData());
2344 break;
2345 }
2346 case XmppEvent::EVENT_MUC_PRESENCE:
2347 {
2348 //printf("##### MUC_USER LIST: %s\n", event.getFrom().c_str());
2349 groupChatPresence(event.getGroup(),
2350 event.getFrom(),
2351 event.getPresence(),
2352 event.getShow(),
2353 event.getStatus());
2354 break;
2355 }
2356 case XmppEvent::EVENT_MUC_LEAVE:
2357 {
2358 status("##### GROUP LEFT: %s\n", event.getGroup().c_str());
2359 groupChatDelete(event.getGroup(), event.getFrom());
2360 break;
2361 }
2362 case XmppEvent::EVENT_FILE_RECEIVE:
2363 {
2364 status("##### FILE RECEIVE: %s\n", event.getFileName().c_str());
2365 doReceiveFile(event.getFrom(), event.getIqId(), event.getStreamId(),
2366 event.getFileName(), event.getFileDesc(),
2367 event.getFileSize(), event.getFileHash());
2368 break;
2369 }
2370 case XmppEvent::EVENT_REGISTRATION_NEW:
2371 {
2372 status("##### REGISTERED: %s at %s\n",
2373 event.getTo().c_str(), event.getFrom().c_str());
2374 break;
2375 }
2376 case XmppEvent::EVENT_REGISTRATION_CHANGE_PASS:
2377 {
2378 status("##### PASSWORD CHANGED: %s at %s\n",
2379 event.getTo().c_str(), event.getFrom().c_str());
2380 break;
2381 }
2382 case XmppEvent::EVENT_REGISTRATION_CANCEL:
2383 {
2384 //client.disconnect();
2385 status("##### REGISTERATION CANCELLED: %s at %s\n",
2386 event.getTo().c_str(), event.getFrom().c_str());
2387 break;
2388 }
2389 default:
2390 {
2391 printf("unknown event type: %d\n", typ);
2392 break;
2393 }
2394 }
2396 }
2398 /**
2399 *
2400 */
2401 bool PedroGui::checkEventQueue()
2402 {
2403 while (client.eventQueueAvailable() > 0)
2404 {
2405 XmppEvent evt = client.eventQueuePop();
2406 doEvent(evt);
2407 }
2409 while( Gtk::Main::events_pending() )
2410 Gtk::Main::iteration();
2412 return true;
2413 }
2416 //##################
2417 //# COMMANDS
2418 //##################
2419 void PedroGui::doChat(const DOMString &jid)
2420 {
2421 if (jid.size()>0)
2422 {
2423 chatCreate(jid);
2424 return;
2425 }
2427 FileSendDialog dlg(*this);
2428 int ret = dlg.run();
2429 if (ret == Gtk::RESPONSE_OK)
2430 {
2431 chatCreate(dlg.getJid());
2432 }
2434 }
2436 void PedroGui::doSendFile(const DOMString &jid)
2437 {
2438 FileSendDialog dlg(*this);
2439 if (jid.size()>0)
2440 dlg.setJid(jid);
2441 int ret = dlg.run();
2442 if (ret == Gtk::RESPONSE_OK)
2443 {
2444 DOMString fileName = dlg.getFileName();
2445 printf("fileName:%s\n", fileName.c_str());
2446 DOMString offeredName = "";
2447 DOMString desc = "";
2448 client.fileSendBackground(jid, offeredName, fileName, desc);
2449 }
2451 }
2453 void PedroGui::doReceiveFile(
2454 const DOMString &jid,
2455 const DOMString &iqId,
2456 const DOMString &streamId,
2457 const DOMString &offeredName,
2458 const DOMString &desc,
2459 long size,
2460 const DOMString &hash
2461 )
2463 {
2464 FileReceiveDialog dlg(*this, jid, iqId, streamId,
2465 offeredName, desc, size, hash);
2466 int ret = dlg.run();
2467 if (ret == Gtk::RESPONSE_OK)
2468 {
2469 DOMString fileName = dlg.getFileName();
2470 printf("fileName:%s\n", fileName.c_str());
2471 client.fileReceiveBackground(jid, iqId, streamId, fileName, size, hash);
2472 }
2474 }
2476 void PedroGui::doShare(const DOMString &jid)
2477 {
2478 Inkscape::Whiteboard::SessionManager& sm =
2479 Inkscape::Whiteboard::SessionManager::instance();
2480 sm.initialiseSession(jid, Inkscape::Whiteboard::State::WHITEBOARD_PEER);
2481 }
2483 void PedroGui::doGroupShare(const DOMString &groupJid)
2484 {
2485 Inkscape::Whiteboard::SessionManager& sm =
2486 Inkscape::Whiteboard::SessionManager::instance();
2487 sm.initialiseSession(groupJid, Inkscape::Whiteboard::State::WHITEBOARD_MUC);
2488 }
2490 //##################
2491 //# CALLBACKS
2492 //##################
2493 void PedroGui::connectCallback()
2494 {
2495 ConnectDialog dialog(*this);
2496 int result = dialog.run();
2497 dialog.hide();
2498 if (result == Gtk::RESPONSE_OK)
2499 {
2500 client.setHost(dialog.getHost());
2501 client.setPort(dialog.getPort());
2502 client.setUsername(dialog.getUser());
2503 client.setPassword(dialog.getPass());
2504 client.setResource(dialog.getResource());
2505 client.setDoRegister(dialog.getRegister());
2506 client.connect();
2507 }
2508 }
2512 void PedroGui::chatCallback()
2513 {
2514 ChatDialog dialog(*this);
2515 int result = dialog.run();
2516 dialog.hide();
2517 if (result == Gtk::RESPONSE_OK)
2518 {
2519 client.message(dialog.getUser(), dialog.getText());
2520 }
2521 }
2525 void PedroGui::groupChatCallback()
2526 {
2527 GroupChatDialog dialog(*this);
2528 int result = dialog.run();
2529 dialog.hide();
2530 if (result != Gtk::RESPONSE_OK)
2531 return;
2532 DOMString groupJid = dialog.getGroup();
2533 groupJid.append("@");
2534 groupJid.append(dialog.getHost());
2535 if (client.groupChatExists(groupJid))
2536 {
2537 error("Group chat %s already exists", groupJid.c_str());
2538 return;
2539 }
2540 groupChatCreate(groupJid, dialog.getNick());
2541 client.groupChatJoin(groupJid, dialog.getNick(), dialog.getPass() );
2542 config.setMucGroup(dialog.getGroup());
2543 config.setMucHost(dialog.getHost());
2544 config.setMucNick(dialog.getNick());
2545 config.setMucPassword(dialog.getPass());
2547 configSave();
2548 }
2551 void PedroGui::disconnectCallback()
2552 {
2553 client.disconnect();
2554 }
2557 void PedroGui::quitCallback()
2558 {
2559 client.disconnect();
2560 hide();
2561 //Severe overkill! :-)
2562 //Gtk::Main::quit();
2563 }
2566 void PedroGui::fontCallback()
2567 {
2568 Gtk::FontSelectionDialog dlg;
2569 int ret = dlg.run();
2570 if (ret == Gtk::RESPONSE_OK)
2571 {
2572 Glib::ustring fontName = dlg.get_font_name();
2573 Pango::FontDescription fontDesc(fontName);
2574 modify_font(fontDesc);
2575 }
2576 }
2578 void PedroGui::colorCallback()
2579 {
2580 Gtk::ColorSelectionDialog dlg;
2581 int ret = dlg.run();
2582 if (ret == Gtk::RESPONSE_OK)
2583 {
2584 Gdk::Color col = dlg.get_colorsel()->get_current_color();
2585 modify_bg(Gtk::STATE_NORMAL, col);
2586 }
2587 }
2589 void PedroGui::regPassCallback()
2590 {
2591 PasswordDialog dlg(*this);
2592 int ret = dlg.run();
2593 if (ret == Gtk::RESPONSE_OK)
2594 {
2595 DOMString newpass = dlg.getNewPass();
2596 client.inBandRegistrationChangePassword(newpass);
2597 }
2598 }
2601 void PedroGui::regCancelCallback()
2602 {
2603 Gtk::MessageDialog dlg(*this, "Do you want to cancel your registration on the server?",
2604 false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true);
2605 int ret = dlg.run();
2606 if (ret == Gtk::RESPONSE_YES)
2607 {
2608 client.inBandRegistrationCancel();
2609 }
2610 }
2614 void PedroGui::sendFileCallback()
2615 {
2616 doSendFile("");
2617 }
2621 void PedroGui::aboutCallback()
2622 {
2623 Gtk::AboutDialog dlg;
2624 std::vector<Glib::ustring>authors;
2625 authors.push_back("Bob Jamison");
2626 dlg.set_authors(authors);
2627 DOMString comments = "A simple XMPP gui client ";
2628 comments.append("Based on the Pedro XMPP client");
2629 dlg.set_comments(comments);
2630 dlg.set_version("1.0");
2631 dlg.run();
2632 }
2636 void PedroGui::actionEnable(const DOMString &name, bool val)
2637 {
2638 DOMString path = "/ui/MenuBar/";
2639 path.append(name);
2640 Glib::RefPtr<Gtk::Action> action = uiManager->get_action(path);
2641 if (!action)
2642 {
2643 path = "/ui/MenuBar/MenuFile/";
2644 path.append(name);
2645 action = uiManager->get_action(path);
2646 }
2647 if (!action)
2648 {
2649 path = "/ui/MenuBar/MenuEdit/";
2650 path.append(name);
2651 action = uiManager->get_action(path);
2652 }
2653 if (!action)
2654 {
2655 path = "/ui/MenuBar/MenuRegister/";
2656 path.append(name);
2657 action = uiManager->get_action(path);
2658 }
2659 if (!action)
2660 {
2661 path = "/ui/MenuBar/MenuTransfer/";
2662 path.append(name);
2663 action = uiManager->get_action(path);
2664 }
2665 if (!action)
2666 {
2667 path = "/ui/MenuBar/MenuHelp/";
2668 path.append(name);
2669 action = uiManager->get_action(path);
2670 }
2671 if (!action)
2672 return;
2673 action->set_sensitive(val);
2674 }
2677 bool PedroGui::configLoad()
2678 {
2679 if (!config.readFile("pedro.ini"))
2680 return false;
2681 return true;
2682 }
2685 bool PedroGui::configSave()
2686 {
2687 if (!config.writeFile("pedro.ini"))
2688 return false;
2689 return true;
2690 }
2695 bool PedroGui::doSetup()
2696 {
2697 configLoad();
2699 set_title("Pedro XMPP Client");
2700 set_size_request(500, 300);
2701 add(mainBox);
2703 Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
2705 //### FILE MENU
2706 actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
2708 actionGroup->add( Gtk::Action::create("Connect",
2709 Gtk::Stock::CONNECT, "Connect"),
2710 sigc::mem_fun(*this, &PedroGui::connectCallback) );
2712 actionGroup->add( Gtk::Action::create("Chat",
2713 Gtk::Stock::CONNECT, "Chat"),
2714 sigc::mem_fun(*this, &PedroGui::chatCallback) );
2716 actionGroup->add( Gtk::Action::create("GroupChat",
2717 Gtk::Stock::CONNECT, "Group Chat"),
2718 sigc::mem_fun(*this, &PedroGui::groupChatCallback) );
2720 actionGroup->add( Gtk::Action::create("Disconnect",
2721 Gtk::Stock::DISCONNECT, "Disconnect"),
2722 sigc::mem_fun(*this, &PedroGui::disconnectCallback) );
2724 actionGroup->add( Gtk::Action::create("Quit", Gtk::Stock::QUIT),
2725 sigc::mem_fun(*this, &PedroGui::quitCallback) );
2727 //### EDIT MENU
2728 actionGroup->add( Gtk::Action::create("MenuEdit", "_Edit") );
2729 actionGroup->add( Gtk::Action::create("SelectFont",
2730 Gtk::Stock::SELECT_FONT, "Select Font"),
2731 sigc::mem_fun(*this, &PedroGui::fontCallback) );
2732 actionGroup->add( Gtk::Action::create("SelectColor",
2733 Gtk::Stock::SELECT_COLOR, "Select Color"),
2734 sigc::mem_fun(*this, &PedroGui::colorCallback) );
2736 //### REGISTER MENU
2737 actionGroup->add( Gtk::Action::create("MenuRegister", "_Registration") );
2738 actionGroup->add( Gtk::Action::create("RegPass",
2739 Gtk::Stock::DIALOG_AUTHENTICATION, "Change Password"),
2740 sigc::mem_fun(*this, &PedroGui::regPassCallback) );
2741 actionGroup->add( Gtk::Action::create("RegCancel",
2742 Gtk::Stock::CANCEL, "Cancel Registration"),
2743 sigc::mem_fun(*this, &PedroGui::regCancelCallback) );
2745 //### TRANSFER MENU
2746 actionGroup->add( Gtk::Action::create("MenuTransfer", "_Transfer") );
2747 actionGroup->add( Gtk::Action::create("SendFile",
2748 Gtk::Stock::NETWORK, "Send File"),
2749 sigc::mem_fun(*this, &PedroGui::sendFileCallback) );
2751 //### HELP MENU
2752 actionGroup->add( Gtk::Action::create("MenuHelp", "_Help") );
2753 actionGroup->add( Gtk::Action::create("About",
2754 Gtk::Stock::ABOUT, "About Pedro"),
2755 sigc::mem_fun(*this, &PedroGui::aboutCallback) );
2757 uiManager = Gtk::UIManager::create();
2759 uiManager->insert_action_group(actionGroup, 0);
2760 add_accel_group(uiManager->get_accel_group());
2762 Glib::ustring ui_info =
2763 "<ui>"
2764 " <menubar name='MenuBar'>"
2765 " <menu action='MenuFile'>"
2766 " <menuitem action='Connect'/>"
2767 " <separator/>"
2768 " <menuitem action='Chat'/>"
2769 " <menuitem action='GroupChat'/>"
2770 " <separator/>"
2771 " <menuitem action='Disconnect'/>"
2772 " <menuitem action='Quit'/>"
2773 " </menu>"
2774 " <menu action='MenuEdit'>"
2775 " <menuitem action='SelectFont'/>"
2776 " <menuitem action='SelectColor'/>"
2777 " </menu>"
2778 " <menu action='MenuRegister'>"
2779 " <menuitem action='RegPass'/>"
2780 " <menuitem action='RegCancel'/>"
2781 " </menu>"
2782 " <menu action='MenuTransfer'>"
2783 " <menuitem action='SendFile'/>"
2784 " </menu>"
2785 " <menu action='MenuHelp'>"
2786 " <menuitem action='About'/>"
2787 " </menu>"
2788 " </menubar>"
2789 "</ui>";
2791 uiManager->add_ui_from_string(ui_info);
2792 Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
2793 menuBarBox.pack_start(*pMenuBar, Gtk::PACK_SHRINK);
2795 padlockDisable();
2796 menuBarBox.pack_end(padlockIcon, Gtk::PACK_SHRINK);
2798 mainBox.pack_start(menuBarBox, Gtk::PACK_SHRINK);
2800 actionEnable("Connect", true);
2801 actionEnable("Chat", false);
2802 actionEnable("GroupChat", false);
2803 actionEnable("Disconnect", false);
2804 actionEnable("RegPass", false);
2805 actionEnable("RegCancel", false);
2807 mainBox.pack_start(vPaned);
2808 vPaned.add1(roster);
2809 vPaned.add2(messageList);
2810 roster.setParent(this);
2812 show_all_children();
2814 //# Start a timer to check the queue every nn milliseconds
2815 Glib::signal_timeout().connect(
2816 sigc::mem_fun(*this, &PedroGui::checkEventQueue), 20 );
2818 //client.addXmppEventListener(*this);
2819 client.eventQueueEnable(true);
2821 return true;
2822 }
2825 } // namespace Pedro
2829 //########################################################################
2830 //# E N D O F F I L E
2831 //########################################################################