Code

Display CMS adjustment per-desktop view
[inkscape.git] / src / pedro / pedrogui.cpp
index 48dfa94e91c9401ab0452bf9d0fbf103c5a53491..38c66b40771fbffc73990d3c54150eaffc55d899 100644 (file)
@@ -4,7 +4,7 @@
  * Authors:
  *   Bob Jamison
  *
- * Copyright (C) 2005 Bob Jamison
+ * Copyright (C) 2005-2007 Bob Jamison
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -894,7 +894,7 @@ bool ChatWindow::doSetup()
     Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
     actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
     actionGroup->add( Gtk::Action::create("Leave",  Gtk::Stock::CANCEL),
-    sigc::mem_fun(*this, &ChatWindow::leaveCallback) );
+        sigc::mem_fun(*this, &ChatWindow::leaveCallback) );
 
 
     Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
@@ -993,7 +993,7 @@ bool GroupChatWindow::doSetup()
     Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
     actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
     actionGroup->add( Gtk::Action::create("Leave",  Gtk::Stock::CANCEL),
-    sigc::mem_fun(*this, &GroupChatWindow::leaveCallback) );
+        sigc::mem_fun(*this, &GroupChatWindow::leaveCallback) );
 
 
     Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
@@ -1060,7 +1060,10 @@ bool GroupChatWindow::receivePresence(const DOMString &fromNick,
             presStr.append(show);
             }
         }
-    messageList.postMessage("*", presStr);
+
+    if (presStr != "xa")
+        messageList.postMessage("*", presStr);
+
     userList.clear();
     std::vector<XmppUser> memberList =
          parent.client.groupChatGetUserList(groupJid);
@@ -1094,35 +1097,63 @@ void GroupChatWindow::doSendFile(const DOMString &nick)
 
 
 
+
 //#########################################################################
-//# C O N N E C T    D I A L O G
+//# C O N F I G    D I A L O G
 //#########################################################################
 
 
