Code

add config
authorishmal <ishmal@users.sourceforge.net>
Mon, 19 Jun 2006 18:22:55 +0000 (18:22 +0000)
committerishmal <ishmal@users.sourceforge.net>
Mon, 19 Jun 2006 18:22:55 +0000 (18:22 +0000)
src/pedro/icon/Thumbs.db
src/pedro/pedro.bat
src/pedro/pedroconfig.cpp
src/pedro/pedroconfig.h
src/pedro/pedrodom.cpp
src/pedro/pedrodom.h
src/pedro/pedrogui.cpp
src/pedro/pedrogui.h
src/pedro/pedroxmpp.cpp

index 15c63291b0a5d31af8dfec023604f1fafecb6b25..b1142522c0960f9d645848e7259274d05410cf5e 100644 (file)
Binary files a/src/pedro/icon/Thumbs.db and b/src/pedro/icon/Thumbs.db differ
index 3bc8b0e5022e5bcd6ecfadeb9732569fa337b1d2..6cae5a26e6639b1e0a28fd43a39aea41e61e3e8c 100644 (file)
@@ -1,2 +1,2 @@
-set path=c:\inkscape;%path%\r
+set path=c:\gtk28\bin;%path%\r
 start pedro.exe\r
index 1197a6f1faff9dc97cdfb48793e68b65a511ccbb..f6de670cd11ccfd0b128cbf6eb023f3b3a70a516 100644 (file)
@@ -80,6 +80,16 @@ bool XmppConfig::read(const DOMString &buffer)
 
     accounts.clear();
 
+    std::vector<Element *> mucElems = root->findElements("muc");
+    if (mucElems.size() > 0)
+        {
+        Element *elem = mucElems[0];
+        mucGroup    = elem->getTagValue("group");
+        mucHost     = elem->getTagValue("host");
+        mucNick     = elem->getTagValue("nick");
+        mucPassword = elem->getTagValue("password");
+        }
+
     std::vector<Element *> accountElems = root->findElements("account");
 
     for (unsigned int i=0 ; i<accountElems .size() ; i++)
@@ -87,7 +97,7 @@ bool XmppConfig::read(const DOMString &buffer)
         XmppAccount account;
         Element *elem = accountElems [i];
 
-        DOMString str = elem ->getTagValue("name");
+        DOMString str = elem->getTagValue("name");
         if (str.size()==0)
             str = "unnamed account";
         account.setName(str);
@@ -95,7 +105,7 @@ bool XmppConfig::read(const DOMString &buffer)
         str = elem->getTagValue("host");
         if (str.size()==0)
             str = "jabber.org";
-        account.setName(str);
+        account.setHost(str);
 
         str = elem->getTagValue("port");
         int port = (int) getInt(str);
@@ -161,6 +171,20 @@ DOMString XmppConfig::toXmlBuffer()
     char fmtbuf[32];
 
     buf.append("<pedro>\n");
+    buf.append("    <muc>\n");
+    buf.append("        <group>");
+    buf.append(mucGroup);
+    buf.append("</group>\n");
+    buf.append("        <host>");
+    buf.append(mucHost);
+    buf.append("</host>\n");
+    buf.append("        <nick>");
+    buf.append(mucNick);
+    buf.append("</nick>\n");
+    buf.append("        <password>");
+    buf.append(mucPassword);
+    buf.append("</password>\n");
+    buf.append("    </muc>\n");
 
     for (unsigned int i = 0 ; i<accounts.size() ; i++)
         {
@@ -221,6 +245,153 @@ bool XmppConfig::writeFile(const DOMString &fileName)
 }
 
 
