| # kdeprint Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# kdeprintd.cpp

    00001 /*
    00002  *  This file is part of the KDE libraries
    00003  *  Copyright (c) 2001 Michael Goffioul <kdeprint@swing.be>
    00004  *
    00005  *  This library is free software; you can redistribute it and/or
    00006  *  modify it under the terms of the GNU Library General Public
    00007  *  License version 2 as published by the Free Software Foundation.
    00008  *
    00009  *  This library is distributed in the hope that it will be useful,
    00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00012  *  Library General Public License for more details.
    00013  *
    00014  *  You should have received a copy of the GNU Library General Public License
    00015  *  along with this library; see the file COPYING.LIB.  If not, write to
    00016  *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    00017  *  Boston, MA 02111-1307, USA.
    00018  **/
    00019
    00020 #include "kdeprintd.h"
    00021 #include "kprintprocess.h"
    00022
    00023 #include <qfile.h>
    00024 #include <klocale.h>
    00025 #include <knotifyclient.h>
    00026 #include <kmessagebox.h>
    00027 #include <kdebug.h>
    00028 #include <dcopclient.h>
    00029 #include <kio/passdlg.h>
    00030 #include <kio/authinfo.h>
    00031 #include <qlabel.h>
    00032 #include <kpushbutton.h>
    00033 #include <kiconloader.h>
    00034 #include <kstandarddirs.h>
    00035 #include <kwin.h>
    00036 #include <kapplication.h>
    00037 #include <qlayout.h>
    00038 #include <qtimer.h>
    00039 #include <qregexp.h>
    00040
    00041 #include <unistd.h>
    00042
    00043 extern "C"
    00044 {
    00045     KDE_EXPORT KDEDModule *create_kdeprintd(const QCString& name)
    00046     {
    00047         return new KDEPrintd(name);
    00048     }
    00049 }
    00050
    00051 class StatusWindow : public QWidget
    00052 {
    00053 public:
    00054     StatusWindow(int pid = -1);
    00055     void setMessage(const QString&);
    00056     int pid() const { return m_pid; }
    00057
    00058 private:
    00059     QLabel      *m_label;
    00060     QPushButton *m_button;
    00061     int     m_pid;
    00062     QLabel      *m_icon;
    00063 };
    00064
    00065 StatusWindow::StatusWindow(int pid)
    00066 : QWidget(NULL, "StatusWindow", WType_TopLevel|WStyle_DialogBorder|WStyle_StaysOnTop|WDestructiveClose), m_pid(pid)
    00067 {
    00068     m_label = new QLabel(this);
    00069     m_label->setAlignment(AlignCenter);
    00070     m_button = new KPushButton(KStdGuiItem::close(), this);
    00071     m_icon = new QLabel(this);
    00072     m_icon->setPixmap(DesktopIcon("fileprint"));
    00073     m_icon->setAlignment(AlignCenter);
    00074     KWin::setIcons(winId(), *(m_icon->pixmap()), SmallIcon("fileprint"));
    00075     QGridLayout *l0 = new QGridLayout(this, 2, 3, 10, 10);
    00076     l0->setRowStretch(0, 1);
    00077     l0->setColStretch(1, 1);
    00078     l0->addMultiCellWidget(m_label, 0, 0, 1, 2);
    00079     l0->addWidget(m_button, 1, 2);
    00080     l0->addMultiCellWidget(m_icon, 0, 1, 0, 0);
    00081     connect(m_button, SIGNAL(clicked()), SLOT(hide()));
    00082     resize(200, 50);
    00083 }
    00084
    00085 void StatusWindow::setMessage(const QString& msg)
    00086 {
    00087     //QSize oldSz = size();
    00088     m_label->setText(msg);
    00089     //QSize sz = m_label->sizeHint();
    00090     //sz += QSize(layout()->margin()*2, layout()->margin()*2+layout()->spacing()+m_button->sizeHint().height());
    00091     // dialog will never be smaller
    00092     //sz = sz.expandedTo(oldSz);
    00093     //resize(sz);
    00094     //setFixedSize(sz);
    00095     //layout()->activate();
    00096 }
    00097
    00098 //*****************************************************************************************************
    00099
    00100 KDEPrintd::KDEPrintd(const QCString& obj)
    00101 : KDEDModule(obj)
    00102 {
    00103     m_processpool.setAutoDelete(true);
    00104     m_windows.setAutoDelete(false);
    00105     m_requestsPending.setAutoDelete( true );
    00106 }
    00107
    00108 KDEPrintd::~KDEPrintd()
    00109 {
    00110 }
    00111
    00112 int KDEPrintd::print(const QString& cmd, const QStringList& files, bool remflag)
    00113 {
    00114     KPrintProcess *proc = new KPrintProcess;
    00115     QString command(cmd);
    00116     QRegExp re( "\\$out\\{([^}]*)\\}" );
    00117
    00118     connect(proc,SIGNAL(printTerminated(KPrintProcess*)),SLOT(slotPrintTerminated(KPrintProcess*)));
    00119     connect(proc,SIGNAL(printError(KPrintProcess*,const QString&)),SLOT(slotPrintError(KPrintProcess*,const QString&)));
    00120     proc->setCommand( command );
    00121     if ( re.search( command ) != -1 )
    00122     {
    00123         KURL url( re.cap( 1 ) );
    00124         if ( !url.isLocalFile() )
    00125         {
    00126             QString tmpFilename = locateLocal( "tmp", "kdeprint_" + kapp->randomString( 8 ) );
    00127             command.replace( re, KProcess::quote( tmpFilename ) );
    00128             proc->setOutput( re.cap( 1 ) );
    00129             proc->setTempOutput( tmpFilename );
    00130         }
    00131         else
    00132             command.replace( re, KProcess::quote( re.cap( 1 ) ) );
    00133     }
    00134
    00135     if ( checkFiles( command, files ) )
    00136     {
    00137         *proc << command;
    00138         if ( remflag )
    00139             proc->setTempFiles( files );
    00140         if ( proc->print() )
    00141         {
    00142             m_processpool.append( proc );
    00143             return ( int )proc->pid();
    00144         }
    00145     }
    00146
    00147     delete proc;
    00148     return -1;
    00149 }
    00150
    00151 void KDEPrintd::slotPrintTerminated( KPrintProcess *proc )
    00152 {
    00153     m_processpool.removeRef( proc );
    00154 }
    00155
    00156 void KDEPrintd::slotPrintError( KPrintProcess *proc, const QString& msg )
    00157 {
    00158     KNotifyClient::event("printerror",i18n("<p><nobr>A print error occurred. Error message received from system:</nobr></p><br>%1").arg(msg));
    00159     m_processpool.removeRef( proc );
    00160 }
    00161
    00162 QString KDEPrintd::openPassDlg(const QString& user)
    00163 {
    00164     QString user_(user), pass_, result;
    00165     if (KIO::PasswordDialog::getNameAndPassword(user_, pass_, NULL) == KDialog::Accepted)
    00166         result.append(user_).append(":").append(pass_);
    00167     return result;
    00168 }
    00169
    00170 bool KDEPrintd::checkFiles(QString& cmd, const QStringList& files)
    00171 {
    00172     for (QStringList::ConstIterator it=files.begin(); it!=files.end(); ++it)
    00173         if (::access(QFile::encodeName(*it).data(), R_OK) != 0)
    00174         {
    00175             if (KMessageBox::warningContinueCancel(0,
    00176                 i18n("Some of the files to print are not readable by the KDE "
    00177                      "print daemon. This may happen if you are trying to print "
    00178                      "as a different user to the one currently logged in. To continue "
    00179                      "printing, you need to provide root's password."),
    00180                 QString::null,
    00181                 i18n("Provide root's Password"),
    00182                 "provideRootsPassword") == KMessageBox::Continue)
    00183             {
    00184                 cmd = ("kdesu -c " + KProcess::quote(cmd));
    00185                 break;
    00186             }
    00187             else
    00188                 return false;
    00189         }
    00190     return true;
    00191 }
    00192
    00193 void KDEPrintd::statusMessage(const QString& msg, int pid, const QString& appName)
    00194 {
    00195     StatusWindow    *w = m_windows.find(pid);
    00196     if (!w && !msg.isEmpty())
    00197     {
    00198         w = new StatusWindow(pid);
    00199         if (appName.isEmpty())
    00200             w->setCaption(i18n("Printing Status - %1").arg("(pid="+QString::number(pid)+")"));
    00201         else
    00202             w->setCaption(i18n("Printing Status - %1").arg(appName));
    00203         connect(w, SIGNAL(destroyed()), SLOT(slotClosed()));
    00204         w->show();
    00205         m_windows.insert(pid, w);
    00206     }
    00207     if (w)
    00208     {
    00209         if (!msg.isEmpty())
    00210             w->setMessage(msg);
    00211         else
    00212             w->close();
    00213     }
    00214 }
    00215
    00216 void KDEPrintd::slotClosed()
    00217 {
    00218     const StatusWindow  *w = static_cast<const StatusWindow*>(sender());
    00219     if (w)
    00220     {
    00221         m_windows.remove(w->pid());
    00222     }
    00223 }
    00224
    00225 //******************************************************************************************
    00226
    00227 class KDEPrintd::Request
    00228 {
    00229 public:
    00230     DCOPClientTransaction *transaction;
    00231     QString user;
    00232     QString uri;
    00233     int seqNbr;
    00234 };
    00235
    00236 QString KDEPrintd::requestPassword( const QString& user, const QString& host, int port, int seqNbr )
    00237 {
    00238     Request *req = new Request;
    00239     req->user = user;
    00240     req->uri = "print://" + user + "@" + host + ":" + QString::number(port);
    00241     req->seqNbr = seqNbr;
    00242     req->transaction = callingDcopClient()->beginTransaction();
    00243     m_requestsPending.append( req );
    00244     if ( m_requestsPending.count() == 1 )
    00245         QTimer::singleShot( 0, this, SLOT( processRequest() ) );
    00246     return "::";
    00247 }
    00248
    00249 void KDEPrintd::processRequest()
    00250 {
    00251     if ( m_requestsPending.count() == 0 )
    00252         return;
    00253
    00254     Request *req = m_requestsPending.first();
    00255     KIO::AuthInfo info;
    00256     QByteArray params, reply;
    00257     QCString replyType;
    00258     QString authString( "::" );
    00259
    00260     info.username = req->user;
    00261     info.keepPassword = true;
    00262     info.url = req->uri;
    00263     info.comment = i18n( "Printing system" );
    00264
    00265     QDataStream input( params, IO_WriteOnly );
    00266     input << info << i18n( "Authentication failed (user name=%1)" ).arg( info.username ) << 0 << req->seqNbr;
    00267     if ( callingDcopClient()->call( "kded", "kpasswdserver", "queryAuthInfo(KIO::AuthInfo,QString,long int,long int)",
    00268                 params, replyType, reply ) )
    00269     {
    00270         if ( replyType == "KIO::AuthInfo" )
    00271         {
    00272             QDataStream output( reply, IO_ReadOnly );
    00273             KIO::AuthInfo result;
    00274             int seqNbr;
    00275             output >> result >> seqNbr;
    00276
    00277             if ( result.isModified() )
    00278                 authString = result.username + ":" + result.password + ":" + QString::number( seqNbr );
    00279         }
    00280         else
    00281             kdWarning( 500 ) << "DCOP returned type error, expected KIO::AuthInfo, received " << replyType << endl;
    00282     }
    00283     else
    00284         kdWarning( 500 ) << "Cannot communicate with kded_kpasswdserver" << endl;
    00285
    00286     QByteArray outputData;
    00287     QDataStream output( outputData, IO_WriteOnly );
    00288     output << authString;
    00289     replyType = "QString";
    00290     callingDcopClient()->endTransaction( req->transaction, replyType, outputData );
    00291
    00292     m_requestsPending.remove( ( unsigned int )0 );
    00293     if ( m_requestsPending.count() > 0 )
    00294         QTimer::singleShot( 0, this, SLOT( processRequest() ) );
    00295 }
    00296
    00297 void KDEPrintd::initPassword( const QString& user, const QString& passwd, const QString& host, int port )
    00298 {
    00299     QByteArray params, reply;
    00300     QCString replyType;
    00301     KIO::AuthInfo info;
    00302
    00303     info.username = user;
    00304     info.password = passwd;
    00305     info.url = "print://" + user + "@" + host + ":" + QString::number(port);
    00306
    00307     QDataStream input( params, IO_WriteOnly );
    00308     input << info << ( long int )0;
    00309
    00310     if ( !callingDcopClient()->call( "kded", "kpasswdserver", "addAuthInfo(KIO::AuthInfo,long int)",
    00311             params, replyType, reply ) )
    00312         kdWarning( 500 ) << "Unable to initialize password, cannot communicate with kded_kpasswdserver" << endl;
    00313 }
    00314
    00315 #include "kdeprintd.moc"

This file is part of the documentation for kdeprint Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:31:01 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003