-void ConnectDialog::okCallback()
+void ConfigDialog::okCallback()
 {
-    response(Gtk::RESPONSE_OK);
-    hide();
+    Glib::ustring pass     = passField.get_text();
+    Glib::ustring newpass  = newField.get_text();
+    Glib::ustring confpass = confField.get_text();
+    if ((pass.size()     < 5 || pass.size()    > 12 ) ||
+        (newpass.size()  < 5 || newpass.size() > 12 ) ||
+        (confpass.size() < 5 || confpass.size()> 12 ))
+        {
+        Gtk::MessageDialog dlg(*this, "Password must be 5 to 12 characters",
+            false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
+        dlg.run();
+        }
+    else if (newpass != confpass)
+        {
+        Gtk::MessageDialog dlg(*this, "New password and confirmation do not match",
+            false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
+        dlg.run();
+        }
+    else
+        {
+        //response(Gtk::RESPONSE_OK);
+        hide();
+        }
 }
 
-void ConnectDialog::cancelCallback()
+void ConfigDialog::cancelCallback()
 {
-    response(Gtk::RESPONSE_CANCEL);
+    //response(Gtk::RESPONSE_CANCEL);
     hide();
 }
 
+void ConfigDialog::on_response(int response_id)
+{
+    if (response_id == Gtk::RESPONSE_OK)
+        okCallback();
+    else
+        cancelCallback();
+}
 
-bool ConnectDialog::doSetup()
+bool ConfigDialog::doSetup()
 {
-    set_title("Connect");
+    set_title("Change Password");
     set_size_request(300,200);
 
     Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
     actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
-    actionGroup->add( Gtk::Action::create("Connect", Gtk::Stock::CONNECT, "Connect"),
-    sigc::mem_fun(*this, &ConnectDialog::okCallback) );
+    actionGroup->add( Gtk::Action::create("Change", Gtk::Stock::OK, "Change Password"),
+        sigc::mem_fun(*this, &ConfigDialog::okCallback) );
     actionGroup->add( Gtk::Action::create("Cancel",  Gtk::Stock::CANCEL, "Cancel"),
-    sigc::mem_fun(*this, &ConnectDialog::cancelCallback) );
+         sigc::mem_fun(*this, &ConfigDialog::cancelCallback) );
 
 
     Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
@@ -1134,7 +1165,7 @@ bool ConnectDialog::doSetup()
         "<ui>"
         "  <menubar name='MenuBar'>"
         "    <menu action='MenuFile'>"
-        "      <menuitem action='Connect'/>"
+        "      <menuitem action='Change'/>"
         "      <separator/>"
         "      <menuitem action='Cancel'/>"
         "    </menu>"
@@ -1145,52 +1176,136 @@ bool ConnectDialog::doSetup()
     Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
     get_vbox()->pack_start(*pMenuBar, Gtk::PACK_SHRINK);
 
-    table.resize(6, 2);
+    table.resize(3, 2);
     get_vbox()->pack_start(table);
 
-    parent.client.setHost("broadway.dynalias.com");
-    parent.client.setPort(5223);
-    parent.client.setUsername("");
-    parent.client.setPassword("");
-    parent.client.setResource("pedroXmpp");
+    passLabel.set_text("Current Password");
+    table.attach(passLabel, 0, 1, 0, 1);
+    passField.set_visibility(false);
+    passField.set_text(parent.client.getPassword());
+    table.attach(passField, 1, 2, 0, 1);
 
-    hostLabel.set_text("Host");
-    table.attach(hostLabel, 0, 1, 0, 1);
-    hostField.set_text(parent.client.getHost());
-    table.attach(hostField, 1, 2, 0, 1);
+    newLabel.set_text("New Password");
+    table.attach(newLabel, 0, 1, 1, 2);
+    newField.set_visibility(false);
+    table.attach(newField, 1, 2, 1, 2);
 
-    portLabel.set_text("Port");
-    table.attach(portLabel, 0, 1, 1, 2);
-    portSpinner.set_digits(0);
-    portSpinner.set_range(1, 65000);
-    portSpinner.set_value(parent.client.getPort());
-    table.attach(portSpinner, 1, 2, 1, 2);
+    confLabel.set_text("Confirm New Password");
+    table.attach(confLabel, 0, 1, 2, 3);
+    confField.set_visibility(false);
+    confField.signal_activate().connect(
+           sigc::mem_fun(*this, &ConfigDialog::okCallback) );
+    table.attach(confField, 1, 2, 2, 3);
 
-    userLabel.set_text("Username");
-    table.attach(userLabel, 0, 1, 2, 3);
-    userField.set_text(parent.client.getUsername());
-    table.attach(userField, 1, 2, 2, 3);
+    add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
+    add_button(Gtk::Stock::OK,     Gtk::RESPONSE_OK);
 
-    passLabel.set_text("Password");
-    table.attach(passLabel, 0, 1, 3, 4);
+    show_all_children();
+
+    return true;
+}
+
+//#########################################################################
+//# P A S S W O R D      D I A L O G
+//#########################################################################
+
+
+void PasswordDialog::okCallback()
+{
+    Glib::ustring pass     = passField.get_text();
+    Glib::ustring newpass  = newField.get_text();
+    Glib::ustring confpass = confField.get_text();
+    if ((pass.size()     < 5 || pass.size()    > 12 ) ||
+        (newpass.size()  < 5 || newpass.size() > 12 ) ||
+        (confpass.size() < 5 || confpass.size()> 12 ))
+        {
+        Gtk::MessageDialog dlg(*this, "Password must be 5 to 12 characters",
+            false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
+        dlg.run();
+        }
+    else if (newpass != confpass)
+        {
+        Gtk::MessageDialog dlg(*this, "New password and confirmation do not match",
+            false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
+        dlg.run();
+        }
+    else
+        {
+        //response(Gtk::RESPONSE_OK);
+        hide();
+        }
+}
+
+void PasswordDialog::cancelCallback()
+{
+    //response(Gtk::RESPONSE_CANCEL);
+    hide();
+}
+
+void PasswordDialog::on_response(int response_id)
+{
+    if (response_id == Gtk::RESPONSE_OK)
+        okCallback();
+    else
+        cancelCallback();
+}
+
+bool PasswordDialog::doSetup()
+{
+    set_title("Change Password");
+    set_size_request(300,200);
+
+    Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
+    actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
+    actionGroup->add( Gtk::Action::create("Change", Gtk::Stock::OK, "Change Password"),
+        sigc::mem_fun(*this, &PasswordDialog::okCallback) );
+    actionGroup->add( Gtk::Action::create("Cancel",  Gtk::Stock::CANCEL, "Cancel"),
+        sigc::mem_fun(*this, &PasswordDialog::cancelCallback) );
+
+
+    Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
+
+    uiManager->insert_action_group(actionGroup, 0);
+    add_accel_group(uiManager->get_accel_group());
+
+    Glib::ustring ui_info =
+        "<ui>"
+        "  <menubar name='MenuBar'>"
+        "    <menu action='MenuFile'>"
+        "      <menuitem action='Change'/>"
+        "      <separator/>"
+        "      <menuitem action='Cancel'/>"
+        "    </menu>"
+        "  </menubar>"
+        "</ui>";
+
+    uiManager->add_ui_from_string(ui_info);
+    Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
+    get_vbox()->pack_start(*pMenuBar, Gtk::PACK_SHRINK);
+
+    table.resize(3, 2);
+    get_vbox()->pack_start(table);
+
+    passLabel.set_text("Current Password");
+    table.attach(passLabel, 0, 1, 0, 1);
     passField.set_visibility(false);
     passField.set_text(parent.client.getPassword());
-    passField.signal_activate().connect(
-           sigc::mem_fun(*this, &ConnectDialog::okCallback) );
-    table.attach(passField, 1, 2, 3, 4);
+    table.attach(passField, 1, 2, 0, 1);
 
-    resourceLabel.set_text("Resource");
-    table.attach(resourceLabel, 0, 1, 4, 5);
-    resourceField.set_text(parent.client.getResource());
-    table.attach(resourceField, 1, 2, 4, 5);
+    newLabel.set_text("New Password");
+    table.attach(newLabel, 0, 1, 1, 2);
+    newField.set_visibility(false);
+    table.attach(newField, 1, 2, 1, 2);
 
-    registerLabel.set_text("Register");
-    table.attach(registerLabel, 0, 1, 5, 6);
-    registerButton.set_active(false);
-    table.attach(registerButton, 1, 2, 5, 6);
+    confLabel.set_text("Confirm New Password");
+    table.attach(confLabel, 0, 1, 2, 3);
+    confField.set_visibility(false);
+    confField.signal_activate().connect(
+           sigc::mem_fun(*this, &PasswordDialog::okCallback) );
+    table.attach(confField, 1, 2, 2, 3);
 
     add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
-    add_button(Gtk::Stock::OPEN,   Gtk::RESPONSE_OK);
+    add_button(Gtk::Stock::OK,     Gtk::RESPONSE_OK);
 
     show_all_children();
 
@@ -1323,35 +1438,330 @@ bool GroupChatDialog::doSetup()
 
     groupLabel.set_text("Group");
     table.attach(groupLabel, 0, 1, 0, 1);
-    groupField.set_text("inkscape");
+    groupField.set_text(parent.config.getMucGroup());
     table.attach(groupField, 1, 2, 0, 1);
 
     hostLabel.set_text("Host");
     table.attach(hostLabel, 0, 1, 1, 2);
-    hostField.set_text("conference.gristle.org");
+    hostField.set_text(parent.config.getMucHost());
     table.attach(hostField, 1, 2, 1, 2);
 
     nickLabel.set_text("Alt Name");
     table.attach(nickLabel, 0, 1, 2, 3);
+    nickField.set_text(parent.config.getMucNick());
     table.attach(nickField, 1, 2, 2, 3);
 
     passLabel.set_text("Password");
     table.attach(passLabel, 0, 1, 3, 4);
     passField.set_visibility(false);
-    //passField.set_text("");
+    passField.set_text(parent.config.getMucPassword());
+    table.attach(passField, 1, 2, 3, 4);
+
+
+    add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
+    add_button(Gtk::Stock::OPEN,   Gtk::RESPONSE_OK);
+
+    show_all_children();
+
+    return true;
+}
+
+
+
+
+//#########################################################################
+//# C O N N E C T    D I A L O G
+//#########################################################################
+
+
+void ConnectDialog::okCallback()
+{
+    response(Gtk::RESPONSE_OK);
+    hide();
+}
+
+void ConnectDialog::saveCallback()
+{
+    Gtk::Entry txtField;
+    Gtk::Dialog dlg("Account name", *this, true, true);
+    dlg.get_vbox()->pack_start(txtField);
+    txtField.signal_activate().connect(
+           sigc::bind(sigc::mem_fun(dlg, &Gtk::Dialog::response),
+              Gtk::RESPONSE_OK  ));
+    dlg.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
+    dlg.add_button(Gtk::Stock::OK,     Gtk::RESPONSE_OK);
+    dlg.show_all_children();
+    int ret = dlg.run();
+    if (ret != Gtk::RESPONSE_OK)
+        return;
+
+    Glib::ustring name = txtField.get_text();
+    if (name.size() < 1)
+        {
+        parent.error("Account name too short");
+        return;
+        }
+
+    if (parent.config.accountExists(name))
+        {
+        parent.config.accountRemove(name);          
+        }
+
+    XmppAccount account;
+    account.setName(name);
+    account.setHost(getHost());
+    account.setPort(getPort());
+    account.setUsername(getUser());
+    account.setPassword(getPass());
+    parent.config.accountAdd(account);
+
+    refresh();
+
+    parent.configSave();
+}
+
+void ConnectDialog::cancelCallback()
+{
+    response(Gtk::RESPONSE_CANCEL);
+    hide();
+}
+
+
+void ConnectDialog::doubleClickCallback(
+                   const Gtk::TreeModel::Path &path,
+                   Gtk::TreeViewColumn *col)
+{
+    Glib::RefPtr<Gtk::TreeModel> model = accountView.get_model();
+    Glib::RefPtr<Gtk::TreeSelection> sel = accountView.get_selection();
+    Gtk::TreeModel::iterator iter = sel->get_selected();
+    DOMString name = iter->get_value(accountColumns.nameColumn);
+    //printf("Double clicked:%s\n", name.c_str());
+    XmppAccount account;
+    if (!parent.config.accountFind(name, account))
+        return;
+    setHost(account.getHost()); 
+    setPort(account.getPort()); 
+    setUser(account.getUsername()); 
+    setPass(account.getPassword()); 
+
+    response(Gtk::RESPONSE_OK);
+    hide();
+}
+
+void ConnectDialog::selectedCallback()
+{
+    Glib::RefPtr<Gtk::TreeModel> model = accountView.get_model();
+    Glib::RefPtr<Gtk::TreeSelection> sel = accountView.get_selection();
+    Gtk::TreeModel::iterator iter = sel->get_selected();
+    DOMString name = iter->get_value(accountColumns.nameColumn);
+    //printf("Single clicked:%s\n", name.c_str());
+    XmppAccount account;
+    if (!parent.config.accountFind(name, account))
+        return;
+    setHost(account.getHost()); 
+    setPort(account.getPort()); 
+    setUser(account.getUsername()); 
+    setPass(account.getPassword()); 
+}
+
+void ConnectDialog::deleteCallback()
+{
+    Glib::RefPtr<Gtk::TreeModel> model = accountView.get_model();
+    Glib::RefPtr<Gtk::TreeSelection> sel = accountView.get_selection();
+    Gtk::TreeModel::iterator iter = sel->get_selected();
+    DOMString name = iter->get_value(accountColumns.nameColumn);
+
+    parent.config.accountRemove(name);
+    refresh();
+    parent.configSave();
+    
+}
+
+
+
+void ConnectDialog::buttonPressCallback(GdkEventButton* event)
+{
+    if( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) )
+        {
+        Gtk::Widget *wid = accountUiManager->get_widget("/PopupMenu");
+        Gtk::Menu *popupMenu = dynamic_cast<Gtk::Menu*>(wid);
+        popupMenu->popup(event->button, event->time);
+        }
+}
+
+
+bool ConnectDialog::doSetup()
+{
+    set_title("Connect");
+    set_size_request(300,400);
+
+    Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
+    actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
+    actionGroup->add( Gtk::Action::create("Connect",
+        Gtk::Stock::CONNECT, "Connect"),
+        sigc::mem_fun(*this, &ConnectDialog::okCallback) );
+    actionGroup->add( Gtk::Action::create("Save",
+        Gtk::Stock::CONNECT, "Save as account"),
+        sigc::mem_fun(*this, &ConnectDialog::saveCallback) );
+    actionGroup->add( Gtk::Action::create("Cancel",
+        Gtk::Stock::CANCEL, "Cancel"),
+        sigc::mem_fun(*this, &ConnectDialog::cancelCallback) );
+
+
+    Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
+
+    uiManager->insert_action_group(actionGroup, 0);
+    add_accel_group(uiManager->get_accel_group());
+
+    Glib::ustring ui_info =
+        "<ui>"
+        "  <menubar name='MenuBar'>"
+        "    <menu action='MenuFile'>"
+        "      <menuitem action='Connect'/>"
+        "      <separator/>"
+        "      <menuitem action='Save'/>"
+        "      <separator/>"
+        "      <menuitem action='Cancel'/>"
+        "    </menu>"
+        "  </menubar>"
+        "</ui>";
+
+    uiManager->add_ui_from_string(ui_info);
+    Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
+    get_vbox()->pack_start(*pMenuBar, Gtk::PACK_SHRINK);
+
+    table.resize(6, 2);
+    get_vbox()->pack_start(table);
+
+    parent.client.setHost("broadway.dynalias.com");
+    parent.client.setPort(5222);
+    parent.client.setUsername("");
+    parent.client.setPassword("");
+    parent.client.setResource("pedroXmpp");
+
+    hostLabel.set_text("Host");
+    table.attach(hostLabel, 0, 1, 0, 1);
+    hostField.set_text(parent.client.getHost());
+    table.attach(hostField, 1, 2, 0, 1);
+
+    portLabel.set_text("Port");
+    table.attach(portLabel, 0, 1, 1, 2);
+    portSpinner.set_digits(0);
+    portSpinner.set_range(1, 65000);
+    portSpinner.set_value(parent.client.getPort());
+    table.attach(portSpinner, 1, 2, 1, 2);
+
+    userLabel.set_text("Username");
+    table.attach(userLabel, 0, 1, 2, 3);
+    userField.set_text(parent.client.getUsername());
+    table.attach(userField, 1, 2, 2, 3);
+
+    passLabel.set_text("Password");
+    table.attach(passLabel, 0, 1, 3, 4);
+    passField.set_visibility(false);
+    passField.set_text(parent.client.getPassword());
+    passField.signal_activate().connect(
+           sigc::mem_fun(*this, &ConnectDialog::okCallback) );
     table.attach(passField, 1, 2, 3, 4);
 
+    resourceLabel.set_text("Resource");
+    table.attach(resourceLabel, 0, 1, 4, 5);
+    resourceField.set_text(parent.client.getResource());
+    table.attach(resourceField, 1, 2, 4, 5);
+
+    registerLabel.set_text("Register");
+    table.attach(registerLabel, 0, 1, 5, 6);
+    registerButton.set_active(false);
+    table.attach(registerButton, 1, 2, 5, 6);
 
     add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
     add_button(Gtk::Stock::OPEN,   Gtk::RESPONSE_OK);
 
+
+    //######################
+    //# ACCOUNT LIST
+    //######################
+
+
+    accountListStore = Gtk::ListStore::create(accountColumns);
+    accountView.set_model(accountListStore);
+
+    accountView.signal_row_activated().connect(
+        sigc::mem_fun(*this, &ConnectDialog::doubleClickCallback) );
+
+    accountView.get_selection()->signal_changed().connect(
+        sigc::mem_fun(*this, &ConnectDialog::selectedCallback) );
+
+    accountView.append_column("Account", accountColumns.nameColumn);
+    accountView.append_column("Host",    accountColumns.hostColumn);
+
+    //accountView.signal_row_activated().connect(
+    //    sigc::mem_fun(*this, &AccountDialog::connectCallback) );
+
+    accountScroll.add(accountView);
+    accountScroll.set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS);
+
+    get_vbox()->pack_start(accountScroll);
+
+    //##### POPUP MENU
+    accountView.signal_button_press_event().connect_notify(
+        sigc::mem_fun(*this, &ConnectDialog::buttonPressCallback) );
+
+    Glib::RefPtr<Gtk::ActionGroup> accountActionGroup =
+                Gtk::ActionGroup::create();
+
+    accountActionGroup->add( Gtk::Action::create("PopupMenu", "_Account") );
+
+    accountActionGroup->add( Gtk::Action::create("Delete",
+                                  Gtk::Stock::DELETE, "Delete"),
+        sigc::mem_fun(*this, &ConnectDialog::deleteCallback) );
+
+
+    accountUiManager = Gtk::UIManager::create();
+
+    accountUiManager->insert_action_group(accountActionGroup, 0);
+
+    Glib::ustring account_ui_info =
+        "<ui>"
+        "  <popup name='PopupMenu'>"
+        "    <menuitem action='Delete'/>"
+        "  </popup>"
+        "</ui>";
+
+    accountUiManager->add_ui_from_string(account_ui_info);
+    //Gtk::Widget* accountMenuBar = uiManager->get_widget("/PopupMenu");
+    //get_vbox()->pack_start(*accountMenuBar, Gtk::PACK_SHRINK);
+
+    refresh();
+
     show_all_children();
 
     return true;
 }
 
+
+/**
+ * Regenerate the account list
+ */
+void ConnectDialog::refresh()
+{
+    accountListStore->clear();
+
+    std::vector<XmppAccount> accounts = parent.config.getAccounts();
+    for (unsigned int i=0 ; i<accounts.size() ; i++)
+        {
+        XmppAccount account = accounts[i];
+        Gtk::TreeModel::Row row = *(accountListStore->append());
+        row[accountColumns.nameColumn] = account.getName();
+        row[accountColumns.hostColumn] = account.getHost();
+        }
+    accountView.expand_all();
+}
+
+
+
 //#########################################################################
-//# F I L E    S E N D   D I A L O G
+//# F I L E    S E N D    D I A L O G
 //#########################################################################
 
 
@@ -1390,9 +1800,9 @@ bool FileSendDialog::doSetup()
     Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
     actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
     actionGroup->add( Gtk::Action::create("Send", Gtk::Stock::NETWORK, "Send File"),
-    sigc::mem_fun(*this, &FileSendDialog::okCallback) );
+        sigc::mem_fun(*this, &FileSendDialog::okCallback) );
     actionGroup->add( Gtk::Action::create("Cancel",  Gtk::Stock::CANCEL, "Cancel"),
-    sigc::mem_fun(*this, &FileSendDialog::cancelCallback) );
+        sigc::mem_fun(*this, &FileSendDialog::cancelCallback) );
 
 
     Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