+/**
+ *
+ */
+DOMString XmppConfig::getMucGroup()
+{
+    return mucGroup;
+}
+
+/**
+ *
+ */
+void XmppConfig::setMucGroup(const DOMString &val)
+{
+    mucGroup = val;
+}
+
+/**
+ *
+ */
+DOMString XmppConfig::getMucHost()
+{
+    return mucHost;
+}
+
+/**
+ *
+ */
+void XmppConfig::setMucHost(const DOMString &val)
+{
+    mucHost = val;
+}
+
+/**
+ *
+ */
+DOMString XmppConfig::getMucNick()
+{
+    return mucNick;
+}
+
+/**
+ *
+ */
+void XmppConfig::setMucNick(const DOMString &val)
+{
+    mucNick = val;
+}
+
+/**
+ *
+ */
+DOMString XmppConfig::getMucPassword()
+{
+    return mucPassword;
+}
+
+/**
+ *
+ */
+void XmppConfig::setMucPassword(const DOMString &val)
+{
+    mucPassword = val;
+}
+
+
+
+/**
+ *
+ */
+std::vector<XmppAccount> &XmppConfig::getAccounts()
+{
+    return accounts;
+}
+
+
+/**
+ *
+ */
+bool XmppConfig::accountAdd(const XmppAccount &account)
+{
+    DOMString name = account.getName();
+    if (name.size() < 1)
+        return false;
+    if (accountExists(name))
+        return false;
+    accounts.push_back(account);
+    return true;
+}
+
+
+/**
+ *
+ */
+bool XmppConfig::accountExists(const DOMString &accountName)
+{
+    if (accountName.size() < 1)
+        return false;
+    std::vector<XmppAccount>::iterator iter;
+    for (iter = accounts.begin() ; iter!= accounts.end() ; iter++)
+        {
+        if (iter->getName() == accountName)
+            return true;
+        }
+    return false;
+}
+
+
+
+/**
+ *
+ */
+void XmppConfig::accountRemove(const DOMString &accountName)
+{
+    if (accountName.size() < 1)
+        return;
+    std::vector<XmppAccount>::iterator iter;
+    for (iter = accounts.begin() ; iter!= accounts.end() ; )
+        {
+        if (iter->getName() == accountName)
+            iter = accounts.erase(iter);
+        else
+            iter++;
+        }        
+}
+
+
+/**
+ *
+ */
+bool XmppConfig::accountFind(const DOMString &accountName,
+                             XmppAccount &retVal)
+{
+    if (accountName.size() < 1)
+        return false;
+    std::vector<XmppAccount>::iterator iter;
+    for (iter = accounts.begin() ; iter!= accounts.end() ; iter++)
+        {
+        if (iter->getName() == accountName)
+            {
+            retVal = (*iter);
+            return true;
+            }
+        }        
+    return false;
+}
+
+
 
 
 
index 61650c361f29c818969ff2dd796eeb396d8051cb..554c47ba9a416a9b44a6a0b261b0c36749241325 100644 (file)
@@ -72,7 +72,7 @@ public:
     /**
      *
      */
-    virtual DOMString getName()
+    virtual DOMString getName() const
         { return name; }
 
     /**
@@ -84,7 +84,7 @@ public:
     /**
      *
      */
-    virtual DOMString getHost()
+    virtual DOMString getHost() const
         { return host; }
 
     /**
@@ -96,7 +96,7 @@ public:
     /**
      *
      */
-    virtual int getPort()
+    virtual int getPort() const
         { return port; }
 
     /**
@@ -108,7 +108,7 @@ public:
     /**
      *
      */
-    virtual DOMString getUsername()
+    virtual DOMString getUsername() const
         { return username; }
 
     /**
@@ -120,7 +120,7 @@ public:
     /**
      *
      */
-    virtual DOMString getPassword()
+    virtual DOMString getPassword() const
         { return password; }
 
     /**
@@ -217,9 +217,68 @@ public:
     /**
      *
      */
-    virtual std::vector<XmppAccount> &getAccounts()
-        { return accounts; }
+    virtual std::vector<XmppAccount> &getAccounts();
 
