diff options
Diffstat (limited to 'tdeprint/tdeprintd.cpp')
-rw-r--r-- | tdeprint/tdeprintd.cpp | 315 |
1 files changed, 315 insertions, 0 deletions
diff --git a/tdeprint/tdeprintd.cpp b/tdeprint/tdeprintd.cpp new file mode 100644 index 000000000..d6237b2b2 --- /dev/null +++ b/tdeprint/tdeprintd.cpp @@ -0,0 +1,315 @@ +/* + * This file is part of the KDE libraries + * Copyright (c) 2001 Michael Goffioul <tdeprint@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 "tdeprintd.h" +#include "kprintprocess.h" + +#include <tqfile.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 <tqlabel.h> +#include <kpushbutton.h> +#include <kiconloader.h> +#include <kstandarddirs.h> +#include <kwin.h> +#include <kapplication.h> +#include <tqlayout.h> +#include <tqtimer.h> +#include <tqregexp.h> + +#include <unistd.h> + +extern "C" +{ + KDE_EXPORT KDEDModule *create_tdeprintd(const TQCString& name) + { + return new KDEPrintd(name); + } +} + +class StatusWindow : public TQWidget +{ +public: + StatusWindow(int pid = -1); + void setMessage(const TQString&); + int pid() const { return m_pid; } + +private: + TQLabel *m_label; + TQPushButton *m_button; + int m_pid; + TQLabel *m_icon; +}; + +StatusWindow::StatusWindow(int pid) +: TQWidget(NULL, "StatusWindow", (WFlags)(WType_TopLevel|WStyle_DialogBorder|WStyle_StaysOnTop|WDestructiveClose)), m_pid(pid) +{ + m_label = new TQLabel(this); + m_label->tqsetAlignment(AlignCenter); + m_button = new KPushButton(KStdGuiItem::close(), this); + m_icon = new TQLabel(this); + m_icon->setPixmap(DesktopIcon("fileprint")); + m_icon->tqsetAlignment(AlignCenter); + KWin::setIcons(winId(), *(m_icon->pixmap()), SmallIcon("fileprint")); + TQGridLayout *l0 = new TQGridLayout(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, TQT_SIGNAL(clicked()), TQT_SLOT(hide())); + resize(200, 50); +} + +void StatusWindow::setMessage(const TQString& msg) +{ + //QSize oldSz = size(); + m_label->setText(msg); + //QSize sz = m_label->tqsizeHint(); + //sz += TQSize(layout()->margin()*2, layout()->margin()*2+layout()->spacing()+m_button->tqsizeHint().height()); + // dialog will never be smaller + //sz = sz.expandedTo(oldSz); + //resize(sz); + //setFixedSize(sz); + //layout()->activate(); +} + +//***************************************************************************************************** + +KDEPrintd::KDEPrintd(const TQCString& obj) +: KDEDModule(obj) +{ + m_processpool.setAutoDelete(true); + m_windows.setAutoDelete(false); + m_requestsPending.setAutoDelete( true ); +} + +KDEPrintd::~KDEPrintd() +{ +} + +int KDEPrintd::print(const TQString& cmd, const TQStringList& files, bool remflag) +{ + KPrintProcess *proc = new KPrintProcess; + TQString command(cmd); + TQRegExp re( "\\$out\\{([^}]*)\\}" ); + + connect(proc,TQT_SIGNAL(printTerminated(KPrintProcess*)),TQT_SLOT(slotPrintTerminated(KPrintProcess*))); + connect(proc,TQT_SIGNAL(printError(KPrintProcess*,const TQString&)),TQT_SLOT(slotPrintError(KPrintProcess*,const TQString&))); + proc->setCommand( command ); + if ( re.search( command ) != -1 ) + { + KURL url( re.cap( 1 ) ); + if ( !url.isLocalFile() ) + { + TQString tmpFilename = locateLocal( "tmp", "tdeprint_" + 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 TQString& 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 ); +} + +TQString KDEPrintd::openPassDlg(const TQString& user) +{ + TQString user_(user), pass_, result; + if (KIO::PasswordDialog::getNameAndPassword(user_, pass_, NULL) == KDialog::Accepted) + result.append(user_).append(":").append(pass_); + return result; +} + +bool KDEPrintd::checkFiles(TQString& cmd, const TQStringList& files) +{ + for (TQStringList::ConstIterator it=files.begin(); it!=files.end(); ++it) + if (::access(TQFile::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."), + TQString::null, + i18n("Provide root's Password"), + "provideRootsPassword") == KMessageBox::Continue) + { + cmd = ("tdesu -c " + KProcess::quote(cmd)); + break; + } + else + return false; + } + return true; +} + +void KDEPrintd::statusMessage(const TQString& msg, int pid, const TQString& 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="+TQString::number(pid)+")")); + else + w->setCaption(i18n("Printing Status - %1").arg(appName)); + connect(w, TQT_SIGNAL(destroyed()), TQT_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; + TQString user; + TQString uri; + int seqNbr; +}; + +TQString KDEPrintd::requestPassword( const TQString& user, const TQString& host, int port, int seqNbr ) +{ + Request *req = new Request; + req->user = user; + req->uri = "print://" + user + "@" + host + ":" + TQString::number(port); + req->seqNbr = seqNbr; + req->transaction = callingDcopClient()->beginTransaction(); + m_requestsPending.append( req ); + if ( m_requestsPending.count() == 1 ) + TQTimer::singleShot( 0, this, TQT_SLOT( processRequest() ) ); + return "::"; +} + +void KDEPrintd::processRequest() +{ + if ( m_requestsPending.count() == 0 ) + return; + + Request *req = m_requestsPending.first(); + KIO::AuthInfo info; + TQByteArray params, reply; + TQCString replyType; + TQString authString( "::" ); + + info.username = req->user; + info.keepPassword = true; + info.url = req->uri; + info.comment = i18n( "Printing system" ); + + TQDataStream input( params, IO_WriteOnly ); + input << info << TQString(i18n( "Authentication failed (user name=%1)" ).arg( info.username )) << 0L << (long int) req->seqNbr; + if ( callingDcopClient()->call( "kded", "kpasswdserver", "queryAuthInfo(KIO::AuthInfo,TQString,long int,long int)", + params, replyType, reply ) ) + { + if ( replyType == "KIO::AuthInfo" ) + { + TQDataStream output( reply, IO_ReadOnly ); + KIO::AuthInfo result; + int seqNbr; + output >> result >> seqNbr; + + if ( result.isModified() ) + authString = result.username + ":" + result.password + ":" + TQString::number( seqNbr ); + } + else + kdWarning( 500 ) << "DCOP returned type error, expected KIO::AuthInfo, received " << replyType << endl; + } + else + kdWarning( 500 ) << "Cannot communicate with kded_kpasswdserver" << endl; + + TQByteArray outputData; + TQDataStream output( outputData, IO_WriteOnly ); + output << authString; + replyType = "TQString"; + callingDcopClient()->endTransaction( req->transaction, replyType, outputData ); + + m_requestsPending.remove( ( unsigned int )0 ); + if ( m_requestsPending.count() > 0 ) + TQTimer::singleShot( 0, this, TQT_SLOT( processRequest() ) ); +} + +void KDEPrintd::initPassword( const TQString& user, const TQString& passwd, const TQString& host, int port ) +{ + TQByteArray params, reply; + TQCString replyType; + KIO::AuthInfo info; + + info.username = user; + info.password = passwd; + info.url = "print://" + user + "@" + host + ":" + TQString::number(port); + + TQDataStream 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 "tdeprintd.moc" |