@@ -1482,9 +1892,9 @@ bool FileReceiveDialog::doSetup()
     Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
     actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
     actionGroup->add( Gtk::Action::create("Send", Gtk::Stock::NETWORK, "Send File"),
-    sigc::mem_fun(*this, &FileReceiveDialog::okCallback) );
+        sigc::mem_fun(*this, &FileReceiveDialog::okCallback) );
     actionGroup->add( Gtk::Action::create("Cancel",  Gtk::Stock::CANCEL, "Cancel"),
-    sigc::mem_fun(*this, &FileReceiveDialog::cancelCallback) );
+        sigc::mem_fun(*this, &FileReceiveDialog::cancelCallback) );
 
 
     Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
@@ -1582,24 +1992,26 @@ void PedroGui::error(const char *fmt, ...)
 {
     va_list args;
     va_start(args, fmt);
-    vsnprintf(writeBuf, writeBufLen, fmt, args);
+    gchar * buffer = g_strdup_vprintf(fmt, args);
     va_end(args) ;
 
-    Gtk::MessageDialog dlg(writeBuf,
+    Gtk::MessageDialog dlg(buffer,
                            false,
                            Gtk::MESSAGE_ERROR,
                            Gtk::BUTTONS_OK,
                            true);
     dlg.run();
+    g_free(buffer);
 }
 
 void PedroGui::status(const char *fmt, ...)
 {
     va_list args;
     va_start(args, fmt);
-    vsnprintf(writeBuf, writeBufLen, fmt, args);
+    gchar * buffer = g_strdup_vprintf(fmt, args);
     va_end(args) ;
-    messageList.postMessage("STATUS", writeBuf);
+    messageList.postMessage("STATUS", buffer);
+    g_free(buffer);
 }
 
 //################################
@@ -1664,9 +2076,11 @@ bool PedroGui::chatMessage(const DOMString &from, const DOMString &data)
     return true;
 }
 