+    /**
+     *
+     */
+    virtual DOMString getMucGroup();
+
+    /**
+     *
+     */
+    virtual void setMucGroup(const DOMString &val);
+
+    /**
+     *
+     */
+    virtual DOMString getMucHost();
+
+    /**
+     *
+     */
+    virtual void setMucHost(const DOMString &val);
+
+    /**
+     *
+     */
+    virtual DOMString getMucNick();
+
+    /**
+     *
+     */
+    virtual void setMucNick(const DOMString &val);
+
+    /**
+     *
+     */
+    virtual DOMString getMucPassword();
+
+    /**
+     *
+     */
+    virtual void setMucPassword(const DOMString &val);
+
+    /**
+     *
+     */
+    virtual bool accountAdd(const XmppAccount &account);
+
+    /**
+     *
+     */
+    virtual bool accountExists(const DOMString &accountName);
+
+    /**
+     *
+     */
+    virtual void accountRemove(const DOMString &accountName);
+
+    /**
+     *
+     */
+    bool accountFind(const DOMString &accountName,
+                     XmppAccount &retVal);
 
 
 private:
@@ -233,6 +292,15 @@ private:
         accounts = other.accounts;
         }
 
+    //# Group stuff
+    DOMString mucGroup;
+
+    DOMString mucHost;
+
+    DOMString mucNick;
+
+    DOMString mucPassword;
+
     std::vector<XmppAccount> accounts;
 
 };
index fa473f1a948ad5c7f7ec877b687de7bbbba741f4..de6b99cf4534bd7d0650354e39d6e6822217469f 100644 (file)
@@ -26,9 +26,6 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdarg.h>
-#if defined(HAVE_MALLOC_H)
-#include <malloc.h>
-#endif
 #include <sys/types.h>
 #include <sys/stat.h>
 
@@ -199,6 +196,35 @@ static EntityEntry entities[] =
 
 
 
