Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

qnet.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2002 by Yann Hodique                                    *
00003  *   Yann.Hodique@lifl.fr                                                  *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  ***************************************************************************/
00010 
00011 #include <qtextbrowser.h>
00012 #include <qlineedit.h>
00013 #include <qtabwidget.h>
00014 #include <qcombobox.h>
00015 #include <qmessagebox.h>
00016 #include <qfile.h>
00017 #include <qtextstream.h>
00018 #include <qdom.h>
00019 #include <qdir.h>
00020 #include <qlistbox.h>
00021 #include <qwidgetstack.h>
00022 #include <qregexp.h>
00023 #include <qprocess.h>
00024 #include <qradiobutton.h>
00025 #include <qstatusbar.h>
00026 
00027 #include <dlfcn.h>
00028 
00029 #include "qnet.h"
00030 #include "connectionbox.h"
00031 #include "ChatSession.h"
00032 #include "version.h"
00033 #include "domutil.h"
00034 #include "SessionsDialog.h"
00035 #include "mtpsettings.h"
00036 #include "mtpfilterssettings.h"
00037 #include "UrlSettings.h"
00038 #include "PrefixSettings.h"
00039 #include "fortunesettings.h"
00040 #include "appearancesettings.h"
00041 #include "remotecontrol.h"
00042 #include "page.h"
00043 
00044 QMtp::QMtp(QWidget *parent, const char *name)
00045         : QMtp_base(parent, name), m_document() {
00046 
00047     // kick out this useless status bar
00048     delete statusBar();
00049 
00050     connect(tabs,SIGNAL(currentChanged(QWidget*)),
00051             this, SLOT(slotCurrentPageChanged(QWidget*)));
00052 
00053     if (!loadConfigFile()) {
00054   QString default_content("<qnet/>");
00055   m_document.setContent(default_content);
00056     }
00057     tabs->setTabPosition((QTabWidget::TabPosition)DomUtil::readIntEntry(m_document,"/appearance/tabs/position",QTabWidget::Top));
00058     fortune_page = 0;
00059     fproc = 0;
00060     if (DomUtil::readBoolEntry(m_document,"/remote/enabled",false))
00061   rctl = new RemoteControlServerInfo(this,DomUtil::readIntEntry(m_document,"/remote/port",5000),system_view);
00062 
00063     // plugins
00064     QStringList plugs = DomUtil::readListEntry(m_document,"/general/plugins","file");
00065     for(QStringList::Iterator it = plugs.begin(); it != plugs.end(); ++it)
00066   loadPlugin(*it);
00067     
00068     // autoconnect
00069     QStringList list = DomUtil::readListEntry(m_document,"/general/sessions","session");
00070     for (QStringList::Iterator it = list.begin(); it != list.end(); ++it)
00071         if(DomUtil::readBoolEntry(m_document,"/sessions/" + *it + "/autoconnect",false))
00072             launchSession(*it);
00073 }
00074 
00075 
00076 QMtp::~QMtp() {
00077     saveConfigFile();
00078     
00079     // unload plugins :
00080     for (QMap<QString,void*>::Iterator it = plugins_map.begin(); it != plugins_map.end(); ++it)
00081   dlclose(*it);
00082 }
00083 
00084 void QMtp::slotConfigure() {
00085     MtpSettings settings(this);
00086     QDomDocument temporary_dom;
00087     
00088     temporary_dom.setContent(m_document.toString());
00089 
00090     // Select the right widget
00091     connect(settings.prop_list, SIGNAL(highlighted(int)),
00092             settings.stack, SLOT(raiseWidget(int)));
00093 
00094     // Filters :
00095     {
00096         MtpFiltersSettings * filters_settings = new MtpFiltersSettings(settings.stack);
00097         settings.stack->addWidget(filters_settings,0);
00098         settings.prop_list->insertItem("Filters",0);
00099         //filters_settings->setEnabled(false);
00100   filters_settings->setDom(&temporary_dom);
00101     }
00102 
00103     // Urls :
00104     UrlSettings * url_settings = new UrlSettings(settings.stack);
00105     settings.stack->addWidget(url_settings,1);
00106     settings.prop_list->insertItem("Url",1);
00107     {
00108         QStringList list = DomUtil::readListEntry(m_document,"/urls/available","type");
00109         for (QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
00110             QString name = *it;
00111             QString motif = DomUtil::readEntry(m_document,"/urls/" + name + "/motif","");
00112             QString command = DomUtil::readEntry(m_document,"/urls/" + name + "/command","");
00113             UrlSettings::UrlItem mng(name,motif,command);
00114             url_settings->addUrlItem(mng);
00115         }
00116     }
00117 
00118     // Prefixes :
00119     PrefixSettings * prefix_settings = new PrefixSettings(settings.stack);
00120     settings.stack->addWidget(prefix_settings,2);
00121     settings.prop_list->insertItem("Prefixes",2);
00122     {
00123         QStringList list = DomUtil::readListEntry(m_document,"/prefixes","item");
00124         for (QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
00125             PrefixSettings::PrefixItem mng(*it);
00126             prefix_settings->addPrefixItem(mng);
00127         }
00128     }
00129 
00130     // Fortune :
00131     FortuneSettings * fortune_settings = new FortuneSettings(settings.stack);
00132     settings.stack->addWidget(fortune_settings,3);
00133     settings.prop_list->insertItem("Fortune",3);
00134     {
00135         QString args = DomUtil::readEntry(m_document,"/fortune");
00136         fortune_settings->fortune_edit->setText(args);
00137     }
00138 
00139     // Appearance :
00140     AppearanceSettings * appearance_settings = new AppearanceSettings(settings.stack);
00141     settings.stack->addWidget(appearance_settings,4);
00142     settings.prop_list->insertItem("Appearance",4);
00143     {
00144         int position = DomUtil::readIntEntry(m_document,"/appearance/tabs/position",QTabWidget::Top);
00145         appearance_settings->rbTop->setChecked(position==QTabWidget::Top);
00146         appearance_settings->rbBottom->setChecked(!appearance_settings->rbTop->isChecked());
00147     }
00148 
00149     if (settings.exec() == QDialog::Accepted) {
00150   
00151   m_document.setContent(temporary_dom.toString());
00152   
00153   for(QValueList<ChatSession*>::Iterator it = sessions.begin(); it != sessions.end(); ++it) {
00154       (*it)->updateFilters();
00155   }
00156 
00157         // Urls
00158         {
00159             QStringList l;
00160             for (uint i=0; i< url_settings->urls_box->count(); i++)
00161                 l << url_settings->urls_box->text(i);
00162             DomUtil::writeListEntry(m_document,"/urls/available","type",l);
00163 
00164             for (uint i=0; i< url_settings->urls_box->count(); i++) {
00165                 UrlSettings::UrlItem it = *(url_settings->map.find(url_settings->urls_box->text(i)));
00166                 DomUtil::writeEntry(m_document,"/urls/" + it.name + "/motif",it.prefix);
00167                 DomUtil::writeEntry(m_document,"/urls/" + it.name + "/command",it.command);
00168             }
00169         }
00170 
00171         // Prefixes
00172         {
00173             QStringList l;
00174             for (uint i=0; i< prefix_settings->prefix_box->count(); i++)
00175                 l << prefix_settings->prefix_box->text(i);
00176             DomUtil::writeListEntry(m_document,"/prefixes","item",l);
00177         }
00178 
00179         // Fortune :
00180         {
00181             DomUtil::writeEntry(m_document,"/fortune",fortune_settings->fortune_edit->text());
00182         }
00183 
00184         // Appearance :
00185         {
00186             int position = appearance_settings->rbTop->isChecked()?QTabWidget::Top : QTabWidget::Bottom;
00187             DomUtil::writeIntEntry(m_document,"appearance/tabs/position",position);
00188             tabs->setTabPosition((QTabWidget::TabPosition)position);
00189         } 
00190   saveConfigFile();
00191     }
00192 }
00193 
00194 void QMtp::fileNew() {
00195     ConnectionBox box;
00196     QStringList list = DomUtil::readListEntry(m_document,"/general/sessions","session");
00197     for (QStringList::Iterator it = list.begin(); it != list.end(); ++it)
00198         box.session_box->insertItem(*it);
00199     box.session_box->setFocus();
00200 
00201     if(box.exec() && (box.session_box->currentText() != "")) {
00202         launchSession(box.session_box->currentText());
00203     }
00204 }
00205 
00206 Page * QMtp::getNewPage(const QString& type,const QString& name,ChatSession * ref) {
00207     QMap<QString,void*>::Iterator it;
00208     if((it = plugins_map.find(type)) != plugins_map.end()) {
00209   create_t* create_plugin = (create_t*) dlsym(*it, "create");
00210   Page* page = create_plugin(tabs,name,ref);
00211   if (page->isSlave()) {
00212       tabs->addTab(page,name);
00213             tabs->showPage(page);
00214   }
00215   tab_map.insert(page,ref);
00216   connect(page, SIGNAL(textDisplayed(QWidget *)),
00217     this, SLOT(slotTextDisplayed(QWidget *)));
00218   return page;
00219     }
00220     system_view->append("No type \"" + type + "\" available\n");
00221     return 0;
00222 }
00223 
00224 void QMtp::fileSessions() {
00225     SessionsDialog dlg;
00226 
00227     QStringList list = DomUtil::readListEntry(m_document,"/general/sessions","session");
00228     for (QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
00229         QString name = *it;
00230         QString host = DomUtil::readEntry(m_document,"/sessions/" + name + "/host","");
00231         QString port = DomUtil::readEntry(m_document,"/sessions/" + name + "/port","");
00232         QString login = DomUtil::readEntry(m_document,"/sessions/" + name + "/login","");
00233         QString password = DomUtil::readEntry(m_document,"/sessions/" + name + "/password","");
00234         bool autoconnect = DomUtil::readBoolEntry(m_document,"/sessions/" + name + "/autoconnect",false);
00235         SessionsDialog::SessionItem session(name,host,port,login,password,autoconnect);
00236         dlg.addSessionItem(session);
00237     }
00238 
00239     if (dlg.exec()) {
00240         QStringList l;
00241         for (uint i=0; i< dlg.sessions_box->count(); i++)
00242             l << dlg.sessions_box->text(i);
00243         DomUtil::writeListEntry(m_document,"/general/sessions","session",l);
00244 
00245   QDomElement child = DomUtil::elementByPath(m_document,"/sessions");
00246         if(!child.isNull()) child.parentNode().removeChild(child);
00247   
00248         for (uint i=0; i< dlg.sessions_box->count(); i++) {
00249             SessionsDialog::SessionItem it = *(dlg.map.find(dlg.sessions_box->text(i)));
00250             DomUtil::writeEntry(m_document,"/sessions/" + it.name + "/host",it.host);
00251             DomUtil::writeEntry(m_document,"/sessions/" + it.name + "/port",it.port);
00252             DomUtil::writeEntry(m_document,"/sessions/" + it.name + "/login",it.login);
00253             DomUtil::writeEntry(m_document,"/sessions/" + it.name + "/password",it.password);
00254             DomUtil::writeBoolEntry(m_document,"/sessions/" + it.name + "/autoconnect",it.autoconnect);
00255         }
00256     }
00257 }
00258 
00259 void QMtp::closeCurrentTab() {
00260     closeTab(tabs->currentPage());
00261 }
00262 
00263 void QMtp::closeTab(QWidget *w) {
00264     if(w == fortune_page) {
00265         delete w;
00266         fortune_page = 0;
00267         return;
00268     }
00269     if(w != tab) {
00270         tabs->removePage(w);
00271         QMap<QWidget*,ChatSession*>::Iterator it;
00272         if ((it = tab_map.find(w)) != tab_map.end()) {
00273             (*it)->kill((Page*)w);
00274         } else // session tab
00275             sessions.remove((ChatSession*)w);
00276         delete w;
00277     }
00278 }
00279 
00280 void QMtp::fileExit() {
00281     saveConfigFile();
00282     close();
00283 }
00284 
00285 void QMtp::gotoNextTab() {
00286     tabs->setCurrentPage((tabs->currentPageIndex() + 1) % tabs->count());
00287 }
00288 
00289 void QMtp::gotoPreviousTab() {
00290     tabs->setCurrentPage((tabs->currentPageIndex() + tabs->count() - 1) % tabs->count());
00291 }
00292 
00293 void QMtp::helpAbout() {
00294     QMessageBox::about(this, "About QNet", CLIENT + QString("\nŠ 2002 - Sigma <Yann.Hodique@lifl.fr>"));
00295 }
00296 
00297 bool QMtp::loadConfigFile() {
00298     QFile fin(QDir::homeDirPath() + "/.qnetrc");
00299     if (!fin.open(IO_ReadOnly)) {
00300         QMessageBox::critical(this,"Error","Could not read config file");
00301         return false;
00302     }
00303 
00304     int errorLine, errorCol;
00305     QString errorMsg;
00306     if (!m_document.setContent(&fin, &errorMsg, &errorLine, &errorCol)) {
00307         QMessageBox::critical(this,"Error",QString("This is not a valid config file.\nXML error in line %1, column %2:\n%3").arg(errorLine).arg(errorCol).arg(errorMsg));
00308         fin.close();
00309         return false;
00310     }
00311     if (m_document.documentElement().nodeName() !="qnet") {
00312         QMessageBox::critical(this,"Error","This is not a valid config file.");
00313         fin.close();
00314         return false;
00315     }
00316 
00317     fin.close();
00318 
00319     return true;
00320 }
00321 
00322 bool QMtp::saveConfigFile() {
00323     QFile fout(QDir::homeDirPath() + "/.qnetrc");
00324     if( !fout.open(IO_WriteOnly) ) {
00325         QMessageBox::critical(this,"Error","Could not write the config file.");
00326         return false;
00327     }
00328 
00329     QTextStream stream(&fout);
00330     stream << m_document.toString();
00331     fout.close();
00332 
00333     return true;
00334 }
00335 
00336 void QMtp::slotTextDisplayed(QWidget* w) {
00337     QString current_label = tabs->label(tabs->indexOf(w));
00338     if ((tabs->currentPage() == w) || current_label.endsWith("*"))
00339         return;
00340     tabs->setTabLabel(w,current_label + "*");
00341 }
00342 
00343 void QMtp::slotCurrentPageChanged(QWidget* w) {
00344     QString current_label = tabs->label(tabs->indexOf(w));
00345     if (current_label.endsWith("*"))
00346         tabs->setTabLabel(w,current_label.replace(QRegExp("\\*$"),""));
00347 }
00348 
00349 void QMtp::slotDisplayFortune() {
00350     if (fproc)
00351         return;
00352     fproc = new QProcess(this);
00353     if (!(this->fortune_page)) {
00354         fortune_page = new QTextBrowser(tabs,"Fortune");
00355         fortune_page->setTextFormat(Qt::RichText);
00356 
00357         fortune_page->setWrapPolicy(QTextBrowser::Anywhere);
00358 
00359         tabs->addTab(fortune_page,"Fortune");
00360         tabs->showPage(fortune_page);
00361     }
00362 
00363     QStringList list;
00364     QStringList list_args = QStringList::split(" ",DomUtil::readEntry(m_document,"/fortune"));
00365     list << "fortune";
00366 
00367     for (QStringList::Iterator it = list_args.begin(); it != list_args.end(); ++it)
00368         list << (*it);
00369 
00370     connect(fproc,SIGNAL(readyReadStdout()),
00371             this, SLOT(readFortune()));
00372     connect(fproc,SIGNAL(processExited()),
00373             this, SLOT(endFortune()));
00374     fproc->setArguments(list);
00375     fproc->start();
00376 }
00377 
00378 void QMtp::readFortune() {
00379     QProcess *p = (QProcess*) sender();
00380     while (p->canReadLineStdout()) {
00381         QString msg(p->readLineStdout());
00382         fortune_page->append(msg);
00383     }
00384 }
00385 
00386 void QMtp::endFortune() {
00387     fortune_page->append("<hr>");
00388     delete fproc;
00389     fproc = 0;
00390 }
00391 
00392 void QMtp::loadPlugin(const QString& file_name) {
00393     system_view->append("Loading " + file_name);
00394     
00395     void* plug = dlopen(file_name, RTLD_LAZY);
00396     if (!plug) {
00397         system_view->append(QString("Cannot load library: ") + dlerror() + "\n");
00398         return;
00399     }
00400 
00401     create_t* create_plugin = (create_t*) dlsym(plug, "create");
00402     destroy_t* destroy_plugin = (destroy_t*) dlsym(plug, "destroy");
00403     name_t* name_plugin = (name_t*) dlsym(plug, "name");
00404     if (!create_plugin || !destroy_plugin || !name_plugin) {
00405         system_view->append(QString("Cannot load symbols: ") + dlerror() + "\n");
00406   return;
00407     }
00408     
00409     plugins_map.insert(name_plugin(),plug);
00410 }
00411 
00412 void QMtp::launchSession(const QString& name) {
00413     ChatSession * session = new ChatSession(name,this,tabs,0,&m_document);
00414 
00415     sessions.push_back(session);
00416 
00417     tabs->addTab(session,name);
00418     tabs->showPage(session);
00419 
00420     connect(session, SIGNAL(textDisplayed(QWidget *)),
00421             this, SLOT(slotTextDisplayed(QWidget *)));
00422 }

Generated on Sat May 10 15:09:27 2003 for qnet by doxygen1.3