+
 //################################
 //# GROUP CHAT WINDOW MANAGEMENT
 //################################
+
 bool PedroGui::groupChatCreate(const DOMString &groupJid, const DOMString &nick)
 {
     std::vector<GroupChatWindow *>::iterator iter;
@@ -1745,6 +2159,64 @@ bool PedroGui::groupChatPresence(const DOMString &groupJid,
 //################################
 //# EVENTS
 //################################
+
+/**
+ *
+ */
+void PedroGui::padlockEnable()
+{
+    padlockIcon.set(Gtk::Stock::DIALOG_AUTHENTICATION,
+               Gtk::ICON_SIZE_MENU);
+}
+
+/**
+ *
+ */
+void PedroGui::padlockDisable()
+{
+    padlockIcon.clear();
+}
+
+
+/**
+ *
+ */
+void PedroGui::handleConnectEvent()
+{
+     status("##### CONNECTED");
+     actionEnable("Connect",    false);
+     actionEnable("Chat",       true);
+     actionEnable("GroupChat",  true);
+     actionEnable("Disconnect", true);
+     actionEnable("RegPass",    true);
+     actionEnable("RegCancel",  true);
+     DOMString title = "Pedro - ";
+     title.append(client.getJid());
+     set_title(title);
+}
+
+
+/**
+ *
+ */
+void PedroGui::handleDisconnectEvent()
+{
+     status("##### DISCONNECTED");
+     actionEnable("Connect",    true);
+     actionEnable("Chat",       false);
+     actionEnable("GroupChat",  false);
+     actionEnable("Disconnect", false);
+     actionEnable("RegPass",    false);
+     actionEnable("RegCancel",  false);
+     padlockDisable();
+     DOMString title = "Pedro";
+     set_title(title);
+     chatDeleteAll();
+     groupChatDeleteAll();
+     roster.clear();
+}
+
+
 /**
  *
  */
@@ -1757,38 +2229,29 @@ void PedroGui::doEvent(const XmppEvent &event)
         case XmppEvent::EVENT_STATUS:
             {
             //printf("##### STATUS: %s\n", event.getData().c_str());
-            status(event.getData().c_str());
+            status("%s", event.getData().c_str());
             break;
             }
         case XmppEvent::EVENT_ERROR:
             {
             //printf("##### ERROR: %s\n", event.getData().c_str());
-            error(event.getData().c_str());
+            error("%s", event.getData().c_str());
+            padlockDisable();
+            break;
+            }
+        case XmppEvent::EVENT_SSL_STARTED:
+            {
+            padlockEnable();
             break;
             }
         case XmppEvent::EVENT_CONNECTED:
             {
-            status("##### CONNECTED");
-            actionEnable("Connect",    false);
-            actionEnable("Chat",       true);
-            actionEnable("GroupChat",  true);
-            actionEnable("Disconnect", true);
-            DOMString title = "Pedro - ";
-            title.append(client.getJid());
-            set_title(title);
+            handleConnectEvent();
             break;
             }
         case XmppEvent::EVENT_DISCONNECTED:
             {
-            status("##### DISCONNECTED");
-            actionEnable("Connect",    true);
-            actionEnable("Chat",       false);
-            actionEnable("GroupChat",  false);
-            actionEnable("Disconnect", false);
-            DOMString title = "Pedro";
-            set_title(title);
-            chatDeleteAll();
-            groupChatDeleteAll();
+            handleDisconnectEvent();
             break;
             }
         case XmppEvent::EVENT_MESSAGE:
@@ -1845,6 +2308,25 @@ void PedroGui::doEvent(const XmppEvent &event)
                        event.getFileSize(), event.getFileHash());
             break;
             }