+/**
+ *  Removes whitespace from beginning and end of a string
+ */
+DOMString Parser::trim(const DOMString &s)
+{
+    if (s.size() < 1)
+        return s;
+    
+    //Find first non-ws char
+    unsigned int begin = 0;
+    for ( ; begin < s.size() ; begin++)
+        {
+        if (!isspace(s[begin]))
+            break;
+        }
+
+    //Find first non-ws char, going in reverse
+    unsigned int end = s.size() - 1;
+    for ( ; end > begin ; end--)
+        {
+        if (!isspace(s[end]))
+            break;
+        }
+    //trace("begin:%d  end:%d", begin, end);
+
+    DOMString res = s.substr(begin, end-begin+1);
+    return res;
+}
+
 void Parser::getLineAndColumn(long pos, long *lineNr, long *colNr)
 {
     long line = 1;
@@ -659,44 +685,36 @@ Element *Parser::parse(XMLCh *buf,int pos,int len)
 
 Element *Parser::parse(const char *buf, int pos, int len)
 {
-
-    XMLCh *charbuf = (XMLCh *)malloc((len+1) * sizeof(XMLCh));
+    XMLCh *charbuf = new XMLCh[len + 1];
     long i = 0;
-    while (i< len)
-        {
+    for ( ; i < len ; i++)
         charbuf[i] = (XMLCh)buf[i];
-        i++;
-        }
     charbuf[i] = '\0';
-    Element *n = parse(charbuf, 0, len);
-    free(charbuf);
+
+    Element *n = parse(charbuf, pos, len);
+    delete[] charbuf;
     return n;
 }
 
 Element *Parser::parse(const DOMString &buf)
 {
-    long len = buf.size();
-    XMLCh *charbuf = (XMLCh *)malloc((len+1) * sizeof(XMLCh));
+    long len = (long)buf.size();
+    XMLCh *charbuf = new XMLCh[len + 1];
     long i = 0;
-    while (i< len)
-        {
+    for ( ; i < len ; i++)
         charbuf[i] = (XMLCh)buf[i];
-        i++;
-        }
     charbuf[i] = '\0';
+
     Element *n = parse(charbuf, 0, len);
-    free(charbuf);
+    delete[] charbuf;
     return n;
 }
 
-Element *Parser::parseFile(const char *fileName)
+Element *Parser::parseFile(const DOMString &fileName)
 {
 
     //##### LOAD INTO A CHAR BUF, THEN CONVERT TO XMLCh
-    if (!fileName)
-        return NULL;
-
-    FILE *f = fopen(fileName, "rb");
+    FILE *f = fopen(fileName.c_str(), "rb");
     if (!f)
         return NULL;
 
@@ -709,7 +727,7 @@ Element *Parser::parseFile(const char *fileName)
     long filelen = statBuf.st_size;
 
     //printf("length:%d\n",filelen);
-    XMLCh *charbuf = (XMLCh *)malloc((filelen+1) * sizeof(XMLCh));
+    XMLCh *charbuf = new XMLCh[filelen + 1];
     for (XMLCh *p=charbuf ; !feof(f) ; p++)
         {
         *p = (XMLCh)fgetc(f);
@@ -723,7 +741,7 @@ Element *Parser::parseFile(const char *fileName)
     printf("buf:%ls\n======\n",charbuf);
     */
     Element *n = parse(charbuf, 0, filelen);
-    free(charbuf);
+    delete [] charbuf;
     return n;
 }
 
index 9c6651259bdd288991ba7cf1f719f788dfd999dc..b9fb98b92faaee8fad161b80b3a118947e654214 100644 (file)
@@ -183,6 +183,9 @@ public:
 
     DOMString getAttribute(const DOMString &name);
 
+    std::vector<Attribute> &getAttributes()
+        { return attributes; } 
+
     DOMString getTagAttribute(const DOMString &tagName, const DOMString &attrName);
 
     DOMString getTagValue(const DOMString &tagName);
@@ -277,7 +280,7 @@ public:
      * @param fileName the name of the file to read
      * @return a pointer to the root of the XML document;
      */
-    Element *parseFile(const char *fileName);
+    Element *parseFile(const DOMString &fileName);
 
     /**
      * Utility method to preprocess a string for XML
@@ -286,6 +289,10 @@ public:
      */
     static DOMString encode(const DOMString &str);
 
+    /**
+     *  Removes whitespace from beginning and end of a string
+     */
+    DOMString trim(const DOMString &s);
 
 private:
 
index f785e7132591a5630e96c148026f68e594c83392..4b4bccbaa53489ffd93d5c3f6e6cdab57e04f414 100644 (file)
@@ -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,111 +1097,6 @@ void GroupChatWindow::doSendFile(const DOMString &nick)
 
 
 
-//#########################################################################
-//# C O N N E C T    D I A L O G
-//#########################################################################
-
-
-void ConnectDialog::okCallback()
-{
-    response(Gtk::RESPONSE_OK);
-    hide();
-}
-
-void ConnectDialog::cancelCallback()
-{
-    response(Gtk::RESPONSE_CANCEL);
-    hide();
-}
-
-
-bool ConnectDialog::doSetup()
-{
-    set_title("Connect");
-    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("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='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);
-
-    show_all_children();
-
-    return true;
-}
-
-
-
 
 //#########################################################################
 //# C O N F I G    D I A L O G
@@ -1540,22 +1438,23 @@ 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);
 
 
@@ -1567,8 +1466,302 @@ bool GroupChatDialog::doSetup()
     return true;
 }
 
+
+
+
 //#########################################################################
-//# F I L E    S E N D   D I A L O G
+//# 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
 //#########################################################################
 
 
@@ -1607,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();
@@ -1699,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();
@@ -1881,9 +2074,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;
@@ -2016,6 +2211,7 @@ void PedroGui::handleDisconnectEvent()
      set_title(title);
      chatDeleteAll();
      groupChatDeleteAll();
+     roster.clear();
 }
 
 
