4af4f1aac381a94bd5b2a64994948d8d0810ca72
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-2007 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 "pedroxmpp.h"
31 #include "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 bool buttonPressCallback(GdkEventButton* event);
99 bool doSetup();
101 Glib::RefPtr<Gdk::Pixbuf> pixbuf_available;
102 Glib::RefPtr<Gdk::Pixbuf> pixbuf_away;
103 Glib::RefPtr<Gdk::Pixbuf> pixbuf_chat;
104 Glib::RefPtr<Gdk::Pixbuf> pixbuf_dnd;
105 Glib::RefPtr<Gdk::Pixbuf> pixbuf_error;
106 Glib::RefPtr<Gdk::Pixbuf> pixbuf_offline;
107 Glib::RefPtr<Gdk::Pixbuf> pixbuf_xa;
109 class RosterColumns : public Gtk::TreeModel::ColumnRecord
110 {
111 public:
112 RosterColumns()
113 {
114 add(groupColumn);
115 add(statusColumn); add(userColumn);
116 add(nameColumn); add(subColumn);
117 }
119 Gtk::TreeModelColumn<Glib::ustring> groupColumn;
120 Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > statusColumn;
121 Gtk::TreeModelColumn<Glib::ustring> userColumn;
122 Gtk::TreeModelColumn<Glib::ustring> nameColumn;
123 Gtk::TreeModelColumn<Glib::ustring> subColumn;
124 };
126 RosterColumns rosterColumns;
128 Glib::RefPtr<Gtk::UIManager> uiManager;
130 Glib::RefPtr<Gtk::TreeStore> treeStore;
131 CustomTreeView rosterView;
133 PedroGui *parent;
134 };
136 //#########################################################################
137 //# M E S S A G E L I S T
138 //#########################################################################
139 class MessageList : public Gtk::ScrolledWindow
140 {
141 public:
143 MessageList()
144 { doSetup(); }
146 virtual ~MessageList()
147 {}
149 /**
150 * Clear all messages from the list
151 */
152 virtual void clear();
154 /**
155 * Post a message to the list
156 */
157 virtual void postMessage(const DOMString &from, const DOMString &msg);
159 private:
161 bool doSetup();
163 Gtk::TextView messageList;
164 Glib::RefPtr<Gtk::TextBuffer> messageListBuffer;
166 };
168 //#########################################################################
169 //# U S E R L I S T
170 //#########################################################################
171 class UserList : public Gtk::ScrolledWindow
172 {
173 public:
175 UserList()
176 { doSetup(); }
178 virtual ~UserList()
179 {}
181 /**
182 * Clear all messages from the list
183 */
184 virtual void clear();
186 /**
187 * Post a message to the list
188 */
189 virtual void addUser(const DOMString &user, const DOMString &show);
192 void setParent(GroupChatWindow *val)
193 { parent = val; }
195 private:
197 class CustomTreeView : public Gtk::TreeView
198 {
199 public:
200 CustomTreeView()
201 { parent = NULL; }
202 virtual ~CustomTreeView()
203 {}
205 bool on_button_press_event(GdkEventButton* event)
206 {
207 Gtk::TreeView::on_button_press_event(event);
208 if (parent)
209 parent->buttonPressCallback(event);
210 return true;
211 }
212 void setParent(UserList *val)
213 { parent = val; }
215 private:
216 UserList *parent;
217 };
219 void doubleClickCallback(const Gtk::TreeModel::Path &path,
220 Gtk::TreeViewColumn *col);
222 void sendFileCallback();
223 void chatCallback();
224 bool buttonPressCallback(GdkEventButton* event);
226 bool doSetup();
228 Glib::RefPtr<Gdk::Pixbuf> pixbuf_available;
229 Glib::RefPtr<Gdk::Pixbuf> pixbuf_away;
230 Glib::RefPtr<Gdk::Pixbuf> pixbuf_chat;
231 Glib::RefPtr<Gdk::Pixbuf> pixbuf_dnd;
232 Glib::RefPtr<Gdk::Pixbuf> pixbuf_error;
233 Glib::RefPtr<Gdk::Pixbuf> pixbuf_offline;
234 Glib::RefPtr<Gdk::Pixbuf> pixbuf_xa;
236 class UserListColumns : public Gtk::TreeModel::ColumnRecord
237 {
238 public:
239 UserListColumns()
240 { add(statusColumn); add(userColumn); }
242 Gtk::TreeModelColumn<Glib::ustring> userColumn;
243 Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > statusColumn;
244 };
246 UserListColumns userListColumns;
248 Glib::RefPtr<Gtk::UIManager> uiManager;
250 Glib::RefPtr<Gtk::ListStore> userListStore;
251 CustomTreeView userList;
253 GroupChatWindow *parent;
254 };
257 //#########################################################################
258 //# C H A T W I N D O W
259 //#########################################################################
260 class ChatWindow : public Gtk::Window
261 {
262 public:
264 ChatWindow(PedroGui &par, const DOMString jid);
266 virtual ~ChatWindow();
268 virtual DOMString getJid()
269 { return jid; }
271 virtual void setJid(const DOMString &val)
272 { jid = val; }
274 virtual bool postMessage(const DOMString &data);
276 private:
278 DOMString jid;
280 void leaveCallback();
281 void hideCallback();
282 void textEnterCallback();
284 bool doSetup();
286 Gtk::VBox vbox;
287 Gtk::VPaned vPaned;
289 MessageList messageList;
291 Gtk::Entry inputTxt;
293 PedroGui &parent;
294 };
297 //#########################################################################
298 //# G R O U P C H A T W I N D O W
299 //#########################################################################
300 class GroupChatWindow : public Gtk::Window
301 {
302 public:
304 GroupChatWindow(PedroGui &par, const DOMString &groupJid,
305 const DOMString &nick);
307 virtual ~GroupChatWindow();
310 virtual DOMString getGroupJid()
311 { return groupJid; }
313 virtual void setGroupJid(const DOMString &val)
314 { groupJid = val; }
316 virtual DOMString getNick()
317 { return nick; }
319 virtual void setNick(const DOMString &val)
320 { nick = val; }
322 virtual bool receiveMessage(const DOMString &from,
323 const DOMString &data);
325 virtual bool receivePresence(const DOMString &nick,
326 bool presence,
327 const DOMString &show,
328 const DOMString &status);
330 virtual void doSendFile(const DOMString &nick);
332 virtual void doChat(const DOMString &nick);
335 private:
337 void textEnterCallback();
338 void leaveCallback();
339 void hideCallback();
341 bool doSetup();
343 Gtk::VBox vbox;
344 Gtk::VPaned vPaned;
345 Gtk::HPaned hPaned;
347 MessageList messageList;
349 UserList userList;
351 Gtk::Entry inputTxt;
353 DOMString groupJid;
354 DOMString nick;
356 PedroGui &parent;
357 };
361 //#########################################################################
362 //# C O N F I G D I A L O G
363 //#########################################################################
365 class ConfigDialog : public Gtk::Dialog
366 {
367 public:
369 ConfigDialog (PedroGui &par) : parent(par)
370 { doSetup(); }
372 virtual ~ConfigDialog ()
373 {}
375 DOMString getPass()
376 { return passField.get_text(); }
377 DOMString getNewPass()
378 { return newField.get_text(); }
379 DOMString getConfirm()
380 { return confField.get_text(); }
382 protected:
384 //Overloaded from Gtk::Dialog
385 virtual void on_response(int response_id);
387 private:
389 void okCallback();
390 void cancelCallback();
392 bool doSetup();
394 Gtk::Table table;
396 Gtk::Label passLabel;
397 Gtk::Entry passField;
398 Gtk::Label newLabel;
399 Gtk::Entry newField;
400 Gtk::Label confLabel;
401 Gtk::Entry confField;
403 PedroGui &parent;
404 };
407 //#########################################################################
408 //# P A S S W O R D D I A L O G
409 //#########################################################################
410 class PasswordDialog : public Gtk::Dialog
411 {
412 public:
414 PasswordDialog (PedroGui &par) : parent(par)
415 { doSetup(); }
417 virtual ~PasswordDialog ()
418 {}
420 DOMString getPass()
421 { return passField.get_text(); }
422 DOMString getNewPass()
423 { return newField.get_text(); }
424 DOMString getConfirm()
425 { return confField.get_text(); }
427 protected:
429 //Overloaded from Gtk::Dialog
430 virtual void on_response(int response_id);
432 private:
434 void okCallback();
435 void cancelCallback();
437 bool doSetup();
439 Gtk::Table table;
441 Gtk::Label passLabel;
442 Gtk::Entry passField;
443 Gtk::Label newLabel;
444 Gtk::Entry newField;
445 Gtk::Label confLabel;
446 Gtk::Entry confField;
448 PedroGui &parent;
449 };
453 //#########################################################################
454 //# C H A T D I A L O G
455 //#########################################################################
456 class ChatDialog : public Gtk::Dialog
457 {
458 public:
460 ChatDialog(PedroGui &par) : parent(par)
461 { doSetup(); }
463 virtual ~ChatDialog()
464 {}
466 DOMString getUser()
467 { return userField.get_text(); }
469 DOMString getText()
470 { return textField.get_text(); }
472 private:
474 void okCallback();
475 void cancelCallback();
477 bool doSetup();
479 Gtk::Table table;
481 Gtk::Label userLabel;
482 Gtk::Entry userField;
483 Gtk::Entry textField;
485 PedroGui &parent;
486 };
490 //#########################################################################
491 //# G R O U P C H A T D I A L O G
492 //#########################################################################
494 class GroupChatDialog : public Gtk::Dialog
495 {
496 public:
498 GroupChatDialog(PedroGui &par) : parent(par)
499 { doSetup(); }
501 virtual ~GroupChatDialog()
502 {}
504 DOMString getGroup()
505 { return groupField.get_text(); }
506 DOMString getHost()
507 { return hostField.get_text(); }
508 DOMString getPass()
509 { return passField.get_text(); }
510 DOMString getNick()
511 { return nickField.get_text(); }
513 private:
515 void okCallback();
516 void cancelCallback();
518 bool doSetup();
520 Gtk::Table table;
522 Gtk::Label groupLabel;
523 Gtk::Entry groupField;
524 Gtk::Label hostLabel;
525 Gtk::Entry hostField;
526 Gtk::Label passLabel;
527 Gtk::Entry passField;
528 Gtk::Label nickLabel;
529 Gtk::Entry nickField;
531 PedroGui &parent;
532 };
535 //#########################################################################
536 //# C O N N E C T D I A L O G
537 //#########################################################################
538 class ConnectDialog : public Gtk::Dialog
539 {
540 public:
542 ConnectDialog (PedroGui &par) : parent(par)
543 { doSetup(); }
545 virtual ~ConnectDialog ()
546 {}
548 DOMString getHost()
549 { return hostField.get_text(); }
550 void setHost(const DOMString &val)
551 { hostField.set_text(val); }
552 int getPort()
553 { return (int)portSpinner.get_value(); }
554 void setPort(int val)
555 { portSpinner.set_value(val); }
556 DOMString getUser()
557 { return userField.get_text(); }
558 void setUser(const DOMString &val)
559 { userField.set_text(val); }
560 DOMString getPass()
561 { return passField.get_text(); }
562 void setPass(const DOMString &val)
563 { passField.set_text(val); }
564 DOMString getResource()
565 { return resourceField.get_text(); }
566 void setResource(const DOMString &val)
567 { resourceField.set_text(val); }
568 bool getRegister()
569 { return registerButton.get_active(); }
571 /**
572 * Regenerate the account list
573 */
574 virtual void refresh();
576 private:
578 void okCallback();
579 void saveCallback();
580 void cancelCallback();
581 void doubleClickCallback(
582 const Gtk::TreeModel::Path &path,
583 Gtk::TreeViewColumn *col);
584 void selectedCallback();
586 bool doSetup();
588 Gtk::Table table;
590 Gtk::Label hostLabel;
591 Gtk::Entry hostField;
592 Gtk::Label portLabel;
593 Gtk::SpinButton portSpinner;
594 Gtk::Label userLabel;
595 Gtk::Entry userField;
596 Gtk::Label passLabel;
597 Gtk::Entry passField;
598 Gtk::Label resourceLabel;
599 Gtk::Entry resourceField;
600 Gtk::Label registerLabel;
601 Gtk::CheckButton registerButton;
603 Glib::RefPtr<Gtk::UIManager> uiManager;
606 //## Account list
608 void buttonPressCallback(GdkEventButton* event);
610 Gtk::ScrolledWindow accountScroll;
612 void connectCallback();
614 void modifyCallback();
616 void deleteCallback();
619 class AccountColumns : public Gtk::TreeModel::ColumnRecord
620 {
621 public:
622 AccountColumns()
623 {
624 add(nameColumn);
625 add(hostColumn);
626 }
628 Gtk::TreeModelColumn<Glib::ustring> nameColumn;
629 Gtk::TreeModelColumn<Glib::ustring> hostColumn;
630 };
632 AccountColumns accountColumns;
634 Glib::RefPtr<Gtk::UIManager> accountUiManager;
636 Glib::RefPtr<Gtk::ListStore> accountListStore;
637 Gtk::TreeView accountView;
640 PedroGui &parent;
641 };
646 //#########################################################################
647 //# F I L E S E N D D I A L O G
648 //#########################################################################
650 class FileSendDialog : public Gtk::Dialog
651 {
652 public:
654 FileSendDialog(PedroGui &par) : parent(par)
655 { doSetup(); }
657 virtual ~FileSendDialog()
658 {}
660 DOMString getFileName()
661 { return fileName; }
662 DOMString getJid()
663 { return jidField.get_text(); }
664 void setJid(const DOMString &val)
665 { return jidField.set_text(val); }
667 private:
669 void okCallback();
670 void cancelCallback();
671 void buttonCallback();
673 bool doSetup();
675 Gtk::Table table;
677 Gtk::Label jidLabel;
678 Gtk::Entry jidField;
680 DOMString fileName;
681 Gtk::Entry fileNameField;
683 Gtk::Button selectFileButton;
685 PedroGui &parent;
686 };
688 //#########################################################################
689 //# F I L E R E C E I V E D I A L O G
690 //#########################################################################
692 class FileReceiveDialog : public Gtk::Dialog
693 {
694 public:
696 FileReceiveDialog(PedroGui &par,
697 const DOMString &jidArg,
698 const DOMString &iqIdArg,
699 const DOMString &streamIdArg,
700 const DOMString &offeredNameArg,
701 const DOMString &descArg,
702 long sizeArg,
703 const DOMString &hashArg
704 ) : parent(par)
705 {
706 jid = jidArg;
707 iqId = iqIdArg;
708 streamId = streamIdArg;
709 offeredName = offeredNameArg;
710 desc = descArg;
711 fileSize = sizeArg;
712 hash = hashArg;
713 doSetup();
714 }
716 virtual ~FileReceiveDialog()
717 {}
719 DOMString getJid()
720 { return jid; }
721 DOMString getIq()
722 { return iqId; }
723 DOMString getStreamId()
724 { return streamId; }
725 DOMString getOfferedName()
726 { return offeredName; }
727 DOMString getFileName()
728 { return fileName; }
729 DOMString getDescription()
730 { return desc; }
731 long getSize()
732 { return fileSize; }
733 DOMString getHash()
734 { return hash; }
736 private:
738 void okCallback();
739 void cancelCallback();
740 void buttonCallback();
742 bool doSetup();
744 Gtk::Table table;
746 Gtk::Label jidLabel;
747 Gtk::Entry jidField;
748 Gtk::Label offeredLabel;
749 Gtk::Entry offeredField;
750 Gtk::Label descLabel;
751 Gtk::Entry descField;
752 Gtk::Label sizeLabel;
753 Gtk::Entry sizeField;
754 Gtk::Label hashLabel;
755 Gtk::Entry hashField;
757 Gtk::Entry fileNameField;
759 Gtk::Button selectFileButton;
761 DOMString jid;
762 DOMString iqId;
763 DOMString streamId;
764 DOMString offeredName;
765 DOMString desc;
766 long fileSize;
767 DOMString hash;
769 DOMString fileName;
771 PedroGui &parent;
772 };
776 //#########################################################################
777 //# M A I N W I N D O W
778 //#########################################################################
780 class PedroGui : public Gtk::Window
781 {
782 public:
784 PedroGui();
786 virtual ~PedroGui();
788 //Let everyone share these
789 XmppClient client;
790 XmppConfig config;
793 virtual void error(const char *fmt, ...) G_GNUC_PRINTF(2,3);
795 virtual void status(const char *fmt, ...) G_GNUC_PRINTF(2,3);
799 void handleConnectEvent();
801 void handleDisconnectEvent();
803 /**
804 *
805 */
806 virtual void doEvent(const XmppEvent &event);
808 /**
809 *
810 */
811 bool checkEventQueue();
814 bool chatCreate(const DOMString &userJid);
815 bool chatDelete(const DOMString &userJid);
816 bool chatDeleteAll();
817 bool chatMessage(const DOMString &jid, const DOMString &data);
819 bool groupChatCreate(const DOMString &groupJid,
820 const DOMString &nick);
821 bool groupChatDelete(const DOMString &groupJid,
822 const DOMString &nick);
823 bool groupChatDeleteAll();
824 bool groupChatMessage(const DOMString &groupJid,
825 const DOMString &from, const DOMString &data);
826 bool groupChatPresence(const DOMString &groupJid,
827 const DOMString &nick,
828 bool presence,
829 const DOMString &show,
830 const DOMString &status);
832 void doChat(const DOMString &jid);
833 void doSendFile(const DOMString &jid);
834 void doReceiveFile(const DOMString &jid,
835 const DOMString &iqId,
836 const DOMString &streamId,
837 const DOMString &offeredName,
838 const DOMString &desc,
839 long size,
840 const DOMString &hash);
843 //# File menu
844 void connectCallback();
845 void chatCallback();
846 void groupChatCallback();
847 void disconnectCallback();
848 void quitCallback();
850 //# Edit menu
851 void fontCallback();
852 void colorCallback();
854 //# Transfer menu
855 void sendFileCallback();
857 //# Registration menu
858 void regPassCallback();
859 void regCancelCallback();
861 //# Help menu
862 void aboutCallback();
864 //# Configuration file
865 bool configLoad();
866 bool configSave();
869 private:
871 bool doSetup();
873 Gtk::VBox mainBox;
875 Gtk::HBox menuBarBox;
877 Gtk::Image padlockIcon;
878 void padlockEnable();
879 void padlockDisable();
882 Pango::FontDescription fontDesc;
883 Gdk::Color foregroundColor;
884 Gdk::Color backgroundColor;
886 Gtk::VPaned vPaned;
887 MessageList messageList;
888 Roster roster;
890 Glib::RefPtr<Gtk::UIManager> uiManager;
891 void actionEnable(const DOMString &name, bool val);
893 std::vector<ChatWindow *>chats;
895 std::vector<GroupChatWindow *>groupChats;
896 };
899 } //namespace Pedro
901 #endif /* __PEDROGUI_H__ */
902 //#########################################################################
903 //# E N D O F F I L E
904 //#########################################################################