+        case XmppEvent::EVENT_REGISTRATION_NEW:
+            {
+            status("##### REGISTERED: %s at %s\n",
+                       event.getTo().c_str(), event.getFrom().c_str());
+            break;
+            }
+        case XmppEvent::EVENT_REGISTRATION_CHANGE_PASS:
+            {
+            status("##### PASSWORD CHANGED: %s at %s\n",
+                       event.getTo().c_str(), event.getFrom().c_str());
+            break;
+            }
+        case XmppEvent::EVENT_REGISTRATION_CANCEL:
+            {
+            //client.disconnect();
+            status("##### REGISTERATION CANCELLED: %s at %s\n",
+                       event.getTo().c_str(), event.getFrom().c_str());
+            break;
+            }
         default:
             {
             printf("unknown event type: %d\n", typ);
@@ -1953,6 +2435,8 @@ void PedroGui::connectCallback()
         }
 }
 
+
+
 void PedroGui::chatCallback()
 {
     ChatDialog dialog(*this);
@@ -1964,6 +2448,8 @@ void PedroGui::chatCallback()
         }
 }
 
+
+
 void PedroGui::groupChatCallback()
 {
     GroupChatDialog dialog(*this);
@@ -1981,18 +2467,27 @@ void PedroGui::groupChatCallback()
         }
     groupChatCreate(groupJid, dialog.getNick());
     client.groupChatJoin(groupJid, dialog.getNick(), dialog.getPass() );