@@ -2269,6 +2465,12 @@ 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();
 }
 
 
@@ -2395,10 +2597,28 @@ 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()
 {
+    configLoad();
+
     set_title("Pedro XMPP Client");
     set_size_request(500, 300);
     add(mainBox);
@@ -2518,8 +2738,6 @@ bool PedroGui::doSetup()
     Glib::signal_timeout().connect(
            sigc::mem_fun(*this, &PedroGui::checkEventQueue), 20 );
 
-    config.readFile("pedro.ini");
-
     //client.addXmppEventListener(*this);
     client.eventQueueEnable(true);
 
index bd37d095d2d68901a9e917a773cff02d12d3e6f0..a8b8964bafe43faefb67a2b2c61c4cade42fcd94 100644 (file)
@@ -357,59 +357,6 @@ private:
  };
 
 
-//#########################################################################
-//# C O N N E C T    D I A L O G
-//#########################################################################
-class ConnectDialog : public Gtk::Dialog
-{
-public:
-
-    ConnectDialog(PedroGui &par) : parent(par)
-        { doSetup(); }
-
-    virtual ~ConnectDialog()
-        {}
-
-   DOMString getHost()
-       { return hostField.get_text(); }
-   int getPort()
-       { return (int)portSpinner.get_value(); }
-   DOMString getUser()
-       { return userField.get_text(); }
-   DOMString getPass()
-       { return passField.get_text(); }
-   DOMString getResource()
-       { return resourceField.get_text(); }
-   bool getRegister()
-       { return registerButton.get_active(); }
-
-private:
-
-    void okCallback();
-    void cancelCallback();
-
-    bool doSetup();
-
-    Gtk::Table       table;
-
-    Gtk::Label       hostLabel;
-    Gtk::Entry       hostField;
-    Gtk::Label       portLabel;
-    Gtk::SpinButton  portSpinner;
-    Gtk::Label       userLabel;
-    Gtk::Entry       userField;
-    Gtk::Label       passLabel;
-    Gtk::Entry       passField;
-    Gtk::Label       resourceLabel;
-    Gtk::Entry       resourceField;
-    Gtk::Label       registerLabel;
-    Gtk::CheckButton registerButton;
-
-    PedroGui &parent;
-};
-
-
-
 
 //#########################################################################
 //# C O N F I G    D I A L O G
@@ -585,6 +532,117 @@ private:
 };
 
 
