summaryrefslogtreecommitdiffstats
path: root/kdeprint/kdeprintd.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kdeprint/kdeprintd.cpp')
-rw-r--r--kdeprint/kdeprintd.cpp315
1 files changed, 315 insertions, 0 deletions
diff --git a/kdeprint/kdeprintd.cpp b/kdeprint/kdeprintd.cpp
new file mode 100644
index 000000000..3506b6469
--- /dev/null
+++ b/kdeprint/kdeprintd.cpp
@@ -0,0 +1,315 @@
+/*
+ * This file is part of the KDE libraries
+ * Copyright (c) 2001 Michael Goffioul <kdeprint@swing.be>
+ *
+ * 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., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#include "kdeprintd.h"
+#include "kprintprocess.h"
+
+#include <qfile.h>
+#include <klocale.h>
+#include <knotifyclient.h>
+#include <kmessagebox.h>
+#include <kdebug.h>
+#include <dcopclient.h>
+#include <kio/passdlg.h>
+#include <kio/authinfo.h>
+#include <qlabel.h>
+#include <kpushbutton.h>
+#include <kiconloader.h>
+#include <kstandarddirs.h>
+#include <kwin.h>
+#include <kapplication.h>
+#include <qlayout.h>
+#include <qtimer.h>
+#include <qregexp.h>
+
+#include <unistd.h>
+
+extern "C"
+{
+ KDE_EXPORT KDEDModule *create_kdeprintd(const QCString& name)
+ {
+ return new KDEPrintd(name);
+ }
+}
+
+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_windows.setAutoDelete(false);
+ m_requestsPending.setAutoDelete( true );
+}
+
+KDEPrintd::~KDEPrintd()
+{
+}
+
+int KDEPrintd::print(const QString& cmd, const QStringList& files, bool remflag)
+{
+ KPrintProcess *proc = new KPrintProcess;
+ QString command(cmd);
+ QRegExp re( "\\$out\\{([^}]*)\\}" );
+
+ connect(proc,SIGNAL(printTerminated(KPrintProcess*)),SLOT(slotPrintTerminated(KPrintProcess*)));
+ connect(proc,SIGNAL(printError(KPrintProcess*,const QString&)),SLOT(slotPrintError(KPrintProcess*,const QString&)));
+ proc->setCommand( command );
+ if ( re.search( command ) != -1 )
+ {
+ KURL url( re.cap( 1 ) );
+ if ( !url.isLocalFile() )
+ {
+ QString tmpFilename = locateLocal( "tmp", "kdeprint_" + kapp->randomString( 8 ) );
+ command.replace( re, KProcess::quote( tmpFilename ) );
+ proc->setOutput( re.cap( 1 ) );
+ proc->setTempOutput( tmpFilename );
+ }
+ else
+ command.replace( re, KProcess::quote( re.cap( 1 ) ) );
+ }
+
+ if ( checkFiles( command, files ) )
+ {
+ *proc << command;
+ if ( remflag )
+ proc->setTempFiles( files );
+ if ( proc->print() )
+ {
+ m_processpool.append( proc );
+ return ( int )proc->pid();
+ }
+ }
+
+ delete proc;
+ return -1;
+}
+
+void KDEPrintd::slotPrintTerminated( KPrintProcess *proc )
+{
+ m_processpool.removeRef( proc );
+}
+
+void KDEPrintd::slotPrintError( KPrintProcess *proc, const QString& msg )
+{
+ KNotifyClient::event("printerror",i18n("<p><nobr>A print error occurred. Error message received from system:</nobr></p><br>%1").arg(msg));
+ m_processpool.removeRef( proc );
+}
+
+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<const StatusWindow*>(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( "Authentication failed (user name=%1)" ).arg( info.username ) << 0L << (long int) 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"