diff --git a/kdeprint/cups/cupsinfos.cpp b/kdeprint/cups/cupsinfos.cpp index 7403f99dec..8b0aa5f232 100644 --- a/kdeprint/cups/cupsinfos.cpp +++ b/kdeprint/cups/cupsinfos.cpp @@ -1,144 +1,161 @@ /* * This file is part of the KDE libraries * Copyright (c) 2001 Michael Goffioul * * $Id$ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License version 2 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. **/ #include "cupsinfos.h" #include "kmfactory.h" #include "kmtimer.h" #include "messagewindow.h" #include #include #include #include #include #include #include +#include #include #include const char* cupsGetPasswordCB(const char*) { return CupsInfos::self()->getPasswordCB(); } CupsInfos* CupsInfos::unique_ = 0; CupsInfos* CupsInfos::self() { if (!unique_) { unique_ = new CupsInfos(); } return unique_; } CupsInfos::CupsInfos() : KPReloadObject(true) { count_ = 0; load(); /* host_ = cupsServer(); login_ = cupsUser(); if (login_.isEmpty()) login_ = QString::null; port_ = ippPort(); password_ = QString::null;*/ cupsSetPasswordCB(cupsGetPasswordCB); } CupsInfos::~CupsInfos() { } void CupsInfos::setHost(const QString& s) { host_ = s; cupsSetServer(s.latin1()); } void CupsInfos::setPort(int p) { port_ = p; ippSetPort(p); } void CupsInfos::setLogin(const QString& s) { login_ = s; cupsSetUser(s.latin1()); } void CupsInfos::setPassword(const QString& s) { password_ = s; } +void CupsInfos::setSavePassword( bool on ) +{ + savepwd_ = on; +} + const char* CupsInfos::getPasswordCB() { QPair pwd = KMFactory::self()->requestPassword( count_, login_, host_, port_ ); if ( pwd.first.isEmpty() && pwd.second.isEmpty() ) return NULL; setLogin( pwd.first ); setPassword( pwd.second ); return pwd.second.latin1(); } void CupsInfos::load() { KConfig *conf_ = KMFactory::self()->printConfig(); conf_->setGroup("CUPS"); host_ = conf_->readEntry("Host",QString::fromLatin1(cupsServer())); port_ = conf_->readNumEntry("Port",ippPort()); login_ = conf_->readEntry("Login",QString::fromLatin1(cupsUser())); - password_ = QString::null; + savepwd_ = conf_->readBoolEntry( "SavePassword", false ); + if ( savepwd_ ) + { + password_ = KStringHandler::obscure( conf_->readEntry( "Password", QString::null ) ); + KMFactory::self()->initPassword( login_, password_, host_, port_ ); + } + else + password_ = QString::null; if (login_.isEmpty()) login_ = QString::null; reallogin_ = cupsUser(); // synchronize with CUPS cupsSetServer(host_.latin1()); cupsSetUser(login_.latin1()); ippSetPort(port_); } void CupsInfos::save() { KConfig *conf_ = KMFactory::self()->printConfig(); conf_->setGroup("CUPS"); conf_->writeEntry("Host",host_); conf_->writeEntry("Port",port_); conf_->writeEntry("Login",login_); - // don't write password for obvious security... + conf_->writeEntry( "SavePassword", savepwd_ ); + if ( savepwd_ ) + conf_->writeEntry( "Password", KStringHandler::obscure( password_ ) ); + else + conf_->deleteEntry( "Password" ); conf_->sync(); } void CupsInfos::reload() { // do nothing, but needs to be implemented } void CupsInfos::configChanged() { // we need to reload settings load(); } diff --git a/kdeprint/cups/cupsinfos.h b/kdeprint/cups/cupsinfos.h index 9f1c1264f0..1b5bf0ecfa 100644 --- a/kdeprint/cups/cupsinfos.h +++ b/kdeprint/cups/cupsinfos.h @@ -1,83 +1,89 @@ /* * This file is part of the KDE libraries * Copyright (c) 2001 Michael Goffioul * * $Id$ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License version 2 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. **/ #ifndef CUPSINFOS_H #define CUPSINFOS_H #include #include "kpreloadobject.h" class CupsInfos : public KPReloadObject { public: static CupsInfos* self(); CupsInfos(); ~CupsInfos(); const QString& host() const; int port() const; const QString& login() const; const QString& password() const; const QString& realLogin() const; + bool savePassword() const; void setHost(const QString& s); void setPort(int p); void setLogin(const QString& s); void setPassword(const QString& s); + void setSavePassword( bool on ); const char* getPasswordCB(); void load(); void save(); protected: void reload(); void configChanged(); private: static CupsInfos *unique_; QString host_; int port_; QString login_; QString password_; QString reallogin_; + bool savepwd_; int count_; }; inline const QString& CupsInfos::host() const { return host_; } inline int CupsInfos::port() const { return port_; } inline const QString& CupsInfos::login() const { return login_; } inline const QString& CupsInfos::password() const { return password_; } inline const QString& CupsInfos::realLogin() const { return reallogin_; } +inline bool CupsInfos::savePassword() const +{ return savepwd_; } + #endif diff --git a/kdeprint/cups/kmcupsconfigwidget.cpp b/kdeprint/cups/kmcupsconfigwidget.cpp index 4f7c11380c..12e9035391 100644 --- a/kdeprint/cups/kmcupsconfigwidget.cpp +++ b/kdeprint/cups/kmcupsconfigwidget.cpp @@ -1,148 +1,161 @@ /* * This file is part of the KDE libraries * Copyright (c) 2001 Michael Goffioul * * $Id$ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License version 2 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. **/ #include "kmcupsconfigwidget.h" #include "cupsinfos.h" #include #include #include #include #include #include #include #include #include #include +#include class PortValidator : public QIntValidator { public: PortValidator(QWidget *parent, const char *name = 0); virtual QValidator::State validate(QString&, int&) const; }; PortValidator::PortValidator(QWidget *parent, const char *name) : QIntValidator(1, 9999, parent, name) { } QValidator::State PortValidator::validate(QString& txt, int&) const { bool ok(false); int p = txt.toInt(&ok); if (txt.isEmpty()) return QValidator::Intermediate; else if (ok && p >= bottom() && p <= top()) return QValidator::Acceptable; return QValidator::Invalid; } //****************************************************************************************** KMCupsConfigWidget::KMCupsConfigWidget(QWidget *parent, const char *name) : QWidget(parent,name) { // widget creation QGroupBox *m_hostbox = new QGroupBox(0, Qt::Vertical, i18n("Server Information"), this); QGroupBox *m_loginbox = new QGroupBox(0, Qt::Vertical, i18n("Account Information"), this); QLabel *m_hostlabel = new QLabel(i18n("&Host:"), m_hostbox); QLabel *m_portlabel = new QLabel(i18n("&Port:"), m_hostbox); m_host = new QLineEdit(m_hostbox); m_port = new QLineEdit(m_hostbox); m_hostlabel->setBuddy(m_host); m_portlabel->setBuddy(m_port); m_port->setValidator(new PortValidator(m_port)); m_login = new QLineEdit(m_loginbox); QLabel *m_loginlabel = new QLabel(i18n("&User:"), m_loginbox); QLabel *m_passwordlabel = new QLabel(i18n("Pass&word:"), m_loginbox); m_password = new QLineEdit(m_loginbox); m_password->setEchoMode(QLineEdit::Password); + m_savepwd = new QCheckBox( i18n( "&Store password in configuration file" ), m_loginbox ); + m_savepwd->setCursor( KCursor::handCursor() ); m_anonymous = new QCheckBox(i18n("Use &anonymous access"), m_loginbox); m_anonymous->setCursor(KCursor::handCursor()); m_loginlabel->setBuddy(m_login); m_passwordlabel->setBuddy(m_password); // layout creation QVBoxLayout *lay0 = new QVBoxLayout(this, 0, 10); lay0->addWidget(m_hostbox,1); lay0->addWidget(m_loginbox,1); QGridLayout *lay2 = new QGridLayout(m_hostbox->layout(), 2, 2, 10); lay2->setColStretch(1,1); lay2->addWidget(m_hostlabel,0,0); lay2->addWidget(m_portlabel,1,0); lay2->addWidget(m_host,0,1); lay2->addWidget(m_port,1,1); - QGridLayout *lay3 = new QGridLayout(m_loginbox->layout(), 3, 2, 10); + QGridLayout *lay3 = new QGridLayout(m_loginbox->layout(), 4, 2, 10); lay3->setColStretch(1,1); lay3->addWidget(m_loginlabel,0,0); lay3->addWidget(m_passwordlabel,1,0); lay3->addWidget(m_login,0,1); lay3->addWidget(m_password,1,1); - lay3->addMultiCellWidget(m_anonymous,2,2,0,1); + lay3->addMultiCellWidget(m_savepwd,2,2,0,1); + lay3->addMultiCellWidget(m_anonymous,3,3,0,1); // connections connect(m_anonymous,SIGNAL(toggled(bool)),m_login,SLOT(setDisabled(bool))); connect(m_anonymous,SIGNAL(toggled(bool)),m_password,SLOT(setDisabled(bool))); + connect(m_anonymous,SIGNAL(toggled(bool)),m_savepwd,SLOT(setDisabled(bool))); } void KMCupsConfigWidget::load() { CupsInfos *inf = CupsInfos::self(); m_host->setText(inf->host()); m_port->setText(QString::number(inf->port())); if (inf->login().isEmpty()) m_anonymous->setChecked(true); else { m_login->setText(inf->login()); m_password->setText(inf->password()); + m_savepwd->setChecked( inf->savePassword() ); } } void KMCupsConfigWidget::save(bool sync) { CupsInfos *inf = CupsInfos::self(); inf->setHost(m_host->text()); inf->setPort(m_port->text().toInt()); if (m_anonymous->isChecked()) { inf->setLogin(QString::null); inf->setPassword(QString::null); + inf->setSavePassword( false ); } else { inf->setLogin(m_login->text()); inf->setPassword(m_password->text()); + inf->setSavePassword( m_savepwd->isChecked() ); } if (sync) inf->save(); } void KMCupsConfigWidget::saveConfig(KConfig *conf) { conf->setGroup("CUPS"); conf->writeEntry("Host",m_host->text()); conf->writeEntry("Port",m_port->text().toInt()); conf->writeEntry("Login",(m_anonymous->isChecked() ? QString::null : m_login->text())); + conf->writeEntry( "SavePassword", ( m_anonymous->isChecked() ? false : m_savepwd->isChecked() ) ); + if ( m_savepwd->isChecked() && !m_anonymous->isChecked() ) + conf->writeEntry( "Password", ( m_anonymous->isChecked() ? QString::null : KStringHandler::obscure( m_password->text() ) ) ); + else + conf->deleteEntry( "Password" ); // synchronize CupsInfos object save(false); } diff --git a/kdeprint/cups/kmcupsconfigwidget.h b/kdeprint/cups/kmcupsconfigwidget.h index b72d7103ab..eb55cc1ba2 100644 --- a/kdeprint/cups/kmcupsconfigwidget.h +++ b/kdeprint/cups/kmcupsconfigwidget.h @@ -1,45 +1,45 @@ /* * This file is part of the KDE libraries * Copyright (c) 2001 Michael Goffioul * * $Id$ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License version 2 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. **/ #ifndef KMCUPSCONFIGWIDGET_H #define KMCUPSCONFIGWIDGET_H #include class QLineEdit; class QCheckBox; class KConfig; class KMCupsConfigWidget : public QWidget { public: KMCupsConfigWidget(QWidget *parent = 0, const char *name = 0); void load(); void save(bool sync = true); void saveConfig(KConfig*); protected: QLineEdit *m_host, *m_port, *m_login, *m_password; - QCheckBox *m_anonymous; + QCheckBox *m_anonymous, *m_savepwd; }; #endif diff --git a/kdeprint/kdeprintd.cpp b/kdeprint/kdeprintd.cpp index 3e0de72ea9..e2dc36fac2 100644 --- a/kdeprint/kdeprintd.cpp +++ b/kdeprint/kdeprintd.cpp @@ -1,310 +1,328 @@ /* * This file is part of the KDE libraries * Copyright (c) 2001 Michael Goffioul * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License version 2 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. **/ #include "kdeprintd.h" #include "kprintprocess.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern "C" { KDEDModule *create_kdeprintd(const QCString& name) { return new KDEPrintd(name); } } static void cleanFileList(const QStringList& files) { for (QStringList::ConstIterator it=files.begin(); it!=files.end(); ++it) QFile::remove(*it); } class StatusWindow : public QWidget { public: StatusWindow(int pid = -1); void setMessage(const QString&); int pid() const { return m_pid; } private: QLabel *m_label; QPushButton *m_button; int m_pid; QLabel *m_icon; }; StatusWindow::StatusWindow(int pid) : QWidget(NULL, "StatusWindow", WType_TopLevel|WStyle_DialogBorder|WStyle_StaysOnTop|WDestructiveClose), m_pid(pid) { m_label = new QLabel(this); m_label->setAlignment(AlignCenter); m_button = new KPushButton(KStdGuiItem::close(), this); m_icon = new QLabel(this); m_icon->setPixmap(DesktopIcon("fileprint")); m_icon->setAlignment(AlignCenter); KWin::setIcons(winId(), *(m_icon->pixmap()), SmallIcon("fileprint")); QGridLayout *l0 = new QGridLayout(this, 2, 3, 10, 10); l0->setRowStretch(0, 1); l0->setColStretch(1, 1); l0->addMultiCellWidget(m_label, 0, 0, 1, 2); l0->addWidget(m_button, 1, 2); l0->addMultiCellWidget(m_icon, 0, 1, 0, 0); connect(m_button, SIGNAL(clicked()), SLOT(hide())); resize(200, 50); } void StatusWindow::setMessage(const QString& msg) { //QSize oldSz = size(); m_label->setText(msg); //QSize sz = m_label->sizeHint(); //sz += QSize(layout()->margin()*2, layout()->margin()*2+layout()->spacing()+m_button->sizeHint().height()); // dialog will never be smaller //sz = sz.expandedTo(oldSz); //resize(sz); //setFixedSize(sz); //layout()->activate(); } //***************************************************************************************************** KDEPrintd::KDEPrintd(const QCString& obj) : KDEDModule(obj) { m_processpool.setAutoDelete(true); m_tempfiles.setAutoDelete(true); m_windows.setAutoDelete(false); m_requestsPending.setAutoDelete( true ); } KDEPrintd::~KDEPrintd() { cleanTempFiles(); } int KDEPrintd::print(const QString& cmd, const QStringList& files, bool remflag) { QString command(cmd); if (!checkFiles(command, files)) return (-1); KPrintProcess *proc = new KPrintProcess; connect(proc,SIGNAL(processExited(KProcess*)),SLOT(slotProcessExited(KProcess*))); // connect(proc,SIGNAL(passwordRequested(KProcess*,const QString&)),SLOT(slotPasswordRequested(KProcess*,const QString&))); *proc << command; if (remflag) m_tempfiles.insert(proc,new QStringList(files)); if (proc->print()) { m_processpool.append(proc); return (int)(proc->pid()); } else { cleanTempFile(proc); delete proc; return (-1); } } void KDEPrintd::cleanTempFiles() { QPtrDictIterator it(m_tempfiles); for (;it.current();++it) cleanFileList(*(it.current())); } void KDEPrintd::cleanTempFile(KProcess *p) { QStringList *l = m_tempfiles.find(p); if (l) cleanFileList(*l); } void KDEPrintd::slotProcessExited(KProcess *proc) { KPrintProcess *pproc = (KPrintProcess*)proc; if (m_processpool.findRef(pproc) != -1) { m_processpool.take(); QString msg; if (!pproc->normalExit()) msg = i18n("Abnormal process termination (%1).").arg(pproc->args().first()); else if (pproc->exitStatus() != 0) msg = i18n("%1: execution failed with message:

%2

").arg(pproc->args().first()).arg(pproc->errorMessage()); cleanTempFile(pproc); delete pproc; if (!msg.isEmpty()) KNotifyClient::event("printerror",i18n("

A print error occurred. Error message received from system:


%1").arg(msg)); } } QString KDEPrintd::openPassDlg(const QString& user) { QString user_(user), pass_, result; if (KIO::PasswordDialog::getNameAndPassword(user_, pass_, NULL) == KDialog::Accepted) result.append(user_).append(":").append(pass_); return result; } bool KDEPrintd::checkFiles(QString& cmd, const QStringList& files) { for (QStringList::ConstIterator it=files.begin(); it!=files.end(); ++it) if (::access(QFile::encodeName(*it).data(), R_OK) != 0) { if (KMessageBox::warningContinueCancel(0, i18n("Some of the files to print are not readable by the KDE " "print daemon. This may happen if you are trying to print " "as a different user to the one currently logged in. To continue " "printing, you need to provide root's password."), QString::null, i18n("Provide root's password"), "provideRootsPassword") == KMessageBox::Continue) { cmd = ("kdesu -c " + KProcess::quote(cmd)); break; } else return false; } return true; } void KDEPrintd::statusMessage(const QString& msg, int pid, const QString& appName) { StatusWindow *w = m_windows.find(pid); if (!w && !msg.isEmpty()) { w = new StatusWindow(pid); if (appName.isEmpty()) w->setCaption(i18n("Printing Status - %1").arg("(pid="+QString::number(pid)+")")); else w->setCaption(i18n("Printing Status - %1").arg(appName)); connect(w, SIGNAL(destroyed()), SLOT(slotClosed())); w->show(); m_windows.insert(pid, w); } if (w) { if (!msg.isEmpty()) w->setMessage(msg); else w->close(); } } void KDEPrintd::slotClosed() { const StatusWindow *w = static_cast(sender()); if (w) { m_windows.remove(w->pid()); } } //****************************************************************************************** class KDEPrintd::Request { public: DCOPClientTransaction *transaction; QString user; QString uri; int seqNbr; }; QString KDEPrintd::requestPassword( const QString& user, const QString& host, int port, int seqNbr ) { Request *req = new Request; req->user = user; req->uri = "print://" + user + "@" + host + ":" + QString::number(port); req->seqNbr = seqNbr; req->transaction = callingDcopClient()->beginTransaction(); m_requestsPending.append( req ); if ( m_requestsPending.count() == 1 ) QTimer::singleShot( 0, this, SLOT( processRequest() ) ); return "::"; } void KDEPrintd::processRequest() { if ( m_requestsPending.count() == 0 ) return; Request *req = m_requestsPending.first(); KIO::AuthInfo info; QByteArray params, reply; QCString replyType; QString authString( "::" ); info.username = req->user; info.keepPassword = true; info.url = req->uri; info.comment = i18n( "Printing system" ); QDataStream input( params, IO_WriteOnly ); input << info << i18n( "Authentification failed (user name=%1)" ).arg( info.username ) << 0 << req->seqNbr; if ( callingDcopClient()->call( "kded", "kpasswdserver", "queryAuthInfo(KIO::AuthInfo,QString,long int,long int)", params, replyType, reply ) ) { if ( replyType == "KIO::AuthInfo" ) { QDataStream output( reply, IO_ReadOnly ); KIO::AuthInfo result; int seqNbr; output >> result >> seqNbr; if ( result.isModified() ) authString = result.username + ":" + result.password + ":" + QString::number( seqNbr ); } else kdWarning( 500 ) << "DCOP returned type error, expected KIO::AuthInfo, received " << replyType << endl; } else kdWarning( 500 ) << "Cannot communicate with kded_kpasswdserver" << endl; QByteArray outputData; QDataStream output( outputData, IO_WriteOnly ); output << authString; replyType = "QString"; callingDcopClient()->endTransaction( req->transaction, replyType, outputData ); m_requestsPending.remove( ( unsigned int )0 ); if ( m_requestsPending.count() > 0 ) QTimer::singleShot( 0, this, SLOT( processRequest() ) ); } +void KDEPrintd::initPassword( const QString& user, const QString& passwd, const QString& host, int port ) +{ + QByteArray params, reply; + QCString replyType; + KIO::AuthInfo info; + + info.username = user; + info.password = passwd; + info.url = "print://" + user + "@" + host + ":" + QString::number(port); + + QDataStream input( params, IO_WriteOnly ); + input << info << ( long int )0; + + if ( !callingDcopClient()->call( "kded", "kpasswdserver", "addAuthInfo(KIO::AuthInfo,long int)", + params, replyType, reply ) ) + kdWarning( 500 ) << "Unable to initialize password, cannot communicate with kded_kpasswdserver" << endl; +} + #include "kdeprintd.moc" diff --git a/kdeprint/kdeprintd.h b/kdeprint/kdeprintd.h index 653b42f76a..8812eb71dd 100644 --- a/kdeprint/kdeprintd.h +++ b/kdeprint/kdeprintd.h @@ -1,67 +1,68 @@ /* * This file is part of the KDE libraries * Copyright (c) 2001 Michael Goffioul * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License version 2 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. **/ #ifndef KDEPRINTD_H #define KDEPRINTD_H #include #include #include #include #include #include class KPrintProcess; class KProcess; class StatusWindow; class KDEPrintd : public KDEDModule { Q_OBJECT K_DCOP public: KDEPrintd(const QCString& obj); ~KDEPrintd(); k_dcop: int print(const QString& cmd, const QStringList& files, bool remove); QString openPassDlg(const QString& user); ASYNC statusMessage(const QString& msg, int pid = -1, const QString& appName = QString::null); QString requestPassword( const QString& user, const QString& host, int port, int seqNbr ); + void initPassword( const QString& user, const QString& passwd, const QString& host, int port ); protected slots: void slotProcessExited(KProcess*); void slotClosed(); void processRequest(); protected: void cleanTempFiles(); void cleanTempFile(KProcess*); bool checkFiles(QString& cmd, const QStringList& files); private: class Request; QPtrList m_processpool; QPtrDict m_tempfiles; QIntDict m_windows; QPtrList m_requestsPending; }; #endif diff --git a/kdeprint/kmfactory.cpp b/kdeprint/kmfactory.cpp index ca93863fdb..5a5afd40bf 100644 --- a/kdeprint/kmfactory.cpp +++ b/kdeprint/kmfactory.cpp @@ -1,437 +1,450 @@ /* * This file is part of the KDE libraries * Copyright (c) 2001 Michael Goffioul * * $Id$ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License version 2 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. **/ #include "kmfactory.h" #include "kmmanager.h" #include "kmjobmanager.h" #include "kmuimanager.h" #include "kprinterimpl.h" #include "kprinter.h" #include "kpreloadobject.h" #include "kdeprintcheck.h" #include "kxmlcommand.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include +#include #include #define UNLOAD_OBJECT(x) if (x != 0) { delete x; x = 0; } extern void qt_generate_epsf( bool b ); KMFactory* KMFactory::m_self = 0; static KStaticDeleter s_kmfactorysd; KMFactory* KMFactory::self() { if (!m_self) m_self = s_kmfactorysd.setObject(m_self, new KMFactory()); return m_self; } bool KMFactory::exists() { return m_self != 0L; } void KMFactory::release() { if (m_self) { KMFactory* p = m_self; m_self = 0; // so that exists() says false delete p; } } KMFactory::KMFactory() : QObject(NULL, "Factory") { m_settings = new Settings; m_settings->application = KPrinter::Dialog; m_settings->pageSelection = KPrinter::SystemSide; m_settings->standardDialogPages = KPrinter::CopiesPage; m_settings->pageSize = -1; m_settings->orientation = -1; m_objects.setAutoDelete(false); m_manager = 0; m_jobmanager = 0; m_uimanager = 0; m_implementation = 0; m_factory = 0; m_printconfig = 0; #if QT_VERSION >= 230 // Qt's default behaviour, to generate EPS in some cases and not in others, sucks. // This is fixed in Qt 3.0, but for Qt 2.x we need to disable it explicitely. // If this is a problem for anyone, we can add a public method to set this flag. // (David Faure, doing as advised by Lars Knoll) qt_generate_epsf( false ); #endif // By default, embed PS fonts bool ok = false; QSettings settings; settings.readBoolEntry( "/qt/embedFonts", true, &ok ); if ( !ok ) settings.writeEntry( "/qt/embedFonts", true ); KGlobal::iconLoader()->addAppDir("kdeprint"); // create DCOP signal connection connectDCOPSignal(0, 0, "pluginChanged(pid_t)", "slot_pluginChanged(pid_t)", false); connectDCOPSignal(0, 0, "configChanged()", "slot_configChanged()", false); } KMFactory::~KMFactory() { delete m_settings; // The only object to be destroyed is m_printconfig. All other objects have been // created with "this" as parent, so we don't need to care about their destruction UNLOAD_OBJECT(m_printconfig); m_self = 0; } KMManager* KMFactory::manager() { if (!m_manager) createManager(); Q_CHECK_PTR(m_manager); return m_manager; } KMJobManager* KMFactory::jobManager() { if (!m_jobmanager) createJobManager(); Q_CHECK_PTR(m_jobmanager); return m_jobmanager; } KMUiManager* KMFactory::uiManager() { if (!m_uimanager) createUiManager(); Q_CHECK_PTR(m_uimanager); return m_uimanager; } KPrinterImpl* KMFactory::printerImplementation() { if (!m_implementation) createPrinterImpl(); Q_CHECK_PTR(m_implementation); return m_implementation; } KMVirtualManager* KMFactory::virtualManager() { return manager()->m_virtualmgr; } KMSpecialManager* KMFactory::specialManager() { return manager()->m_specialmgr; } KXmlCommandManager* KMFactory::commandManager() { return KXmlCommandManager::self(); } void KMFactory::createManager() { loadFactory(); if (m_factory) m_manager = (KMManager*)m_factory->create(this,"Manager","KMManager"); if (!m_manager) m_manager = new KMManager(this,"Manager"); } void KMFactory::createJobManager() { loadFactory(); if (m_factory) m_jobmanager = (KMJobManager*)m_factory->create(this,"JobManager","KMJobManager"); if (!m_jobmanager) m_jobmanager = new KMJobManager(this,"JobManager"); } void KMFactory::createUiManager() { loadFactory(); if (m_factory) m_uimanager = (KMUiManager*)m_factory->create(this,"UiManager","KMUiManager"); if (!m_uimanager) m_uimanager = new KMUiManager(this,"UiManager"); } void KMFactory::createPrinterImpl() { loadFactory(); if (m_factory) m_implementation = (KPrinterImpl*)m_factory->create(this,"PrinterImpl","KPrinterImpl"); if (!m_implementation) m_implementation = new KPrinterImpl(this,"PrinterImpl"); } void KMFactory::loadFactory(const QString& syst) { if (!m_factory) { QString sys(syst); if (sys.isEmpty()) // load default configured print plugin sys = printSystem(); QString libname = QString::fromLatin1("kdeprint_%1").arg(sys); m_factory = KLibLoader::self()->factory(QFile::encodeName(libname)); if (!m_factory) { KMessageBox::error(0, i18n("There was an error loading %1. The diagnostic is:

%2

") .arg(libname).arg(KLibLoader::self()->lastErrorMessage())); } } } KConfig* KMFactory::printConfig(const QString& group) { if (!m_printconfig) { m_printconfig = new KConfig("kdeprintrc"); Q_CHECK_PTR(m_printconfig); } if (!group.isEmpty()) m_printconfig->setGroup(group); return m_printconfig; } QString KMFactory::printSystem() { KConfig *conf = printConfig(); conf->setGroup("General"); QString sys = conf->readEntry("PrintSystem",QString::null); if (sys.isEmpty()) { // perform auto-detection (will at least return "lpdunix") sys = autoDetect(); // save the result conf->writeEntry("PrintSystem", sys); conf->sync(); } else if ( sys.length()==1 && sys[0].isDigit() ) // discard old-style settings sys = "lpdunix"; return sys; } void KMFactory::unload() { UNLOAD_OBJECT(m_manager); UNLOAD_OBJECT(m_jobmanager); UNLOAD_OBJECT(m_uimanager); UNLOAD_OBJECT(m_implementation); // factory will be automatically unloaded by KLibLoader as all object have been deleted. // But to have loadFactory() to work, we need to set m_factory to NULL. m_factory = 0; } void KMFactory::reload(const QString& syst, bool saveSyst) { // notify all registered objects about the coming reload QPtrListIterator it(m_objects); for (;it.current();++it) it.current()->aboutToReload(); // unload all objects from the plugin unload(); if (saveSyst) { KConfig *conf = printConfig(); conf->setGroup("General"); conf->writeEntry("PrintSystem", syst); conf->sync(); // notify all other apps using DCOP signal emit pluginChanged(getpid()); } // reload the factory loadFactory(syst); // notify all registered objects for (it.toFirst();it.current();++it) it.current()->reload(); } QValueList KMFactory::pluginList() { QDir d(locate("data", "kdeprint/plugins/"), "*.print", QDir::Name, QDir::Files); QValueList list; for (uint i=0; irollback(); UNLOAD_OBJECT(m_printconfig); // Then reload everything and notified registered objects. // Do NOT re-save the new print system. QString syst = printSystem(); reload(syst, false); } } void KMFactory::slot_configChanged() { kdDebug(500) << "KMFactory (" << getpid() << ") receiving DCOP signal configChanged()" << endl; // unload/reload config object (make it non dirty to // avoid saving it and overwriting the newly saved options // in the other application) printConfig()->rollback(); UNLOAD_OBJECT(m_printconfig); printConfig(); // notify all registered objects about the coming reload QPtrListIterator it(m_objects); /*for (;it.current();++it) it.current()->aboutToReload();*/ // notify all object about the change for (it.toFirst(); it.current();++it) it.current()->configChanged(); } void KMFactory::saveConfig() { KConfig *conf = printConfig(); conf->sync(); kdDebug(500) << "KMFactory (" << getpid() << ") emitting DCOP signal configChanged()" << endl; emit configChanged(); // normally, the self application should also receive the signal, // anyway the config object has been updated "locally", so ne real // need to reload the config file. } QPair KMFactory::requestPassword( int& seqNbr, const QString& user, const QString& host, int port ) { DCOPRef kdeprintd( "kded", "kdeprintd" ); /** * We do not use an internal event loop for 2 potential problems: * - the MessageWindow modality (appearing afterwards, it pops up on top * of the password dialog) * - KMTimer should be stopped, but it's unavailable from this object */ - DCOPReply reply = kdeprintd.callExt( "requestPassword", DCOPRef::NoEventLoop, -1, user, host, port, seqNbr ); + DCOPReply reply = kdeprintd.call( "requestPassword", user, host, port, seqNbr ); if ( reply.isValid() ) { QString replyString = reply; if ( replyString != "::" ) { QStringList l = QStringList::split( ':', replyString, true ); if ( l.count() == 3 ) { seqNbr = l[ 2 ].toInt(); return QPair( l[ 0 ], l[ 1 ] ); } } } return QPair( QString::null, QString::null ); } +void KMFactory::initPassword( const QString& user, const QString& password, const QString& host, int port ) +{ + DCOPRef kdeprintd( "kded", "kdeprintd" ); + /** + * We do not use an internal event loop for 2 potential problems: + * - the MessageWindow modality (appearing afterwards, it pops up on top + * of the password dialog) + * - KMTimer should be stopped, but it's unavailable from this object + */ + kdeprintd.call( "initPassword", user, password, host, port ); +} + #include "kmfactory.moc" diff --git a/kdeprint/kmfactory.h b/kdeprint/kmfactory.h index 685c91f1e8..6eabd1f5c3 100644 --- a/kdeprint/kmfactory.h +++ b/kdeprint/kmfactory.h @@ -1,129 +1,130 @@ /* * This file is part of the KDE libraries * Copyright (c) 2001 Michael Goffioul * * $Id$ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License version 2 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. **/ #ifndef KMFACTORY_H #define KMFACTORY_H #include #include #include #include #include #include #include #include class KMManager; class KMJobManager; class KMUiManager; class KMVirtualManager; class KXmlCommandManager; class KMSpecialManager; class KPrinterImpl; class KLibFactory; class KConfig; class KPReloadObject; class KMFactory : public QObject, public DCOPObject { Q_OBJECT K_DCOP public: struct PluginInfo { QString name; QString comment; QStringList detectUris; int detectPrecedence; QStringList mimeTypes; QString primaryMimeType; }; static KMFactory* self(); static bool exists(); static void release(); KMFactory(); ~KMFactory(); KMManager* manager(); KMJobManager* jobManager(); KMUiManager* uiManager(); KMVirtualManager* virtualManager(); KMSpecialManager* specialManager(); KXmlCommandManager* commandManager(); KPrinterImpl* printerImplementation(); KConfig* printConfig(const QString& group = QString::null); QString printSystem(); QValueList pluginList(); PluginInfo pluginInfo(const QString& name); void saveConfig(); void reload(const QString& syst, bool saveSyst = true); void registerObject(KPReloadObject*, bool = false); void unregisterObject(KPReloadObject*); struct Settings { int application; int standardDialogPages; int pageSelection; int orientation; int pageSize; }; Settings* settings() const { return m_settings; } QPair requestPassword( int& seqNbr, const QString& user, const QString& host = "localhost", int port = 0 ); + void initPassword( const QString& user, const QString& password, const QString& host = "localhsot", int port = 0 ); k_dcop: ASYNC slot_pluginChanged(pid_t); ASYNC slot_configChanged(); k_dcop_signals: void pluginChanged(pid_t); void configChanged(); private: void createManager(); void createJobManager(); void createUiManager(); void createPrinterImpl(); void loadFactory(const QString& syst = QString::null); void unload(); QString autoDetect(); private: static KMFactory *m_self; KMManager *m_manager; KMJobManager *m_jobmanager; KMUiManager *m_uimanager; KPrinterImpl *m_implementation; KLibFactory *m_factory; KConfig *m_printconfig; Settings *m_settings; QPtrList m_objects; }; #endif