+//#########################################################################
+//#  C O N N E C T    D I A L O G
+//#########################################################################
+class ConnectDialog : public Gtk::Dialog
+{
+public:
+
+    ConnectDialog (PedroGui &par) : parent(par)
+        { doSetup(); }
+
+    virtual ~ConnectDialog ()
+        {}
+
+   DOMString getHost()
+       { return hostField.get_text(); }
+   void setHost(const DOMString &val)
+       { hostField.set_text(val); }
+   int getPort()
+       { return (int)portSpinner.get_value(); }
+   void setPort(int val)
+       { portSpinner.set_value(val); }
+   DOMString getUser()
+       { return userField.get_text(); }
+   void setUser(const DOMString &val)
+       { userField.set_text(val); }
+   DOMString getPass()
+       { return passField.get_text(); }
+   void setPass(const DOMString &val)
+       { passField.set_text(val); }
+   DOMString getResource()
+       { return resourceField.get_text(); }
+   void setResource(const DOMString &val)
+       { resourceField.set_text(val); }
+   bool getRegister()
+       { return registerButton.get_active(); }
+
+    /**
+     * Regenerate the account list
+     */
+    virtual void refresh();
+
+private:
+
+    void okCallback();
+    void saveCallback();
+    void cancelCallback();
+    void doubleClickCallback(
+                   const Gtk::TreeModel::Path &path,
+                   Gtk::TreeViewColumn *col);
+    void selectedCallback();
+
+    bool doSetup();
+
+    Gtk::Table       table;
+
+    Gtk::Label       hostLabel;
+    Gtk::Entry       hostField;
+    Gtk::Label       portLabel;
+    Gtk::SpinButton  portSpinner;
+    Gtk::Label       userLabel;
+    Gtk::Entry       userField;
+    Gtk::Label       passLabel;
+    Gtk::Entry       passField;
+    Gtk::Label       resourceLabel;
+    Gtk::Entry       resourceField;
+    Gtk::Label       registerLabel;
+    Gtk::CheckButton registerButton;
+
+    Glib::RefPtr<Gtk::UIManager> uiManager;
+
+
+    //##  Account list
+
+    void buttonPressCallback(GdkEventButton* event);
+
+    Gtk::ScrolledWindow accountScroll;
+
+    void connectCallback();
+
+    void modifyCallback();
+
+    void deleteCallback();
+
+
+    class AccountColumns : public Gtk::TreeModel::ColumnRecord
+        {
+        public:
+            AccountColumns()
+                {
+                add(nameColumn);
+                add(hostColumn);
+                }
+
+            Gtk::TreeModelColumn<Glib::ustring> nameColumn;
+            Gtk::TreeModelColumn<Glib::ustring> hostColumn;
+        };
+
+    AccountColumns accountColumns;
+
+    Glib::RefPtr<Gtk::UIManager> accountUiManager;
+
+    Glib::RefPtr<Gtk::ListStore> accountListStore;
+    Gtk::TreeView accountView;
+
+
+    PedroGui &parent;
+};
+
+
+
+
 //#########################################################################
 //# F I L E    S E N D    D I A L O G
 //#########################################################################
@@ -803,6 +861,11 @@ public:
     //# Help menu
     void aboutCallback();
 
+    //# Configuration file
+    bool configLoad();
+    bool configSave();
+
+
 private:
 
     bool doSetup();
index 30070c4347bab10308b0395f1173b393d852b953..48a4930b4837e29342dc8c8bace51b67fe67e4b0 100644 (file)
@@ -27,6 +27,8 @@
 
 #include <sys/stat.h>
 
+#include <time.h>
+
 #include "pedroxmpp.h"
 #include "pedrodom.h"
 #include "pedroutil.h"
@@ -755,7 +757,7 @@ bool XmppClient::pause(unsigned long millis)
 static int strIndex(const DOMString &str, char *key)
 {
     unsigned int p = str.find(key);
-    if (p == DOMString::npos)
+    if (p == str.npos)
         return -1;
     return p;
 }
@@ -833,6 +835,7 @@ void XmppClient::setUsername(const DOMString &val)
 
 DOMString XmppClient::readStanza()
 {
+
     int  openCount    = 0;
     bool inTag        = false;
     bool slashSeen    = false;
@@ -842,6 +845,9 @@ DOMString XmppClient::readStanza()
     bool textSeen     = false;
     DOMString buf;
 
+
+    time_t timeout = time((time_t *)0) + 180;
+
     while (true)
         {
         int ch = sock->read();
@@ -853,6 +859,17 @@ DOMString XmppClient::readStanza()
                 //Since we are timed out, let's assume that we
                 //are between chunks of text.  Let's reset all states.
                 //printf("-----#### Timeout\n");
+                time_t currentTime = time((time_t *)0);
+                if (currentTime > timeout)
+                    {
+                    timeout = currentTime + 180;
+                    if (!write("\n"))
+                        {
+                        error("ping send error");
+                        disconnect();
+                        return "";
+                        }
+                    }
                 continue;
                 }
             else
@@ -1472,7 +1489,7 @@ bool XmppClient::receiveAndProcessLoop()
         {
         if (!keepGoing)
             {
-            printf("Abort requested\n");
+            status("Abort requested");
             break;
             }
         if (!receiveAndProcess())