+    config.setMucGroup(dialog.getGroup());
+    config.setMucHost(dialog.getHost());
+    config.setMucNick(dialog.getNick());
+    config.setMucPassword(dialog.getPass());
+    configSave();
 }
 
+
 void PedroGui::disconnectCallback()
 {
     client.disconnect();
 }
 
+
 void PedroGui::quitCallback()
 {
     Gtk::Main::quit();
 }
 
+
 void PedroGui::fontCallback()
 {
     Gtk::FontSelectionDialog dlg;
@@ -2016,11 +2511,38 @@ void PedroGui::colorCallback()
         }
 }
 
+void PedroGui::regPassCallback()
+{
+    PasswordDialog dlg(*this);
+    int ret = dlg.run();
+    if (ret == Gtk::RESPONSE_OK)
+        {
+        DOMString newpass = dlg.getNewPass();
+        client.inBandRegistrationChangePassword(newpass);
+        }
+}
+
+
+void PedroGui::regCancelCallback()
+{
+    Gtk::MessageDialog dlg(*this, "Do you want to cancel your registration on the server?",
+        false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true);
+    int ret = dlg.run();
+    if (ret == Gtk::RESPONSE_YES)
+        {
+        client.inBandRegistrationCancel();
+        }
+}
+
+
+
 void PedroGui::sendFileCallback()
 {
     doSendFile("");
 }
 
