1 #ifndef __PEDROGUI_H__
2 #define __PEDROGUI_H__
3 /*
4 * Simple demo GUI for the Pedro mini-XMPP client.
5 *
6 * Authors:
7 * Bob Jamison
8 *
9 * Copyright (C) 2005 Bob Jamison
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
28 #include <gtkmm.h>
30 #include "pedro/pedroxmpp.h"
31 #include "pedro/pedroconfig.h"
34 namespace Pedro
35 {
38 class PedroGui;
39 class GroupChatWindow;
41 //#########################################################################
42 //# R O S T E R
43 //#########################################################################
44 class Roster : public Gtk::ScrolledWindow
45 {
46 public:
48 Roster()
49 { doSetup(); }
51 virtual ~Roster()
52 {}
54 /**
55 * Clear all roster items from the list
56 */
57 virtual void clear();
59 /**
60 * Regenerate the roster
61 */
62 virtual void refresh();
65 void setParent(PedroGui *val)
66 { parent = val; }
68 private:
70 class CustomTreeView : public Gtk::TreeView
71 {
72 public:
73 CustomTreeView()
74 { parent = NULL; }
75 virtual ~CustomTreeView()
76 {}
78 bool on_button_press_event(GdkEventButton* event)
79 {
80 Gtk::TreeView::on_button_press_event(event);
81 if (parent)
82 parent->buttonPressCallback(event);
83 return true;
84 }
85 void setParent(Roster *val)
86 { parent = val; }
88 private:
89 Roster *parent;
90 };
92 void doubleClickCallback(const Gtk::TreeModel::Path &path,
93 Gtk::TreeViewColumn *col);
95 void sendFileCallback();
96 void chatCallback();
97 void shareCallback();
98 bool buttonPressCallback(GdkEventButton* event);
100 bool doSetup();
102 Glib::RefPtr<Gdk::Pixbuf> pixbuf_available;
103 Glib::RefPtr<Gdk::Pixbuf> pixbuf_away;
104 Glib::RefPtr<Gdk::Pixbuf> pixbuf_chat;
105 Glib::RefPtr<Gdk::Pixbuf> pixbuf_dnd;
106 Glib::RefPtr<Gdk::Pixbuf> pixbuf_error;
107 Glib::RefPtr<Gdk::Pixbuf> pixbuf_offline;
108 Glib::RefPtr<Gdk::Pixbuf> pixbuf_xa;
110 class RosterColumns : public Gtk::TreeModel::ColumnRecord
111 {
112 public:
113 RosterColumns()
114 {
115 add(groupColumn);
116 add(statusColumn); add(userColumn);
117 add(nameColumn); add(subColumn);
118 }
120 Gtk::TreeModelColumn<Glib::ustring> groupColumn;
121 Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > statusColumn;
122 Gtk::TreeModelColumn<Glib::ustring> userColumn;
123 Gtk::TreeModelColumn<Glib::ustring> nameColumn;
124 Gtk::TreeModelColumn<Glib::ustring> subColumn;
125 };
127 RosterColumns rosterColumns;
129 Glib::RefPtr<Gtk::UIManager> uiManager;
131 Glib::RefPtr<Gtk::TreeStore> treeStore;
132 CustomTreeView rosterView;
134 PedroGui *parent;
135 };
137 //#########################################################################
138 //# M E S S A G E L I S T
139 //#########################################################################
140 class MessageList : public Gtk::ScrolledWindow
141 {
142 public:
144 MessageList()
145 { doSetup(); }
147 virtual ~MessageList()
148 {}
150 /**
151 * Clear all messages from the list
152 */
153 virtual void clear();
155 /**
156 * Post a message to the list
157 */
158 virtual void postMessage(const DOMString &from, const DOMString &msg);
160 private:
162 bool doSetup();
164 Gtk::TextView messageList;
165 Glib::RefPtr<Gtk::TextBuffer> messageListBuffer;
167 };
169 //#########################################################################
170 //# U S E R L I S T
171 //#########################################################################
172 class UserList : public Gtk::ScrolledWindow
173 {
174 public:
176 UserList()
177 { doSetup(); }
179 virtual ~UserList()
180 {}
182 /**
183 * Clear all messages from the list
184 */
185 virtual void clear();
187 /**
188 * Post a message to the list
189 */
190 virtual void addUser(const DOMString &user, const DOMString &show);
193 void setParent(GroupChatWindow *val)
194 { parent = val; }
196 private:
198 class CustomTreeView : public Gtk::TreeView
199 {
200 public:
201 CustomTreeView()
202 { parent = NULL; }
203 virtual ~CustomTreeView()
204 {}
206 bool on_button_press_event(GdkEventButton* event)
207 {
208 Gtk::TreeView::on_button_press_event(event);
209 if (parent)
210 parent->buttonPressCallback(event);
211 return true;
212 }
213 void setParent(UserList *val)
214 { parent = val; }
216 private:
217 UserList *parent;
218 };
220 void doubleClickCallback(const Gtk::TreeModel::Path &path,
221 Gtk::TreeViewColumn *col);
223 void sendFileCallback();
224 void chatCallback();
225 void shareCallback();
226 bool buttonPressCallback(GdkEventButton* event);
228 bool doSetup();
230 Glib::RefPtr<Gdk::Pixbuf> pixbuf_available;
231 Glib::RefPtr<Gdk::Pixbuf> pixbuf_away;
232 Glib::RefPtr<Gdk::Pixbuf> pixbuf_chat;
233 Glib::RefPtr<Gdk::Pixbuf> pixbuf_dnd;
234 Glib::RefPtr<Gdk::Pixbuf> pixbuf_error;
235 Glib::RefPtr<Gdk::Pixbuf> pixbuf_offline;
236 Glib::RefPtr<Gdk::Pixbuf> pixbuf_xa;
238 class UserListColumns : public Gtk::TreeModel::ColumnRecord
239 {
240 public:
241 UserListColumns()
242 { add(statusColumn); add(userColumn); }
244 Gtk::TreeModelColumn<Glib::ustring> userColumn;
245 Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > statusColumn;
246 };
248 UserListColumns userListColumns;
250 Glib::RefPtr<Gtk::UIManager> uiManager;
252 Glib::RefPtr<Gtk::ListStore> userListStore;
253 CustomTreeView userList;
255 GroupChatWindow *parent;
256 };
259 //#########################################################################
260 //# C H A T W I N D O W
261 //#########################################################################
262 class ChatWindow : public Gtk::Window
263 {
264 public:
266 ChatWindow(PedroGui &par, const DOMString jid);
268 virtual ~ChatWindow();
270 virtual DOMString getJid()
271 { return jid; }
273 virtual void setJid(const DOMString &val)
274 { jid = val; }
276 virtual bool postMessage(const DOMString &data);
278 private:
280 DOMString jid;
282 void leaveCallback();
283 void hideCallback();
284 void shareCallback();
285 void textEnterCallback();
287 bool doSetup();
289 Gtk::VBox vbox;
290 Gtk::VPaned vPaned;
292 MessageList messageList;
294 Gtk::Entry inputTxt;
296 PedroGui &parent;
297 };
300 //#########################################################################
301 //# G R O U P C H A T W I N D O W
302 //#########################################################################
303 class GroupChatWindow : public Gtk::Window
304 {
305 public:
307 GroupChatWindow(PedroGui &par, const DOMString &groupJid,
308 const DOMString &nick);
310 virtual ~GroupChatWindow();
313 virtual DOMString getGroupJid()
314 { return groupJid; }
316 virtual void setGroupJid(const DOMString &val)
317 { groupJid = val; }
319 virtual DOMString getNick()
320 { return nick; }
322 virtual void setNick(const DOMString &val)
323 { nick = val; }
325 virtual bool receiveMessage(const DOMString &from,
326 const DOMString &data);
328 virtual bool receivePresence(const DOMString &nick,
329 bool presence,
330 const DOMString &show,
331 const DOMString &status);
333 virtual void doSendFile(const DOMString &nick);
335 virtual void doChat(const DOMString &nick);
336 virtual void doShare(const DOMString &nick);
339 private:
341 void textEnterCallback();
342 void leaveCallback();
343 void hideCallback();
344 void shareCallback();
346 bool doSetup();
348 Gtk::VBox vbox;
349 Gtk::VPaned vPaned;
350 Gtk::HPaned hPaned;
352 MessageList messageList;
354 UserList userList;
356 Gtk::Entry inputTxt;
358 DOMString groupJid;
359 DOMString nick;
361 PedroGui &parent;
362 };
366 //#########################################################################
367 //# C O N F I G D I A L O G
368 //#########################################################################
370 class ConfigDialog : public Gtk::Dialog
371 {
372 public:
374 ConfigDialog (PedroGui &par) : parent(par)
375 { doSetup(); }
377 virtual ~ConfigDialog ()
378 {}
380 DOMString getPass()
381 { return passField.get_text(); }
382 DOMString getNewPass()
383 { return newField.get_text(); }
384 DOMString getConfirm()
385 { return confField.get_text(); }
387 protected:
389 //Overloaded from Gtk::Dialog
390 virtual void on_response(int response_id);
392 private:
394 void okCallback();
395 void cancelCallback();
397 bool doSetup();
399 Gtk::Table table;
401 Gtk::Label passLabel;
402 Gtk::Entry passField;
403 Gtk::Label newLabel;
404 Gtk::Entry newField;
405 Gtk::Label confLabel;
406 Gtk::Entry confField;
408 PedroGui &parent;
409 };
412 //#########################################################################
413 //# P A S S W O R D D I A L O G
414 //#########################################################################
415 class PasswordDialog : public Gtk::Dialog
416 {
417 public:
419 PasswordDialog (PedroGui &par) : parent(par)
420 { doSetup(); }
422 virtual ~PasswordDialog ()
423 {}
425 DOMString getPass()
426 { return passField.get_text(); }
427 DOMString getNewPass()
428 { return newField.get_text(); }
429 DOMString getConfirm()
430 { return confField.get_text(); }
432 protected:
434 //Overloaded from Gtk::Dialog
435 virtual void on_response(int response_id);
437 private:
439 void okCallback();
440 void cancelCallback();
442 bool doSetup();
444 Gtk::Table table;
446 Gtk::Label passLabel;
447 Gtk::Entry passField;
448 Gtk::Label newLabel;
449 Gtk::Entry newField;
450 Gtk::Label confLabel;
451 Gtk::Entry confField;
453 PedroGui &parent;
454 };
458 //#########################################################################
459 //# C H A T D I A L O G
460 //#########################################################################
461 class ChatDialog : public Gtk::Dialog
462 {
463 public:
465 ChatDialog(PedroGui &par) : parent(par)
466 { doSetup(); }
468 virtual ~ChatDialog()
469 {}
471 DOMString getUser()
472 { return userField.get_text(); }
474 DOMString getText()
475 { return textField.get_text(); }
477 private:
479 void okCallback();
480 void cancelCallback();
482 bool doSetup();
484 Gtk::Table table;
486 Gtk::Label userLabel;
487 Gtk::Entry userField;
488 Gtk::Entry textField;
490 PedroGui &parent;
491 };
495 //#########################################################################
496 //# G R O U P C H A T D I A L O G
497 //#########################################################################
499 class GroupChatDialog : public Gtk::Dialog
500 {
501 public:
503 GroupChatDialog(PedroGui &par) : parent(par)
504 { doSetup(); }
506 virtual ~GroupChatDialog()
507 {}
509 DOMString getGroup()
510 { return groupField.get_text(); }
511 DOMString getHost()
512 { return hostField.get_text(); }
513 DOMString getPass()
514 { return passField.get_text(); }
515 DOMString getNick()
516 { return nickField.get_text(); }
518 private:
520 void okCallback();
521 void cancelCallback();
523 bool doSetup();
525 Gtk::Table table;
527 Gtk::Label groupLabel;
528 Gtk::Entry groupField;
529 Gtk::Label hostLabel;
530 Gtk::Entry hostField;
531 Gtk::Label passLabel;
532 Gtk::Entry passField;
533 Gtk::Label nickLabel;
534 Gtk::Entry nickField;
536 PedroGui &parent;
537 };
540 //#########################################################################
541 //# C O N N E C T D I A L O G
542 //#########################################################################
543 class ConnectDialog : public Gtk::Dialog
544 {
545 public:
547 ConnectDialog (PedroGui &par) : parent(par)
548 { doSetup(); }
550 virtual ~ConnectDialog ()
551 {}
553 DOMString getHost()
554 { return hostField.get_text(); }
555 void setHost(const DOMString &val)
556 { hostField.set_text(val); }
557 int getPort()
558 { return (int)portSpinner.get_value(); }
559 void setPort(int val)
560 { portSpinner.set_value(val); }
561 DOMString getUser()
562 { return userField.get_text(); }
563 void setUser(const DOMString &val)
564 { userField.set_text(val); }
565 DOMString getPass()
566 { return passField.get_text(); }
567 void setPass(const DOMString &val)
568 { passField.set_text(val); }
569 DOMString getResource()
570 { return resourceField.get_text(); }
571 void setResource(const DOMString &val)
572 { resourceField.set_text(val); }
573 bool getRegister()
574 { return registerButton.get_active(); }
576 /**
577 * Regenerate the account list
578 */
579 virtual void refresh();
581 private:
583 void okCallback();
584 void saveCallback();
585 void cancelCallback();
586 void doubleClickCallback(
587 const Gtk::TreeModel::Path &path,
588 Gtk::TreeViewColumn *col);
589 void selectedCallback();
591 bool doSetup();
593 Gtk::Table table;
595 Gtk::Label hostLabel;
596 Gtk::Entry hostField;
597 Gtk::Label portLabel;
598 Gtk::SpinButton portSpinner;
599 Gtk::Label userLabel;
600 Gtk::Entry userField;
601 Gtk::Label passLabel;
602 Gtk::Entry passField;
603 Gtk::Label resourceLabel;
604 Gtk::Entry resourceField;
605 Gtk::Label registerLabel;
606 Gtk::CheckButton registerButton;
608 Glib::RefPtr<Gtk::UIManager> uiManager;
611 //## Account list
613 void buttonPressCallback(GdkEventButton* event);
615 Gtk::ScrolledWindow accountScroll;
617 void connectCallback();
619 void modifyCallback();
621 void deleteCallback();
624 class AccountColumns : public Gtk::TreeModel::ColumnRecord
625 {
626 public:
627 AccountColumns()
628 {
629 add(nameColumn);
630 add(hostColumn);
631 }
633 Gtk::TreeModelColumn<Glib::ustring> nameColumn;
634 Gtk::TreeModelColumn<Glib::ustring> hostColumn;
635 };
637 AccountColumns accountColumns;
639 Glib::RefPtr<Gtk::UIManager> accountUiManager;
641 Glib::RefPtr<Gtk::ListStore> accountListStore;
642 Gtk::TreeView accountView;
645 PedroGui &parent;
646 };
651 //#########################################################################
652 //# F I L E S E N D D I A L O G
653 //#########################################################################
655 class FileSendDialog : public Gtk::Dialog
656 {
657 public:
659 FileSendDialog(PedroGui &par) : parent(par)
660 { doSetup(); }
662 virtual ~FileSendDialog()
663 {}
665 DOMString getFileName()
666 { return fileName; }
667 DOMString getJid()
668 { return jidField.get_text(); }
669 void setJid(const DOMString &val)
670 { return jidField.set_text(val); }
672 private:
674 void okCallback();
675 void cancelCallback();
676 void buttonCallback();
678 bool doSetup();
680 Gtk::Table table;
682 Gtk::Label jidLabel;
683 Gtk::Entry jidField;
685 DOMString fileName;
686 Gtk::Entry fileNameField;
688 Gtk::Button selectFileButton;
690 PedroGui &parent;
691 };
693 //#########################################################################
694 //# F I L E R E C E I V E D I A L O G
695 //#########################################################################
697 class FileReceiveDialog : public Gtk::Dialog
698 {
699 public:
701 FileReceiveDialog(PedroGui &par,
702 const DOMString &jidArg,
703 const DOMString &iqIdArg,
704 const DOMString &streamIdArg,
705 const DOMString &offeredNameArg,
706 const DOMString &descArg,
707 long sizeArg,
708 const DOMString &hashArg
709 ) : parent(par)
710 {
711 jid = jidArg;
712 iqId = iqIdArg;
713 streamId = streamIdArg;
714 offeredName = offeredNameArg;
715 desc = descArg;
716 fileSize = sizeArg;
717 hash = hashArg;
718 doSetup();
719 }
721 virtual ~FileReceiveDialog()
722 {}
724 DOMString getJid()
725 { return jid; }
726 DOMString getIq()
727 { return iqId; }
728 DOMString getStreamId()
729 { return streamId; }
730 DOMString getOfferedName()
731 { return offeredName; }
732 DOMString getFileName()
733 { return fileName; }
734 DOMString getDescription()
735 { return desc; }
736 long getSize()
737 { return fileSize; }
738 DOMString getHash()
739 { return hash; }
741 private:
743 void okCallback();
744 void cancelCallback();
745 void buttonCallback();
747 bool doSetup();
749 Gtk::Table table;
751 Gtk::Label jidLabel;
752 Gtk::Entry jidField;
753 Gtk::Label offeredLabel;
754 Gtk::Entry offeredField;
755 Gtk::Label descLabel;
756 Gtk::Entry descField;
757 Gtk::Label sizeLabel;
758 Gtk::Entry sizeField;
759 Gtk::Label hashLabel;
760 Gtk::Entry hashField;
762 Gtk::Entry fileNameField;
764 Gtk::Button selectFileButton;
766 DOMString jid;
767 DOMString iqId;
768 DOMString streamId;
769 DOMString offeredName;
770 DOMString desc;
771 long fileSize;
772 DOMString hash;
774 DOMString fileName;
776 PedroGui &parent;
777 };
781 //#########################################################################
782 //# M A I N W I N D O W
783 //#########################################################################
785 class PedroGui : public Gtk::Window
786 {
787 public:
789 PedroGui();
791 virtual ~PedroGui();
793 //Let everyone share these
794 XmppClient client;
795 XmppConfig config;
798 virtual void error(const char *fmt, ...);
800 virtual void status(const char *fmt, ...);
804 void handleConnectEvent();
806 void handleDisconnectEvent();
808 /**
809 *
810 */
811 virtual void doEvent(const XmppEvent &event);
813 /**
814 *
815 */
816 bool checkEventQueue();
819 bool chatCreate(const DOMString &userJid);
820 bool chatDelete(const DOMString &userJid);
821 bool chatDeleteAll();
822 bool chatMessage(const DOMString &jid, const DOMString &data);
824 bool groupChatCreate(const DOMString &groupJid,
825 const DOMString &nick);
826 bool groupChatDelete(const DOMString &groupJid,
827 const DOMString &nick);
828 bool groupChatDeleteAll();
829 bool groupChatMessage(const DOMString &groupJid,
830 const DOMString &from, const DOMString &data);
831 bool groupChatPresence(const DOMString &groupJid,
832 const DOMString &nick,
833 bool presence,
834 const DOMString &show,
835 const DOMString &status);
837 void doChat(const DOMString &jid);
838 void doSendFile(const DOMString &jid);
839 void doReceiveFile(const DOMString &jid,
840 const DOMString &iqId,
841 const DOMString &streamId,
842 const DOMString &offeredName,
843 const DOMString &desc,
844 long size,
845 const DOMString &hash);
847 void doShare(const DOMString &jid);
848 void doGroupShare(const DOMString &groupJid);
850 //# File menu
851 void connectCallback();
852 void chatCallback();
853 void groupChatCallback();
854 void disconnectCallback();
855 void quitCallback();
857 //# Edit menu
858 void fontCallback();
859 void colorCallback();
861 //# Transfer menu
862 void sendFileCallback();
864 //# Registration menu
865 void regPassCallback();
866 void regCancelCallback();
868 //# Help menu
869 void aboutCallback();
871 //# Configuration file
872 bool configLoad();
873 bool configSave();
876 private:
878 bool doSetup();
880 Gtk::VBox mainBox;
882 Gtk::HBox menuBarBox;
884 Gtk::Image padlockIcon;
885 void padlockEnable();
886 void padlockDisable();
889 Pango::FontDescription fontDesc;
890 Gdk::Color foregroundColor;
891 Gdk::Color backgroundColor;
893 Gtk::VPaned vPaned;
894 MessageList messageList;
895 Roster roster;
897 Glib::RefPtr<Gtk::UIManager> uiManager;
898 void actionEnable(const DOMString &name, bool val);
900 std::vector<ChatWindow *>chats;
902 std::vector<GroupChatWindow *>groupChats;
904 static const int writeBufLen = 2048;
906 char writeBuf[writeBufLen];
907 };
910 } //namespace Pedro
912 #endif /* __PEDROGUI_H__ */
913 //#########################################################################
914 //# E N D O F F I L E
915 //#########################################################################