From 6bc774df705642f90a0e382d7ea4526bad558cef Mon Sep 17 00:00:00 2001 From: konrad Date: Fri, 28 Aug 2009 16:56:13 +0000 Subject: [PATCH] *separated login from settings window *store host data in profile *remove autoupdate remnants *some more minor fixes... git-svn-id: https://silmor.de/svn/softmagic/smoke/trunk@340 6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33 --- src/autoupdate.cpp | 19 -- src/autoupdate.h | 18 -- src/configdialog.cpp | 434 ++++++++++++++++++++++++++++++++++++++++++++ src/configdialog.h | 63 +++++++ src/keygen.cpp | 7 +- src/keygen.h | 2 +- src/login.cpp | 134 ++++++++++++++ src/login.h | 40 ++++ src/main.cpp | 40 +---- src/mainwindow.cpp | 358 ------------------------------------ src/mainwindow.h | 61 ------ src/msinterface.cpp | 21 ++- src/msinterface.h | 2 +- src/overview.cpp | 1 - src/smoke.pro | 8 +- src/wbase/WInterface.cpp | 10 +- src/wbase/WInterface.h | 4 + src/wbase/WTransaction.cpp | 1 + src/widgets/listview.cpp | 21 ++ src/widgets/listview.h | 28 +++ src/widgets/treeview.cpp | 21 ++ src/widgets/treeview.h | 28 +++ src/widgets/widgets.pri | 8 +- 23 files changed, 821 insertions(+), 508 deletions(-) delete mode 100644 src/autoupdate.cpp delete mode 100644 src/autoupdate.h create mode 100644 src/configdialog.cpp create mode 100644 src/configdialog.h create mode 100644 src/login.cpp create mode 100644 src/login.h delete mode 100644 src/mainwindow.cpp delete mode 100644 src/mainwindow.h create mode 100644 src/widgets/listview.cpp create mode 100644 src/widgets/listview.h create mode 100644 src/widgets/treeview.cpp create mode 100644 src/widgets/treeview.h diff --git a/src/autoupdate.cpp b/src/autoupdate.cpp deleted file mode 100644 index 7ab768d..0000000 --- a/src/autoupdate.cpp +++ /dev/null @@ -1,19 +0,0 @@ -// -// C++ Implementation: autoupdate -// -// Description: -// -// -// Author: Konrad Rosenbaum , (C) 2009 -// -// Copyright: See COPYING file that comes with this distribution -// -// - -#include "autoupdate.h" - -void initAutoUpdate() -{ - //... -} - diff --git a/src/autoupdate.h b/src/autoupdate.h deleted file mode 100644 index 6816529..0000000 --- a/src/autoupdate.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// C++ Interface: autoupdate -// -// Description: -// -// -// Author: Konrad Rosenbaum , (C) 2009 -// -// Copyright: See COPYING file that comes with this distribution -// -// - -#ifndef MAGICSMOKE_AUTOUPDATE_H -#define MAGICSMOKE_AUTOUPDATE_H - -void initAutoUpdate(); - -#endif diff --git a/src/configdialog.cpp b/src/configdialog.cpp new file mode 100644 index 0000000..1ee01d3 --- /dev/null +++ b/src/configdialog.cpp @@ -0,0 +1,434 @@ +// +// C++ Implementation: mainwindow +// +// Description: +// +// +// Author: Konrad Rosenbaum , (C) 2007 +// +// Copyright: See README/COPYING files that come with this distribution +// +// + +#include "keygen.h" +#include "main.h" +#include "configdialog.h" +#include "office.h" +#include "listview.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MConfigDialog::MConfigDialog() +{ + setWindowTitle(tr("Magic Smoke Configuration")); + + oldrow=-1; + //main layout + QHBoxLayout*hl; + QVBoxLayout*vl; + setLayout(hl=new QHBoxLayout); + //create Menu Bar + QMenuBar*mb; + hl->setMenuBar(mb=new QMenuBar); + QMenu*m=mb->addMenu(tr("&Profile")); + m->addAction(tr("&New Profile..."),this,SLOT(newProfile())); + m->addAction(tr("&Delete Profile"),this,SLOT(deleteProfile())); + m->addAction(tr("&Rename Profile"),this,SLOT(renameProfile())); + m->addAction(tr("C&lone Profile"),this,SLOT(cloneProfile())); + m->addAction(tr("&Make Default Profile"),this,SLOT(defaultProfile())); + m->addSeparator(); + m->addAction(tr("&Export Host Key..."),this,SLOT(exportKey())); + m->addAction(tr("&Import Host Key..."),this,SLOT(importKey())); + m->addAction(tr("&Generate Host Key..."),this,SLOT(generateKey())); + m->addSeparator(); + m->addAction(tr("&Close Window"),this,SLOT(close())); + m=mb->addMenu(tr("&Settings")); + m->addAction(tr("&Language..."),this,SLOT(changeLang())); + m->addAction(tr("&OpenOffice.org Settings..."),this,SLOT(openOfficeCfg())); + m->addAction(tr("Set &Default Label Font..."),this,SLOT(setDefaultFont())); + mb->addMenu(MApplication::helpMenu()); + + //create central widget + QGridLayout*gl; + hl->addWidget(profiles=new MListView); + profilemodel=new QStandardItemModel(this); + profiles->setModel(profilemodel); + profiles->setEditTriggers(QListView::NoEditTriggers); + connect(profiles,SIGNAL(clicked(const QModelIndex&)),this,SLOT(loadProfile())); + connect(profiles,SIGNAL(activated(const QModelIndex&)),this,SLOT(loadProfile())); + hl->addLayout(gl=new QGridLayout,10); + QLabel*lab; + int lctr=0; + gl->addWidget(lab=new QLabel(tr("Hostname:")),++lctr,0); + lab->setAlignment(Qt::AlignRight); + gl->addWidget(hostname=new QLineEdit,lctr,1); + gl->addWidget(lab=new QLabel(tr("Hostkey:")),++lctr,0); + lab->setAlignment(Qt::AlignRight); + gl->addWidget(hostkey=new QLineEdit,lctr,1); + gl->addWidget(lab=new QLabel(tr("Server URL:")),++lctr,0); + lab->setAlignment(Qt::AlignRight); + gl->addLayout(hl=new QHBoxLayout,lctr,1); + hl->addWidget(new QLabel("https://"),0); + hl->addWidget(serverurl=new QLineEdit,1); + gl->addWidget(useproxy=new QCheckBox(tr("Proxy:")),++lctr,0); + gl->addLayout(hl=new QHBoxLayout,lctr,1); + hl->addWidget(proxyname=new QLineEdit,1); + hl->addWidget(new QLabel(":"),0); + hl->addWidget(proxyport=new QSpinBox,0); + proxyport->setRange(1,65535); + connect(useproxy,SIGNAL(toggled(bool)),proxyname,SLOT(setEnabled(bool))); + connect(useproxy,SIGNAL(toggled(bool)),proxyport,SLOT(setEnabled(bool))); + gl->addWidget(lab=new QLabel(tr("Proxy Username:")),++lctr,0); + lab->setAlignment(Qt::AlignRight); + gl->addWidget(proxyuser=new QLineEdit,lctr,1); + gl->addWidget(lab=new QLabel(tr("Proxy Password:")),++lctr,0); + lab->setAlignment(Qt::AlignRight); + gl->addWidget(proxypass=new QLineEdit,lctr,1); + proxypass->setEchoMode(QLineEdit::Password); + connect(useproxy,SIGNAL(toggled(bool)),proxyuser,SLOT(setEnabled(bool))); + connect(useproxy,SIGNAL(toggled(bool)),proxypass,SLOT(setEnabled(bool))); + gl->addWidget(lab=new QLabel(tr("Default Username:")),++lctr,0); + lab->setAlignment(Qt::AlignRight); + gl->addWidget(username=new QLineEdit,lctr,1); + gl->setRowStretch(++lctr,10); + gl->addLayout(hl=new QHBoxLayout,++lctr,0,1,2); + + initProfiles(); + loadProfile(); +} + +MConfigDialog::~MConfigDialog() +{ + saveProfile(); +} + +void MConfigDialog::initProfiles(QString selIdx) +{ + oldrow=-1; + QSettings set; + int defpro=set.value("defaultprofile",0).toInt(); + set.beginGroup("profiles"); + QStringList prf=set.childGroups(); + profilemodel->clear(); + if(profilemodel->columnCount()<1) + profilemodel->insertColumn(0); + profilemodel->insertRows(0,prf.size()); + int newrow=0; + for(int i=0;iindex(i,0); + profilemodel->setData(idx,set.value(prf[i]+"/name").toString()); + profilemodel->setData(idx,prf[i],Qt::UserRole); + if(i==defpro){ + QFont f=profiles->font(); + f.setBold(true); + profilemodel->setData(idx,f,Qt::FontRole); + } + if(prf[i]==selIdx)newrow=i; + } + profiles->setCurrentIndex(profilemodel->index(newrow,0)); +} + +void MConfigDialog::loadProfile() +{ + //save old + saveProfile(); + //get new + QModelIndex idx=profiles->currentIndex(); + if(!idx.isValid())return; + oldrow=idx.row(); + QString key=profilemodel->data(idx,Qt::UserRole).toString(); + QSettings set; + set.beginGroup("profiles/"+key); + hostname->setText(set.value("hostname").toString()); + hostkey->setText(set.value("hostkey").toString()); + serverurl->setText(set.value("serverurl","my.host.com/path/machine.php").toString()); + useproxy->setChecked(set.value("useproxy",false).toBool()); + proxyname->setText(set.value("proxyname","proxy").toString()); + proxyport->setValue(set.value("proxyport",74).toInt()); + proxyuser->setText(set.value("proxyuser").toString()); + proxypass->setText(set.value("proxypass").toString()); + proxyname->setEnabled(useproxy->isChecked()); + proxyport->setEnabled(useproxy->isChecked()); + proxyuser->setEnabled(useproxy->isChecked()); + proxypass->setEnabled(useproxy->isChecked()); + username->setText(set.value("username").toString()); +} + +void MConfigDialog::saveProfile() +{ + if(oldrow<0 || oldrow>=profilemodel->rowCount())return; + QString key=profilemodel->data(profilemodel->index(oldrow,0),Qt::UserRole).toString(); + QSettings set; + set.beginGroup("profiles/"+key); + set.setValue("hostname",hostname->text()); + set.setValue("hostkey",hostkey->text()); + set.setValue("serverurl",serverurl->text()); + set.setValue("useproxy",useproxy->isChecked()); + set.setValue("proxyname",proxyname->text()); + set.setValue("proxyport",proxyport->value()); + set.setValue("proxyuser",proxyuser->text()); + set.setValue("proxypass",proxypass->text()); + set.setValue("username",username->text()); +} + +void MConfigDialog::newProfile() +{ + saveProfile(); + //scan for existing ones... + QSettings set; + set.beginGroup("profiles"); + QStringList prf=set.childGroups(); + QStringList prn; + for(int i=0;icurrentIndex(); + if(!idx.isValid())return; + QString key=profilemodel->data(idx,Qt::UserRole).toString(); + QSettings set; + set.beginGroup("profiles"); + set.remove(key); + set.sync(); + oldrow=-1; + initProfiles(); + loadProfile(); +} + +void MConfigDialog::renameProfile() +{ + //get old name + QModelIndex idx=profiles->currentIndex(); + if(!idx.isValid())return; + QString key=profilemodel->data(idx,Qt::UserRole).toString(); + QString pname=profilemodel->data(idx).toString(); + //query + bool ok; + QString npname=QInputDialog::getText(this,tr("Rename Profile"),tr("Please enter a profile name. It must be non-empty and must not be used yet:"),QLineEdit::Normal,pname,&ok); + if(!ok)return; + //check + if(npname==pname)return; + for(int i=0;irowCount();i++){ + QString pn=profilemodel->data(profilemodel->index(i,0)).toString(); + if(pn==npname){ + QMessageBox::warning(this,tr("Warning"),tr("This profile name is already in use.")); + return; + } + } + //set + QSettings().setValue("profiles/"+key+"/name",npname); + profilemodel->setData(idx,npname); +} + +void MConfigDialog::cloneProfile() +{ + saveProfile(); + //get current + QModelIndex idx=profiles->currentIndex(); + if(!idx.isValid())return; + QString key=profilemodel->data(idx,Qt::UserRole).toString(); + //scan for existing ones... + QSettings set; + set.beginGroup("profiles"); + QStringList prf=set.childGroups(); + QStringList prn; + for(int i=0;icurrentIndex(); + if(!idx.isValid())return; + QString key=profilemodel->data(idx,Qt::UserRole).toString(); + QSettings().setValue("defaultprofile",key); + initProfiles(key); + loadProfile(); +} + + +void MConfigDialog::changeLang() +{ + choseLanguage(); +} + +void MConfigDialog::exportKey() +{ + QSettings st; + QModelIndex idx=profiles->currentIndex(); + if(!idx.isValid())return; + QString pkey=profilemodel->data(idx,Qt::UserRole).toString(); + st.beginGroup("profiles/"+pkey); + QString host=st.value("hostname").toString().trimmed(); + QString key=st.value("hostkey").toString().trimmed(); + saveKey(host,key); +} + +void MConfigDialog::generateKey() +{ + QString name; + MKeyGen mkg(this); + QString k=mkg.getKey(); + if(k=="") + if(mkg.exec()!=QDialog::Accepted) + return; + hostkey->setText(mkg.getKey()); +} + +void MConfigDialog::saveKey(QString host,QString key) +{ + QStringList fn; + QFileDialog fdlg(this,tr("Export Key to File"),QString(),"Magic Smoke Host Key (*.mshk)"); + fdlg.setDefaultSuffix("mshk"); + fdlg.setAcceptMode(QFileDialog::AcceptSave); + fdlg.setFileMode(QFileDialog::AnyFile); + if(!fdlg.exec())return; + fn=fdlg.selectedFiles(); + if(fn.size()!=1)return; + QFile fd(fn[0]); + if(!fd.open(QIODevice::WriteOnly|QIODevice::Truncate)){ + QMessageBox::warning(this,tr("Warning"),tr("Unable to open file %1 for writing: %2").arg(fn[0]).arg(fd.errorString())); + return; + } + QString chk=QCryptographicHash::hash(key.toAscii(),QCryptographicHash::Md5).toHex(); + QString out="MagicSmokeHostKey\n"+host+"\n"+key+"\n"+chk; + fd.write(out.toAscii()); + fd.close(); +} + +void MConfigDialog::importKey() +{ + QModelIndex idx=profiles->currentIndex(); + if(!idx.isValid())return; + QString profkey=profilemodel->data(idx,Qt::UserRole).toString(); + + if(QMessageBox::warning(this,tr("Warning"),tr("Importing a key overwrites the host key that is currently used by this profile. This may disable your accounts. Do you still want to continue?"),QMessageBox::Yes|QMessageBox::Abort,QMessageBox::Abort)!=QMessageBox::Yes) + return; + QStringList fn; + QFileDialog fdlg(this,tr("Import Key from File"),QString(),"Magic Smoke Host Key (*.mshk)"); + fdlg.setDefaultSuffix("mshk"); + fdlg.setAcceptMode(QFileDialog::AcceptOpen); + fdlg.setFileMode(QFileDialog::ExistingFile); + if(!fdlg.exec())return; + fn=fdlg.selectedFiles(); + if(fn.size()!=1)return; + QFile fd(fn[0]); + if(!fd.open(QIODevice::ReadOnly)){ + QMessageBox::warning(this,tr("Warning"),tr("Unable to open file %1 for reading: %2").arg(fn[0]).arg(fd.errorString())); + return; + } + //read content (max: 10k to limit potential damage) + QStringList fc=QString::fromAscii(fd.read(10240)).split("\n",QString::SkipEmptyParts); + fd.close(); + //check content + if(fc.size()<3){ + QMessageBox::warning(this,tr("Warning"),tr("This is not a host key file.")); + return; + } + if(fc[0].trimmed()!="MagicSmokeHostKey"){ + QMessageBox::warning(this,tr("Warning"),tr("This is not a host key file.")); + return; + } + QString hname=fc[1].trimmed(); + if(!QRegExp("[A-Za-z][A-Za-z0-9_]*").exactMatch(hname)){ + QMessageBox::warning(this,tr("Warning"),tr("This host key file does not contain a valid host name.")); + return; + } + QString key=fc[2].trimmed(); + if(!QRegExp("[0-9a-fA-F]+").exactMatch(key) || key.size()<40){ + QMessageBox::warning(this,tr("Warning"),tr("This host key file does not contain a valid key.")); + return; + } + QString chk=QCryptographicHash::hash(key.toAscii(),QCryptographicHash::Md5).toHex(); + if(chk!=fc[3].trimmed()){ + QMessageBox::warning(this,tr("Warning"),tr("The key check sum did not match. Please get a clean copy of the host key file.")); + return; + } + //save + QSettings set; + set.beginGroup("profiles/"+profkey); + set.setValue("hostkey",key); + set.setValue("hostname",hname); +} + +void MConfigDialog::openOfficeCfg() +{ + MOfficeConfig c(this); + c.exec(); +} + +void MConfigDialog::setDefaultFont() +{ + QStringList fonts=QFontDatabase().families(); + QString df=QInputDialog::getItem(this,tr("Chose Default Font"),tr("Please chose a default font:"),fonts,fonts.indexOf(QSettings().value("defaultfont","").toString()),false); + if(df.isEmpty())return; + QSettings().setValue("defaultfont",df); +} diff --git a/src/configdialog.h b/src/configdialog.h new file mode 100644 index 0000000..4d78ff5 --- /dev/null +++ b/src/configdialog.h @@ -0,0 +1,63 @@ +// +// C++ Interface: mainwindow +// +// Description: +// +// +// Author: Konrad Rosenbaum , (C) 2007 +// +// Copyright: See README/COPYING files that come with this distribution +// +// + +#ifndef MAGICSMOKE_CONFIGDIALOG_H +#define MAGICSMOKE_CONFIGDIALOG_H + +#include + +class QCheckBox; +class QLineEdit; +class QListView; +class QSpinBox; +class QStandardItemModel; + +/**login and profile configuration window*/ +class MConfigDialog:public QDialog +{ + Q_OBJECT + public: + MConfigDialog(); + ~MConfigDialog(); + + private: + QCheckBox*useproxy; + QLineEdit*hostname,*hostkey,*serverurl,*proxyname,*username,*proxyuser,*proxypass; + QSpinBox*proxyport; + QListView*profiles; + QStandardItemModel*profilemodel; + + int oldrow; + + //helper for exportKey and generateKey + void saveKey(QString hostname,QString hostkey); + + private slots: + //handling of login/profile screen + void initProfiles(QString idx=QString()); + void loadProfile(); + void saveProfile(); + void newProfile(); + void deleteProfile(); + void renameProfile(); + void cloneProfile(); + void defaultProfile(); + //settings + void changeLang(); + void exportKey(); + void importKey(); + void generateKey(); + void openOfficeCfg(); + void setDefaultFont(); +}; + +#endif diff --git a/src/keygen.cpp b/src/keygen.cpp index 27448e7..5158db0 100644 --- a/src/keygen.cpp +++ b/src/keygen.cpp @@ -37,7 +37,8 @@ static QPointerefilter; -MKeyGen::MKeyGen() +MKeyGen::MKeyGen(QWidget*parentw) + :QDialog(parentw) { setWindowTitle(tr("Magic Smoke Key Generator")); @@ -55,7 +56,7 @@ MKeyGen::MKeyGen() lab->setMouseTracking(true); //buffer display int e=efilter->entropy(); - vl->addWidget(randlab=new QLabel(tr("Current random buffer: %n Bits","",e).arg(e)),0); + vl->addWidget(randlab=new QLabel(tr("Current random buffer: %n Bits","",e)),0); randlab->setMouseTracking(true); randlab->setFrameShape(QFrame::Box); randlab->setAutoFillBackground(true); @@ -85,7 +86,7 @@ MKeyGen::~MKeyGen() void MKeyGen::updateProps() { int e=efilter->entropy(); - randlab->setText(tr("Current random buffer: %n Bits","",e).arg(e)); + randlab->setText(tr("Current random buffer: %n Bits","",e)); if(efilter->entropy(), (C) 2007 +// +// Copyright: See README/COPYING files that come with this distribution +// +// + +#include "main.h" +#include "login.h" +#include "msinterface.h" +#include "overview.h" +#include "configdialog.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MLogin::MLogin() +{ + setWindowTitle(tr("Magic Smoke Login")); + QVBoxLayout*vl; + setLayout(vl=new QVBoxLayout); + //create Menu Bar + QMenuBar*mb; + vl->setMenuBar(mb=new QMenuBar); + QMenu*m=mb->addMenu(tr("&File")); + m->addAction(tr("&Exit"),this,SLOT(close())); + m=mb->addMenu(tr("&Configure")); + m->addAction(tr("&Configuration..."),this,SLOT(configwin())); + mb->addMenu(MApplication::helpMenu()); + + //create central widget + QGridLayout*gl; + vl->addLayout(gl=new QGridLayout,10); + QLabel*lab; + int lctr=0; + gl->addWidget(lab=new QLabel(tr("Profile:")),lctr,0); + lab->setAlignment(Qt::AlignRight); + gl->addWidget(profiles=new QComboBox,lctr,1); + connect(profiles,SIGNAL(currentIndexChanged(int)),this,SLOT(loadProfile())); + gl->addWidget(lab=new QLabel(tr("Username:")),++lctr,0); + lab->setAlignment(Qt::AlignRight); + gl->addWidget(username=new QLineEdit,lctr,1); + gl->addWidget(lab=new QLabel(tr("Password:")),++lctr,0); + lab->setAlignment(Qt::AlignRight); + gl->addWidget(password=new QLineEdit,lctr,1); + password->setEchoMode(QLineEdit::Password); + connect(password,SIGNAL(returnPressed()),this,SLOT(startLogin())); + connect(username,SIGNAL(returnPressed()),password,SLOT(setFocus())); + gl->setRowStretch(++lctr,10); + QHBoxLayout *hl=new QHBoxLayout; + gl->addLayout(hl,++lctr,0,1,2); + QPushButton*p; + hl->addStretch(10); + hl->addWidget(p=new QPushButton(tr("Login")),0); + connect(p,SIGNAL(clicked()),this,SLOT(startLogin())); + initProfiles(); + loadProfile(); +} + +void MLogin::initProfiles() +{ + QSettings set; + set.beginGroup("profiles"); + QStringList prf=set.childGroups(); + profiles->clear(); + for(int i=0;iaddItem(set.value(prf[i]+"/name").toString(),prf[i]); + } +} + +void MLogin::loadProfile() +{ + QString key=profiles->itemData(profiles->currentIndex()).toString(); + QSettings set; + set.beginGroup("profiles/"+key); + username->setText(set.value("username").toString()); + password->setText(""); + password->setFocus(); +} + +void MLogin::startLogin() +{ + //make it impossible for the user to interfere + setEnabled(false); + //create request object + MSInterface *mw=new MSInterface(profiles->itemData(profiles->currentIndex()).toString()); + //check server version + if(!mw->checkServer()){ + //no need for messagebox: checkServer displays one if necessary + mw->deleteLater(); + return; + } + //start login request + if(!mw->login(username->text(),password->text())){ + QMessageBox::warning(this,tr("Warning"),tr("Unable to log in.")); + mw->deleteLater(); + setEnabled(true); + return; + } + //initialize + mw->initialize(); + //open window + MOverview *mo=new MOverview(profiles->itemData(profiles->currentIndex()).toString()); + mo->show(); + + //make sure the application exits (only) after everything is cleaned up + qApp->setQuitOnLastWindowClosed(false); + connect(mw,SIGNAL(destroyed(QObject*)),qApp,SLOT(quit())); + + hide(); +} + +void MLogin::configwin() +{ + MConfigDialog cd; + cd.exec(); + initProfiles(); + loadProfile(); +} diff --git a/src/login.h b/src/login.h new file mode 100644 index 0000000..53c328e --- /dev/null +++ b/src/login.h @@ -0,0 +1,40 @@ +// +// C++ Interface: mainwindow +// +// Description: +// +// +// Author: Konrad Rosenbaum , (C) 2007/8/9 +// +// Copyright: See README/COPYING files that come with this distribution +// +// + +#ifndef MAGICSMOKE_LOGIN_H +#define MAGICSMOKE_LOGIN_H + +#include + +class QComboBox; +class QLineEdit; + +/**login and profile configuration window*/ +class MLogin:public QDialog +{ + Q_OBJECT + public: + MLogin(); + + private: + QString sessionid; + QLineEdit*username,*password; + QComboBox*profiles; + + private slots: + void initProfiles(); + void loadProfile(); + void startLogin(); + void configwin(); +}; + +#endif diff --git a/src/main.cpp b/src/main.cpp index 76fee03..b96876f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -22,12 +22,12 @@ #include #include -#include "autoupdate.h" +#include "configdialog.h" #include "debug.h" #include "hmac.h" #include "keygen.h" #include "main.h" -#include "mainwindow.h" +#include "login.h" #include "msinterface.h" QString choseLanguage(bool warn) @@ -150,44 +150,14 @@ int main(int argc,char**argv) //initialize log file initDebug(); - //check/generate host settings - if(!QSettings().contains("hostkey")){ - MKeyGen mkg; - if(mkg.exec()==QDialog::Accepted) - QSettings().setValue("hostkey",mkg.getKey()); - else{ - QMessageBox::critical(0,app.translate("initkey","Warning"), app.translate("initkey","Magic Smoke needs a host key. You have to generate one before you can use the program.")); - return 1; - } - } - if(!QSettings().contains("hostname")){ - bool ok; - QString hn=QInputDialog::getText(0,app.translate("initkey","Enter Host Name"), - app.translate("initkey","Host name:"),QLineEdit::Normal,QHostInfo::localHostName(), - &ok); - if(ok && !hn.isEmpty()) - QSettings().setValue("hostname",hn); - else{ - QMessageBox::critical(0,app.translate("initkey","Warning"), app.translate("initkey","Magic Smoke needs a host name. You have to configure one before you can use the program.")); - return 1; - } - } //check/generate profile - QString iprof; if(!QSettings().childGroups().contains("profiles")){ - iprof="0"; - bool ok; - QString ipname=app.translate("initprofile","default","initial profile"); - ipname=QInputDialog::getText(0,app.translate("initprofile","Create Initial Profile"), app.translate("initprofile","You need a profile to work with Magic Smoke. Magic Smoke will now create one for you. Please enter the name you wish to give this profile."), QLineEdit::Normal, ipname, &ok); - if(!ok || ipname.isEmpty())return 1; - QSettings().setValue("profiles/0/name",ipname); + QMessageBox::warning(0,app.translate("initprofile","Initial Profile Warning"), app.translate("initprofile","You need a profile to work with Magic Smoke. Please create one now.")); + MConfigDialog().exec(); } - //initialize auto update - initAutoUpdate(); - //open main window - MMainWindow mmw; + MLogin mmw; mmw.show(); return app.exec(); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp deleted file mode 100644 index 5284430..0000000 --- a/src/mainwindow.cpp +++ /dev/null @@ -1,358 +0,0 @@ -// -// C++ Implementation: mainwindow -// -// Description: -// -// -// Author: Konrad Rosenbaum , (C) 2007 -// -// Copyright: See README/COPYING files that come with this distribution -// -// - -#include "keygen.h" -#include "main.h" -#include "mainwindow.h" -#include "msinterface.h" -#include "office.h" -#include "overview.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -MMainWindow::MMainWindow() -{ - setWindowTitle("Magic Smoke"); - //create Menu Bar - QMenuBar*mb=menuBar(); - QMenu*m=mb->addMenu(tr("&File")); - m->addAction(tr("&New Profile..."),this,SLOT(newProfile())); - m->addAction(tr("&Save Profile"),this,SLOT(saveProfile())); - m->addSeparator(); - m->addAction(tr("&Close Window"),this,SLOT(close())); - m=mb->addMenu(tr("&Configure")); - m->addAction(tr("&Language..."),this,SLOT(changeLang())); - m->addSeparator(); - m->addAction(tr("&Export Host Key..."),this,SLOT(exportKey())); - m->addAction(tr("&Import Host Key..."),this,SLOT(importKey())); - m->addAction(tr("&Generate Host Key..."),this,SLOT(generateKey())); - m->addSeparator(); - m->addAction(tr("&OpenOffice.org Settings..."),this,SLOT(openOfficeCfg())); - m->addAction(tr("Set &Default Label Font..."),this,SLOT(setDefaultFont())); - mb->addMenu(MApplication::helpMenu()); - - //create central widget - QWidget *loginwidget; - setCentralWidget(loginwidget=new QWidget); - QGridLayout*gl; - loginwidget->setLayout(gl=new QGridLayout); - QLabel*lab; - int lctr=0; - gl->addWidget(lab=new QLabel(tr("Profile:")),lctr,0); - lab->setAlignment(Qt::AlignRight); - gl->addWidget(profiles=new QComboBox,lctr,1); - connect(profiles,SIGNAL(currentIndexChanged(int)),this,SLOT(loadProfile())); - gl->addWidget(usealterhost=new QCheckBox(tr("Alternate Hostname:")),++lctr,0); - gl->addWidget(alterhostname=new QLineEdit,lctr,1); - connect(usealterhost,SIGNAL(toggled(bool)),alterhostname,SLOT(setEnabled(bool))); - gl->addWidget(lab=new QLabel(tr("Server URL:")),++lctr,0); - lab->setAlignment(Qt::AlignRight); - gl->addWidget(serverurl=new QLineEdit,lctr,1); - gl->addWidget(useproxy=new QCheckBox(tr("Proxy:")),++lctr,0); - QHBoxLayout*hl; - gl->addLayout(hl=new QHBoxLayout,lctr,1); - hl->addWidget(proxyname=new QLineEdit,1); - hl->addWidget(new QLabel(":"),0); - hl->addWidget(proxyport=new QSpinBox,0); - proxyport->setRange(1,65535); - connect(useproxy,SIGNAL(toggled(bool)),proxyname,SLOT(setEnabled(bool))); - connect(useproxy,SIGNAL(toggled(bool)),proxyport,SLOT(setEnabled(bool))); - gl->addWidget(lab=new QLabel(tr("Proxy Username:")),++lctr,0); - lab->setAlignment(Qt::AlignRight); - gl->addWidget(proxyuser=new QLineEdit,lctr,1); - gl->addWidget(lab=new QLabel(tr("Proxy Password:")),++lctr,0); - lab->setAlignment(Qt::AlignRight); - gl->addWidget(proxypass=new QLineEdit,lctr,1); - proxypass->setEchoMode(QLineEdit::Password); - connect(useproxy,SIGNAL(toggled(bool)),proxyuser,SLOT(setEnabled(bool))); - connect(useproxy,SIGNAL(toggled(bool)),proxypass,SLOT(setEnabled(bool))); - QFrame*frm; - gl->addWidget(frm=new QFrame,++lctr,0,1,2); - frm->setFrameShape(QFrame::HLine); - gl->addWidget(lab=new QLabel(tr("Username:")),++lctr,0); - lab->setAlignment(Qt::AlignRight); - gl->addWidget(username=new QLineEdit,lctr,1); - gl->addWidget(lab=new QLabel(tr("Password:")),++lctr,0); - lab->setAlignment(Qt::AlignRight); - gl->addWidget(password=new QLineEdit,lctr,1); - password->setEchoMode(QLineEdit::Password); - connect(password,SIGNAL(returnPressed()),this,SLOT(startLogin())); - connect(username,SIGNAL(returnPressed()),password,SLOT(setFocus())); - gl->setRowStretch(++lctr,10); - gl->addLayout(hl=new QHBoxLayout,++lctr,0,1,2); - QPushButton*p; - hl->addWidget(p=new QPushButton(tr("new Profile")),0); - connect(p,SIGNAL(clicked()),this,SLOT(newProfile())); - hl->addWidget(p=new QPushButton(tr("save Profile")),0); - connect(p,SIGNAL(clicked()),this,SLOT(saveProfile())); - hl->addStretch(10); - hl->addWidget(p=new QPushButton(tr("Login")),0); - connect(p,SIGNAL(clicked()),this,SLOT(saveProfile())); - connect(p,SIGNAL(clicked()),this,SLOT(startLogin())); - initProfiles(); - loadProfile(); -} - -void MMainWindow::initProfiles() -{ - QSettings set; - set.beginGroup("profiles"); - QStringList prf=set.childGroups(); - profiles->clear(); - for(int i=0;iaddItem(set.value(prf[i]+"/name").toString(),prf[i]); - } -} - -void MMainWindow::loadProfile() -{ - QString key=profiles->itemData(profiles->currentIndex()).toString(); - QSettings set; - set.beginGroup("profiles/"+key); - usealterhost->setChecked(set.value("usealternatehost",false).toBool()); - alterhostname->setText(set.value("alternatehostname").toString()); - alterhostname->setEnabled(usealterhost->isChecked()); - serverurl->setText(set.value("serverurl","http://my.host.com/path/machine.php").toString()); - useproxy->setChecked(set.value("useproxy",false).toBool()); - proxyname->setText(set.value("proxyname","proxy").toString()); - proxyport->setValue(set.value("proxyport",74).toInt()); - proxyuser->setText(set.value("proxyuser").toString()); - proxypass->setText(set.value("proxypass").toString()); - proxyname->setEnabled(useproxy->isChecked()); - proxyport->setEnabled(useproxy->isChecked()); - proxyuser->setEnabled(useproxy->isChecked()); - proxypass->setEnabled(useproxy->isChecked()); - username->setText(set.value("username").toString()); - password->setText(""); - password->setFocus(); -} - -void MMainWindow::saveProfile() -{ - QString key=profiles->itemData(profiles->currentIndex()).toString(); - QSettings set; - set.beginGroup("profiles/"+key); - set.setValue("usealternatehost",usealterhost->isChecked()); - set.setValue("alternatehostname",alterhostname->text()); - set.setValue("serverurl",serverurl->text()); - set.setValue("useproxy",useproxy->isChecked()); - set.setValue("proxyname",proxyname->text()); - set.setValue("proxyport",proxyport->value()); - set.setValue("proxyuser",proxyuser->text()); - set.setValue("proxypass",proxypass->text()); - set.setValue("username",username->text()); -} - -void MMainWindow::newProfile() -{ - //scan for existing ones... - QSettings set; - set.beginGroup("profiles"); - QStringList prf=set.childGroups(); - QStringList prn; - for(int i=0;iaddItem(pname,pidx); - profiles->setCurrentIndex(profiles->count()-1); -} - -void MMainWindow::startLogin() -{ - //make it impossible for the user to interfere - setEnabled(false); - //create request object - MSInterface *mw=new MSInterface(profiles->itemData(profiles->currentIndex()).toString()); - mw->setUrl(serverurl->text()); - if(useproxy->isChecked()) - mw->setProxy(proxyname->text(),proxyport->value(),proxyuser->text(),proxypass->text()); - //check server version - if(!mw->checkServer())return; - //start login request - QString hn; - if(usealterhost->isChecked())hn=alterhostname->text(); - else hn=QSettings().value("hostname").toString(); - QString hk=QSettings().value("hostkey").toString(); - if(!mw->login(username->text(),password->text(),hn,hk)){ - QMessageBox::warning(this,tr("Warning"),tr("Unable to log in.")); - mw->deleteLater(); - setEnabled(true); - return; - } - //initialize - mw->initialize(); - //open window - MOverview *mo=new MOverview(profiles->itemData(profiles->currentIndex()).toString()); - mo->show(); - - //make sure the application exits (only) after everything is cleaned up - qApp->setQuitOnLastWindowClosed(false); - connect(mw,SIGNAL(destroyed(QObject*)),qApp,SLOT(quit())); - - //reset main window -// password->setText(""); -// setEnabled(true); -// deleteLater(); - hide(); -} - -void MMainWindow::changeLang() -{ - choseLanguage(); -} - -void MMainWindow::exportKey() -{ - QSettings st; - QString host=st.value("hostname").toString().trimmed(); - QString key=st.value("hostkey").toString().trimmed(); - saveKey(host,key); -} - -void MMainWindow::generateKey() -{ - QString name; - do{ - bool ok; - name=QInputDialog::getText(this,tr("New Host Name"),tr("Please enter a name for the new host:"),QLineEdit::Normal,name,&ok); - if(!ok)return; - if(!QRegExp("[A-Za-z][A-Za-z0-9_]*").exactMatch(name)){ - QMessageBox::warning(this,tr("Warning"),tr("The host name must only consist of letters, digits and underscore. It must start with a letter.")); - continue; - } - }while(false); - MKeyGen mkg; - if(mkg.exec()==QDialog::Accepted) - saveKey(name,mkg.getKey()); -} - -void MMainWindow::saveKey(QString host,QString key) -{ - QStringList fn; - QFileDialog fdlg(this,tr("Export Key to File"),QString(),"Magic Smoke Host Key (*.mshk)"); - fdlg.setDefaultSuffix("mshk"); - fdlg.setAcceptMode(QFileDialog::AcceptSave); - fdlg.setFileMode(QFileDialog::AnyFile); - if(!fdlg.exec())return; - fn=fdlg.selectedFiles(); - if(fn.size()!=1)return; - QFile fd(fn[0]); - if(!fd.open(QIODevice::WriteOnly|QIODevice::Truncate)){ - QMessageBox::warning(this,tr("Warning"),tr("Unable to open file %1 for writing: %2").arg(fn[0]).arg(fd.errorString())); - return; - } - QString chk=QCryptographicHash::hash(key.toAscii(),QCryptographicHash::Md5).toHex(); - QString out="MagicSmokeHostKey\n"+host+"\n"+key+"\n"+chk; - fd.write(out.toAscii()); - fd.close(); -} - -void MMainWindow::importKey() -{ - if(QMessageBox::warning(this,tr("Warning"),tr("Importing a key overwrites the host key that is currently used by this program. This may disable your accounts. Do you still want to continue?"),QMessageBox::Yes|QMessageBox::Abort,QMessageBox::Abort)!=QMessageBox::Yes) - return; - QStringList fn; - QFileDialog fdlg(this,tr("Import Key from File"),QString(),"Magic Smoke Host Key (*.mshk)"); - fdlg.setDefaultSuffix("mshk"); - fdlg.setAcceptMode(QFileDialog::AcceptOpen); - fdlg.setFileMode(QFileDialog::ExistingFile); - if(!fdlg.exec())return; - fn=fdlg.selectedFiles(); - if(fn.size()!=1)return; - QFile fd(fn[0]); - if(!fd.open(QIODevice::ReadOnly)){ - QMessageBox::warning(this,tr("Warning"),tr("Unable to open file %1 for reading: %2").arg(fn[0]).arg(fd.errorString())); - return; - } - //read content (max: 10k to limit potential damage) - QStringList fc=QString::fromAscii(fd.read(10240)).split("\n",QString::SkipEmptyParts); - fd.close(); - //check content - if(fc.size()<3){ - QMessageBox::warning(this,tr("Warning"),tr("This is not a host key file.")); - return; - } - if(fc[0].trimmed()!="MagicSmokeHostKey"){ - QMessageBox::warning(this,tr("Warning"),tr("This is not a host key file.")); - return; - } - QString hname=fc[1].trimmed(); - if(!QRegExp("[A-Za-z][A-Za-z0-9_]*").exactMatch(hname)){ - QMessageBox::warning(this,tr("Warning"),tr("This host key file does not contain a valid host name.")); - return; - } - QString key=fc[2].trimmed(); - if(!QRegExp("[0-9a-fA-F]+").exactMatch(key) || key.size()<40){ - QMessageBox::warning(this,tr("Warning"),tr("This host key file does not contain a valid key.")); - return; - } - QString chk=QCryptographicHash::hash(key.toAscii(),QCryptographicHash::Md5).toHex(); - if(chk!=fc[3].trimmed()){ - QMessageBox::warning(this,tr("Warning"),tr("The key check sum did not match. Please get a clean copy of the host key file.")); - return; - } - //save - QSettings().setValue("hostkey",key); - QSettings().setValue("hostname",hname); -} - -void MMainWindow::openOfficeCfg() -{ - MOfficeConfig c(this); - c.exec(); -} - -void MMainWindow::setDefaultFont() -{ - QStringList fonts=QFontDatabase().families(); - QString df=QInputDialog::getItem(this,tr("Chose Default Font"),tr("Please chose a default font:"),fonts,fonts.indexOf(QSettings().value("defaultfont","").toString()),false); - if(df.isEmpty())return; - QSettings().setValue("defaultfont",df); -} diff --git a/src/mainwindow.h b/src/mainwindow.h deleted file mode 100644 index f2b8d31..0000000 --- a/src/mainwindow.h +++ /dev/null @@ -1,61 +0,0 @@ -// -// C++ Interface: mainwindow -// -// Description: -// -// -// Author: Konrad Rosenbaum , (C) 2007 -// -// Copyright: See README/COPYING files that come with this distribution -// -// - -#ifndef MAGICSMOKE_MAINWINDOW_H -#define MAGICSMOKE_MAINWINDOW_H - -#include -#include -#include - -class QHttp; -class QStackedWidget; -class QComboBox; -class QLineEdit; -class QCheckBox; -class QSpinBox; - -/**login and profile configuration window*/ -class MMainWindow:public QMainWindow -{ - Q_OBJECT - public: - MMainWindow(); - - private: - QHttp*req; - QString sessionid; - QCheckBox*usealterhost,*useproxy; - QLineEdit*alterhostname,*serverurl,*proxyname,*username,*password,*proxyuser,*proxypass; - QSpinBox*proxyport; - QComboBox*profiles; - - //helper for exportKey and generateKey - void saveKey(QString hostname,QString hostkey); - - private slots: - //handling of login/profile screen - void initProfiles(); - void loadProfile(); - void saveProfile(); - void newProfile(); - void startLogin(); - //settings - void changeLang(); - void exportKey(); - void importKey(); - void generateKey(); - void openOfficeCfg(); - void setDefaultFont(); -}; - -#endif diff --git a/src/msinterface.cpp b/src/msinterface.cpp index 936e5a1..4c31080 100644 --- a/src/msinterface.cpp +++ b/src/msinterface.cpp @@ -22,6 +22,19 @@ MSInterface::MSInterface(QString pid) :MInterface() { profileid=pid; + QSettings set; + set.beginGroup("profiles/"+pid); + setUrl("https://"+set.value("serverurl","my.host.com/path/machine.php").toString()); + bool useproxy=set.value("useproxy",false).toBool(); + if(useproxy) + setProxy( + set.value("proxyname","proxy").toString(), + set.value("proxyport",74).toInt(), + set.value("proxyuser").toString(), + set.value("proxypass").toString() + ); + m_host=set.value("hostname").toString(); + m_hostkey=set.value("hostkey").toString(); } MSInterface::~MSInterface() @@ -29,10 +42,10 @@ MSInterface::~MSInterface() logout(); } -bool MSInterface::login(QString username,QString passwd,QString hostname,QString hostkey) +bool MSInterface::login(QString username,QString passwd) { - m_uname=username;m_passwd=passwd;m_host=hostname;m_hostkey=hostkey; - MTLogin lg=MTLogin::query(username,passwd,hostname,hostkey); + m_uname=username;m_passwd=passwd; + MTLogin lg=MTLogin::query(username,passwd,m_host,m_hostkey); if(lg.stage()==lg.Error) QMessageBox::warning(0,tr("Warning"),tr("Login failed: %1").arg(tr(lg.errorString().toAscii()))); else @@ -90,7 +103,7 @@ void MSInterface::logout() bool MSInterface::relogin() { logout(); - return login(m_uname,m_passwd,m_host,m_hostkey); + return login(m_uname,m_passwd); } QMap MSInterface::headers(QString s)const diff --git a/src/msinterface.h b/src/msinterface.h index 88029ec..61ddefc 100644 --- a/src/msinterface.h +++ b/src/msinterface.h @@ -59,7 +59,7 @@ class MSInterface:public MInterface public slots: /**logs into the server, returns true on success*/ - bool login(QString username,QString passwd,QString hostname,QString hostkey); + bool login(QString username,QString passwd); /**logs out of the server*/ void logout(); /**refreshes the login*/ diff --git a/src/overview.cpp b/src/overview.cpp index 9c78545..d83be45 100644 --- a/src/overview.cpp +++ b/src/overview.cpp @@ -15,7 +15,6 @@ #include "eventedit.h" #include "eventsummary.h" #include "main.h" -#include "mainwindow.h" #include "misc.h" #include "moneylog.h" #include "msinterface.h" diff --git a/src/smoke.pro b/src/smoke.pro index c070454..c6e936e 100644 --- a/src/smoke.pro +++ b/src/smoke.pro @@ -25,7 +25,8 @@ SOURCES = \ debug.cpp \ misc.cpp \ keygen.cpp \ - mainwindow.cpp \ + login.cpp \ + configdialog.cpp \ hmac.cpp \ code39.cpp \ overview.cpp \ @@ -45,7 +46,6 @@ SOURCES = \ templatedlg.cpp \ office.cpp \ moneylog.cpp \ - autoupdate.cpp \ domquery.cpp \ msinterface.cpp @@ -53,7 +53,8 @@ HEADERS = \ main.h \ keygen.h \ debug.h \ - mainwindow.h \ + login.h \ + configdialog.h \ hmac.h \ overview.h \ eventedit.h \ @@ -73,7 +74,6 @@ HEADERS = \ templatedlg.h \ office.h \ moneylog.h \ - autoupdate.h \ domquery.h \ msinterface.h diff --git a/src/wbase/WInterface.cpp b/src/wbase/WInterface.cpp index 1248317..f410437 100644 --- a/src/wbase/WInterface.cpp +++ b/src/wbase/WInterface.cpp @@ -12,12 +12,13 @@ #include "WInterface.h" +#include #include #include QMap WInterface::inst; -static QMutex mtx; +static QMutex mtx(QMutex::Recursive); WInterface*WInterface::instance(QString name) { @@ -54,3 +55,10 @@ QMap WInterface::headers(QString)const { return QMap(); } + +void WInterface::sslErrors(const QList&errs) +{ + QHttp*src=qobject_cast(sender()); + if(!src)return; + src->ignoreSslErrors(); +} diff --git a/src/wbase/WInterface.h b/src/wbase/WInterface.h index 8cae7d6..2f51c3a 100644 --- a/src/wbase/WInterface.h +++ b/src/wbase/WInterface.h @@ -16,6 +16,7 @@ #include #include #include +#include class WInterface:public QObject { @@ -81,6 +82,9 @@ class WInterface:public QObject /**sets the URL of the interface*/ void setUrl(QUrl u){m_url=u;} + /**handles SSL errors*/ + void sslErrors(const QList&); + private: static QMapinst; QUrl m_url; diff --git a/src/wbase/WTransaction.cpp b/src/wbase/WTransaction.cpp index 9d040f7..22d5fc6 100644 --- a/src/wbase/WTransaction.cpp +++ b/src/wbase/WTransaction.cpp @@ -78,6 +78,7 @@ QByteArray WTransaction::executeQuery(QString hreq,QByteArray data) m_errstr=tr("interface not found"); return QByteArray(); } + connect(&req,SIGNAL(sslErrors(const QList&)),iface,SLOT(sslErrors(const QList&))); QUrl url=iface->url(); int port=url.port(); if(port<=0){ diff --git a/src/widgets/listview.cpp b/src/widgets/listview.cpp new file mode 100644 index 0000000..6c64415 --- /dev/null +++ b/src/widgets/listview.cpp @@ -0,0 +1,21 @@ +// +// C++ Implementation: treeview +// +// Description: +// +// +// Author: Konrad Rosenbaum , (C) 2009 +// +// Copyright: See README/COPYING files that come with this distribution +// +// + +#include "listview.h" + +void MListView::keyPressEvent(QKeyEvent *event) +{ + QModelIndex idx=currentIndex(); + QListView::keyPressEvent(event); + if(idx!=currentIndex()) + emit activated(currentIndex()); +} \ No newline at end of file diff --git a/src/widgets/listview.h b/src/widgets/listview.h new file mode 100644 index 0000000..fcd3dd5 --- /dev/null +++ b/src/widgets/listview.h @@ -0,0 +1,28 @@ +// +// C++ Interface: treeview +// +// Description: +// +// +// Author: Konrad Rosenbaum , (C) 2009 +// +// Copyright: See README/COPYING files that come with this distribution +// +// + +#ifndef MAGICSMOKE_LISTVIEW_H +#define MAGICSMOKE_LISTVIEW_H + +#include + +/**enhances QTreeView to react a bit friendlier on clicks*/ +class MListView:public QListView +{ + public: + MListView(QWidget*w=0):QListView(w){} + protected: + void keyPressEvent(QKeyEvent *event); + +}; + +#endif diff --git a/src/widgets/treeview.cpp b/src/widgets/treeview.cpp new file mode 100644 index 0000000..f043e2c --- /dev/null +++ b/src/widgets/treeview.cpp @@ -0,0 +1,21 @@ +// +// C++ Implementation: treeview +// +// Description: +// +// +// Author: Konrad Rosenbaum , (C) 2009 +// +// Copyright: See README/COPYING files that come with this distribution +// +// + +#include "treeview.h" + +void MTreeView::keyPressEvent(QKeyEvent *event) +{ + QModelIndex idx=currentIndex(); + QTreeView::keyPressEvent(event); + if(idx!=currentIndex()) + emit activated(currentIndex()); +} \ No newline at end of file diff --git a/src/widgets/treeview.h b/src/widgets/treeview.h new file mode 100644 index 0000000..3258b18 --- /dev/null +++ b/src/widgets/treeview.h @@ -0,0 +1,28 @@ +// +// C++ Interface: treeview +// +// Description: +// +// +// Author: Konrad Rosenbaum , (C) 2009 +// +// Copyright: See README/COPYING files that come with this distribution +// +// + +#ifndef MAGICSMOKE_TREEVIEW_H +#define MAGICSMOKE_TREEVIEW_H + +#include + +/**enhances QTreeView to react a bit friendlier on clicks*/ +class MTreeView:public QTreeView +{ + public: + MTreeView(QWidget*w=0):QTreeView(w){} + protected: + void keyPressEvent(QKeyEvent *event); + +}; + +#endif diff --git a/src/widgets/widgets.pri b/src/widgets/widgets.pri index 5409f0f..4ff2b0f 100644 --- a/src/widgets/widgets.pri +++ b/src/widgets/widgets.pri @@ -1,11 +1,15 @@ HEADERS += \ widgets/waitcursor.h \ widgets/centbox.h \ - widgets/checkdlg.h + widgets/checkdlg.h \ + widgets/listview.h \ + widgets/treeview.h SOURCES += \ widgets/waitcursor.cpp \ widgets/centbox.cpp \ - widgets/checkdlg.cpp + widgets/checkdlg.cpp \ + widgets/listview.cpp \ + widgets/treeview.cpp INCLUDEPATH += ./widgets \ No newline at end of file -- 1.7.2.5