+
+
 void PedroGui::aboutCallback()
 {
     Gtk::AboutDialog dlg;
@@ -2034,17 +2556,31 @@ void PedroGui::aboutCallback()
     dlg.run();
 }
 
+
+
 void PedroGui::actionEnable(const DOMString &name, bool val)
 {
-    DOMString path = "/ui/MenuBar/MenuFile/";
+    DOMString path = "/ui/MenuBar/";
     path.append(name);
     Glib::RefPtr<Gtk::Action> action = uiManager->get_action(path);
+    if (!action)
+        {
+        path = "/ui/MenuBar/MenuFile/";
+        path.append(name);
+        action = uiManager->get_action(path);
+        }
     if (!action)
         {
         path = "/ui/MenuBar/MenuEdit/";
         path.append(name);
         action = uiManager->get_action(path);
         }
+    if (!action)
+        {
+        path = "/ui/MenuBar/MenuRegister/";
+        path.append(name);
+        action = uiManager->get_action(path);
+        }
     if (!action)
         {
         path = "/ui/MenuBar/MenuTransfer/";
@@ -2063,9 +2599,29 @@ void PedroGui::actionEnable(const DOMString &name, bool val)
 }
 
 
+bool PedroGui::configLoad()
+{
+    if (!config.readFile("pedro.ini"))
+        return false;
+    return true;
+}
+
+
+bool PedroGui::configSave()
+{
+    if (!config.writeFile("pedro.ini"))
+        return false;
+    return true;
+}
+
+
+
+
 bool PedroGui::doSetup()
 {
-    set_title("Inkscape XMPP (Inkboard)");
+    configLoad();
+
+    set_title("Pedro XMPP Client");
     set_size_request(500, 300);
     add(mainBox);
 
@@ -2102,6 +2658,15 @@ bool PedroGui::doSetup()
                                   Gtk::Stock::SELECT_COLOR, "Select Color"),
     sigc::mem_fun(*this, &PedroGui::colorCallback) );
 
