Code

Export. Fix PS/EPS export (Bug #698340, PS Level Restriction reversed.
[inkscape.git] / src / jabber_whiteboard / pedrogui.cpp
1 /*
2  * Simple demo GUI for the Pedro mini-XMPP client.
3  *
4  * Authors:
5  *   Bob Jamison
6  *
7  * Copyright (C) 2005-2008 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*/)
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);
396 void Roster::chatCallback()
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);
407 void Roster::sendFileCallback()
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);
418 void Roster::shareCallback()
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);
429 bool Roster::buttonPressCallback(GdkEventButton* event)
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;
442 bool Roster::doSetup()
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;
536 /**
537  * Clear the roster
538  */
539 void Roster::clear()
541     treeStore->clear();
544 /**
545  * Regenerate the roster
546  */
547 void Roster::refresh()
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();
592 //#########################################################################
593 //# M E S S A G E    L I S T
594 //#########################################################################
596 bool MessageList::doSetup()
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;
657 /**
658  * Clear all messages from the list
659  */
660 void MessageList::clear()
662     messageListBuffer->erase(messageListBuffer->begin(),
663                              messageListBuffer->end());
667 /**
668  * Post a message to the list
669  */
670 void MessageList::postMessage(const DOMString &from, const DOMString &msg)
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);
699 //#########################################################################
700 //# U S E R     L I S T
701 //#########################################################################
702 void UserList::doubleClickCallback(const Gtk::TreeModel::Path &/*path*/,
703                    Gtk::TreeViewColumn */*col*/)
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);
715 void UserList::chatCallback()
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);
726 void UserList::sendFileCallback()
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);
737 void UserList::shareCallback()
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);
748 bool UserList::buttonPressCallback(GdkEventButton* event)
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;
761 bool UserList::doSetup()
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;
842 /**
843  * Clear all messages from the list
844  */
845 void UserList::clear()
847     userListStore->clear();
851 /**
852  * Add a user to the list
853  */
854 void UserList::addUser(const DOMString &user, const DOMString &show)
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;
879 //#########################################################################
880 //# C H A T    W I N D O W
881 //#########################################################################
882 ChatWindow::ChatWindow(PedroGui &par, const DOMString jidArg)
883                         : parent(par)
885     jid = jidArg;
886     doSetup();
889 ChatWindow::~ChatWindow()
893 void ChatWindow::leaveCallback()
895     hide();
896     parent.chatDelete(jid);
900 void ChatWindow::hideCallback()
902     hide();
903     parent.chatDelete(jid);
906 void ChatWindow::shareCallback()
908 //    hide();
909     parent.doShare(this->jid);
912 void ChatWindow::textEnterCallback()
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);
921 bool ChatWindow::doSetup()
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;
974 bool ChatWindow::postMessage(const DOMString &data)
976     messageList.postMessage(jid, data);
977     return true;
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)
989     groupJid = groupJidArg;
990     nick     = nickArg;
991     doSetup();
994 GroupChatWindow::~GroupChatWindow()
999 void GroupChatWindow::leaveCallback()
1001     parent.client.groupChatLeave(groupJid, nick);
1002     hide();
1003     parent.groupChatDelete(groupJid, nick);
1006 void GroupChatWindow::hideCallback()
1008     parent.client.groupChatLeave(groupJid, nick);
1009     hide();
1010     parent.groupChatDelete(groupJid, nick);
1013 void GroupChatWindow::textEnterCallback()
1015     DOMString str = inputTxt.get_text();
1016     if (str.size() > 0)
1017         parent.client.groupChatMessage(groupJid, str);
1018     inputTxt.set_text("");
1021 void GroupChatWindow::shareCallback()
1023     parent.doGroupShare(groupJid);
1026 bool GroupChatWindow::doSetup()
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;
1085 bool GroupChatWindow::receiveMessage(const DOMString &from,
1086                                      const DOMString &data)
1088     messageList.postMessage(from, data);
1089     return true;
1092 bool GroupChatWindow::receivePresence(const DOMString &fromNick,
1093                                       bool presence,
1094                                       const DOMString &show,
1095                                       const DOMString &/*status*/)
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;
1128 void GroupChatWindow::doChat(const DOMString &nick)
1130     printf("##Chat with %s\n", nick.c_str());
1131     DOMString fullJid = groupJid;
1132     fullJid.append("/");
1133     fullJid.append(nick);
1134     parent.doChat(fullJid);
1137 void GroupChatWindow::doSendFile(const DOMString &nick)
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);
1147 void GroupChatWindow::doShare(const DOMString &nick)
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);
1158 //#########################################################################
1159 //# C O N F I G    D I A L O G
1160 //#########################################################################
1163 void ConfigDialog::okCallback()
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         }
1189 void ConfigDialog::cancelCallback()
1191     //response(Gtk::RESPONSE_CANCEL);
1192     hide();
1195 void ConfigDialog::on_response(int response_id)
1197     if (response_id == Gtk::RESPONSE_OK)
1198         okCallback();
1199     else
1200         cancelCallback();
1203 bool ConfigDialog::doSetup()
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;
1265 //#########################################################################
1266 //# P A S S W O R D      D I A L O G
1267 //#########################################################################
1270 void PasswordDialog::okCallback()
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         }
1296 void PasswordDialog::cancelCallback()
1298     //response(Gtk::RESPONSE_CANCEL);
1299     hide();
1302 void PasswordDialog::on_response(int response_id)
1304     if (response_id == Gtk::RESPONSE_OK)
1305         okCallback();
1306     else
1307         cancelCallback();
1310 bool PasswordDialog::doSetup()
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;
1372 //#########################################################################
1373 //# C H A T    D I A L O G
1374 //#########################################################################
1377 void ChatDialog::okCallback()
1379     response(Gtk::RESPONSE_OK);
1380     hide();
1383 void ChatDialog::cancelCallback()
1385     response(Gtk::RESPONSE_CANCEL);
1386     hide();
1390 bool ChatDialog::doSetup()
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;
1442 //#########################################################################
1443 //# G R O U P    C H A T   D I A L O G
1444 //#########################################################################
1447 void GroupChatDialog::okCallback()
1449     response(Gtk::RESPONSE_OK);
1450     hide();
1453 void GroupChatDialog::cancelCallback()
1455     response(Gtk::RESPONSE_CANCEL);
1456     hide();
1460 bool GroupChatDialog::doSetup()
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;
1529 //#########################################################################
1530 //# C O N N E C T    D I A L O G
1531 //#########################################################################
1534 void ConnectDialog::okCallback()
1536     response(Gtk::RESPONSE_OK);
1537     hide();
1540 void ConnectDialog::saveCallback()
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();
1580 void ConnectDialog::cancelCallback()
1582     response(Gtk::RESPONSE_CANCEL);
1583     hide();
1587 void ConnectDialog::doubleClickCallback(
1588                    const Gtk::TreeModel::Path &/*path*/,
1589                    Gtk::TreeViewColumn */*col*/)
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();
1608 void ConnectDialog::selectedCallback()
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()); 
1624 void ConnectDialog::deleteCallback()
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();
1634     
1639 void ConnectDialog::buttonPressCallback(GdkEventButton* event)
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         }
1650 bool ConnectDialog::doSetup()
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("enter server name");
1694     parent.client.setPort(5222);
1695     parent.client.setUsername("");
1696     parent.client.setPassword("");
1697     parent.client.setResource("inkscape");
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;
1800 /**
1801  * Regenerate the account list
1802  */
1803 void ConnectDialog::refresh()
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();
1820 //#########################################################################
1821 //# F I L E    S E N D    D I A L O G
1822 //#########################################################################
1825 void FileSendDialog::okCallback()
1827     response(Gtk::RESPONSE_OK);
1828     hide();
1831 void FileSendDialog::cancelCallback()
1833     response(Gtk::RESPONSE_CANCEL);
1834     hide();
1838 void FileSendDialog::buttonCallback()
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         }
1852 bool FileSendDialog::doSetup()
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;
1912 //#########################################################################
1913 //# F I L E    R E C E I V E   D I A L O G
1914 //#########################################################################
1917 void FileReceiveDialog::okCallback()
1919     response(Gtk::RESPONSE_OK);
1920     hide();
1923 void FileReceiveDialog::cancelCallback()
1925     response(Gtk::RESPONSE_CANCEL);
1926     hide();
1929 void FileReceiveDialog::buttonCallback()
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         }
1944 bool FileReceiveDialog::doSetup()
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;
2032 //#########################################################################
2033 //# M A I N    W I N D O W
2034 //#########################################################################
2036 PedroGui::PedroGui()
2038     doSetup();
2041 PedroGui::~PedroGui()
2043     chatDeleteAll();
2044     groupChatDeleteAll();
2048 void PedroGui::error(const char *fmt, ...)
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);
2064 void PedroGui::status(const char *fmt, ...)
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);
2074 //################################
2075 //# CHAT WINDOW MANAGEMENT
2076 //################################
2077 bool PedroGui::chatCreate(const DOMString &userJid)
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;
2091 bool PedroGui::chatDelete(const DOMString &userJid)
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;
2107 bool PedroGui::chatDeleteAll()
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;
2118 bool PedroGui::chatMessage(const DOMString &from, const DOMString &data)
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;
2140 //################################
2141 //# GROUP CHAT WINDOW MANAGEMENT
2142 //################################
2144 bool PedroGui::groupChatCreate(const DOMString &groupJid, const DOMString &nick)
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;
2159 bool PedroGui::groupChatDelete(const DOMString &groupJid, const DOMString &nick)
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;
2177 bool PedroGui::groupChatDeleteAll()
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;
2189 bool PedroGui::groupChatMessage(const DOMString &groupJid,
2190               const DOMString &from, const DOMString &data)
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;
2203 bool PedroGui::groupChatPresence(const DOMString &groupJid,
2204                       const DOMString &nick, bool presence,
2205                       const DOMString &show,
2206                       const DOMString &status)
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;
2219 //################################
2220 //# EVENTS
2221 //################################
2223 /**
2224  *
2225  */
2226 void PedroGui::padlockEnable()
2228     padlockIcon.set(Gtk::Stock::DIALOG_AUTHENTICATION,
2229                Gtk::ICON_SIZE_MENU);
2232 /**
2233  *
2234  */
2235 void PedroGui::padlockDisable()
2237     padlockIcon.clear();
2241 /**
2242  *
2243  */
2244 void PedroGui::handleConnectEvent()
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);
2259 /**
2260  *
2261  */
2262 void PedroGui::handleDisconnectEvent()
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();
2280 /**
2281  *
2282  */
2283 void PedroGui::doEvent(const XmppEvent &event)
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         }
2399 /**
2400  *
2401  */
2402 bool PedroGui::checkEventQueue()
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;
2417 //##################
2418 //# COMMANDS
2419 //##################
2420 void PedroGui::doChat(const DOMString &jid)
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         }
2437 void PedroGui::doSendFile(const DOMString &jid)
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         }
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                       )
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         }
2477 void PedroGui::doShare(const DOMString &jid)
2479     Inkscape::Whiteboard::SessionManager& sm =
2480          Inkscape::Whiteboard::SessionManager::instance();
2481     sm.initialiseSession(jid, Inkscape::Whiteboard::State::WHITEBOARD_PEER);
2484 void PedroGui::doGroupShare(const DOMString &groupJid)
2486     Inkscape::Whiteboard::SessionManager& sm =
2487         Inkscape::Whiteboard::SessionManager::instance();
2488     sm.initialiseSession(groupJid, Inkscape::Whiteboard::State::WHITEBOARD_MUC);
2491 //##################
2492 //# CALLBACKS
2493 //##################
2494 void PedroGui::connectCallback()
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         }
2513 void PedroGui::chatCallback()
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         }
2526 void PedroGui::groupChatCallback()
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());
2547  
2548     configSave();
2552 void PedroGui::disconnectCallback()
2554     client.disconnect();
2558 void PedroGui::quitCallback()
2560     client.disconnect();
2561     hide();
2562     //Severe overkill!  :-)
2563     //Gtk::Main::quit();
2567 void PedroGui::fontCallback()
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         }
2579 void PedroGui::colorCallback()
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         }
2590 void PedroGui::regPassCallback()
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         }
2602 void PedroGui::regCancelCallback()
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         }
2615 void PedroGui::sendFileCallback()
2617     doSendFile("");
2622 void PedroGui::aboutCallback()
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();
2639 void PedroGui::actionEnable(const DOMString &name, bool val)
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);
2680 bool PedroGui::configLoad()
2682     if (!config.readFile("pedro.ini"))
2683         return false;
2684     return true;
2688 bool PedroGui::configSave()
2690     if (!config.writeFile("pedro.ini"))
2691         return false;
2692     return true;
2698 bool PedroGui::doSetup()
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;
2828 } // namespace Pedro
2832 //########################################################################
2833 //# E N D    O F     F I L E
2834 //########################################################################