+    //### REGISTER MENU
+    actionGroup->add( Gtk::Action::create("MenuRegister", "_Registration") );
+    actionGroup->add( Gtk::Action::create("RegPass",
+                                  Gtk::Stock::DIALOG_AUTHENTICATION, "Change Password"),
+    sigc::mem_fun(*this, &PedroGui::regPassCallback) );
+    actionGroup->add( Gtk::Action::create("RegCancel",
+                                  Gtk::Stock::CANCEL, "Cancel Registration"),
+    sigc::mem_fun(*this, &PedroGui::regCancelCallback) );
+
     //### TRANSFER MENU
     actionGroup->add( Gtk::Action::create("MenuTransfer", "_Transfer") );
     actionGroup->add( Gtk::Action::create("SendFile",
@@ -2135,6 +2700,10 @@ bool PedroGui::doSetup()
         "      <menuitem action='SelectFont'/>"
         "      <menuitem action='SelectColor'/>"
         "    </menu>"
+        "    <menu action='MenuRegister'>"
+        "      <menuitem action='RegPass'/>"
+        "      <menuitem action='RegCancel'/>"
+        "    </menu>"
         "    <menu action='MenuTransfer'>"
         "      <menuitem action='SendFile'/>"
         "    </menu>"
@@ -2146,12 +2715,19 @@ bool PedroGui::doSetup()
 
     uiManager->add_ui_from_string(ui_info);
     Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
-    mainBox.pack_start(*pMenuBar, Gtk::PACK_SHRINK);
+    menuBarBox.pack_start(*pMenuBar, Gtk::PACK_SHRINK);
+
+    padlockDisable();
+    menuBarBox.pack_end(padlockIcon, Gtk::PACK_SHRINK);
+
+    mainBox.pack_start(menuBarBox, Gtk::PACK_SHRINK);
 
     actionEnable("Connect",    true);
     actionEnable("Chat",       false);
     actionEnable("GroupChat",  false);
     actionEnable("Disconnect", false);
+    actionEnable("RegPass",    false);
+    actionEnable("RegCancel",  false);
 
     mainBox.pack_start(vPaned);
     vPaned.add1(roster);