diff options
Diffstat (limited to 'kdeprint/slave/kio_print.cpp')
-rw-r--r-- | kdeprint/slave/kio_print.cpp | 920 |
1 files changed, 920 insertions, 0 deletions
diff --git a/kdeprint/slave/kio_print.cpp b/kdeprint/slave/kio_print.cpp new file mode 100644 index 000000000..6857ef2e6 --- /dev/null +++ b/kdeprint/slave/kio_print.cpp @@ -0,0 +1,920 @@ +/* + * 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 "kio_print.h" +#include <kdeprint/kmprinter.h> +#include <kdeprint/kmmanager.h> +#include <kdeprint/kmjobmanager.h> +#include <kdeprint/kmjob.h> +#include <kdeprint/driver.h> + +#include <qfile.h> +#include <qtextstream.h> +#include <klocale.h> +#include <kdebug.h> +#include <kinstance.h> +#include <kio/global.h> +#include <kstandarddirs.h> +#include <kiconloader.h> +#include <kmimetype.h> +#include <kio/job.h> +#include <kapplication.h> +#include <kcmdlineargs.h> +#include <kaboutdata.h> +#include <kprocess.h> +#include <ktempfile.h> +#include <qfile.h> +#include <qdom.h> + +#include <stdio.h> +#include <stdlib.h> +#include <sys/stat.h> + +#define PRINT_DEBUG kdDebug(7019) << "kio_print: " + +extern "C" +{ + int KDE_EXPORT kdemain(int argc, char **argv); +} + +void addAtom(KIO::UDSEntry& entry, unsigned int ID, long l, const QString& s = QString::null) +{ + KIO::UDSAtom atom; + atom.m_uds = ID; + atom.m_long = l; + atom.m_str = s; + entry.append(atom); +} + +static void createDirEntry(KIO::UDSEntry& entry, const QString& name, const QString& url, const QString& mime) +{ + entry.clear(); + addAtom(entry, KIO::UDS_NAME, 0, name); + addAtom(entry, KIO::UDS_FILE_TYPE, S_IFDIR); + addAtom(entry, KIO::UDS_ACCESS, 0500); + addAtom(entry, KIO::UDS_MIME_TYPE, 0, mime); + addAtom(entry, KIO::UDS_URL, 0, url); + PRINT_DEBUG << "creating dir entry url=" << url << " mimetype=" << mime << endl; + addAtom(entry, KIO::UDS_SIZE, 0); + //addAtom(entry, KIO::UDS_GUESSED_MIME_TYPE, 0, "application/octet-stream"); +} + +static void createFileEntry(KIO::UDSEntry& entry, const QString& name, const QString& url, const QString& mime) +{ + entry.clear(); + addAtom(entry, KIO::UDS_NAME, 0, name); + addAtom(entry, KIO::UDS_FILE_TYPE, S_IFREG); + addAtom(entry, KIO::UDS_URL, 0, url); + addAtom(entry, KIO::UDS_ACCESS, 0400); + addAtom(entry, KIO::UDS_MIME_TYPE, 0, mime); + addAtom(entry, KIO::UDS_SIZE, 0); + addAtom(entry, KIO::UDS_GUESSED_MIME_TYPE, 0, "application/octet-stream"); +} + +QString buildMenu(const QStringList& items, const QStringList& links, int active) +{ + if (items.count() == 0 || items.count() != links.count()) + return QString("<td height=20 class=\"menu\"> </td>"); + + QString s; + int index = 0; + for (QStringList::ConstIterator it1=items.begin(), it2=links.begin(); it1!=items.end() && it2!=links.end(); ++it1, ++it2, index++) + { + if (index == active) + s.append("<td height=20 class=\"menuactive\"> ").append(*it1).append(" </td>"); + else + s.append("<td height=20 class=\"menu\"> <a class=\"menu\" href=\"").append(*it2).append("\">").append(*it1).append("</a> </td>"); + if ((unsigned int)index < items.count()-1) + s.append("<td height=20 class=\"menu\">|</td>"); + } + return s; +} + +QString buildOptionRow(DrBase *opt, bool f) +{ + QString s("<tr class=\"%1\"><td width=\"41%\">%1</td><td width=\"59%\">%1</td></tr>\n"); + s = s.arg(f ? "contentwhite" : "contentyellow").arg(opt->get("text")).arg(opt->prettyText()); + return s; +} + +QString buildGroupTable(DrGroup *grp, bool showHeader = true) +{ + QString s("<tr class=\"top\"><td colspan=\"2\">%1</td></tr>\n"); + if (showHeader) + s = s.arg(grp->get("text")); + else + s = QString::null; + + QPtrListIterator<DrBase> oit(grp->options()); + bool f(false); + for (; oit.current(); ++oit, f = !f) + s.append(buildOptionRow(oit.current(), f)); + + QPtrListIterator<DrGroup> git(grp->groups()); + for (; git.current(); ++git) + s.append(buildGroupTable(git.current())); + + return s; +} + +int kdemain(int argc, char **argv) +{ + KInstance instance("kio_print"); + + PRINT_DEBUG << "starting ioslave" << endl; + if (argc != 4) + { + fprintf(stderr, "Usage: kio_print protocol domain-socket1 domain-socket2\n"); + exit(-1); + } + + /* create fake KApplicatiom object, needed for job stuffs */ + KAboutData about( "kio_print", "kio_print", "fake_version", + "KDEPrint IO slave", KAboutData::License_GPL, "(c) 2003, Michael Goffioul" ); + KCmdLineArgs::init( &about ); + KApplication app; + + KIO_Print slave(argv[2], argv[3]); + slave.dispatchLoop(); + + PRINT_DEBUG << "done" << endl; + return 0; +} + +KIO_Print::KIO_Print(const QCString& pool, const QCString& app) +: KIO::SlaveBase("print", pool, app) +{ +} + +void KIO_Print::listDir(const KURL& url) +{ + if ( url.protocol() == "printdb" ) + { + listDirDB( url ); + return; + } + + QStringList path = QStringList::split('/', url.path(), false); + + PRINT_DEBUG << "listing " << url.path() << endl; + QString group = path[0].lower(); + if (path.count() == 0) + listRoot(); + else if (path.count() == 1 && group != "manager" && group != "jobs") + { + PRINT_DEBUG << "listing group " << path[0] << endl; + + int mask; + QString mimeType; + KIO::UDSEntry entry; + + if (group == "printers") + { + mask = KMPrinter::Printer; + mimeType = "print/printer"; + } + else if (group == "classes") + { + mask = KMPrinter::Class | KMPrinter::Implicit; + mimeType = "print/class"; + } + else if (group == "specials") + { + mask = KMPrinter::Special; + mimeType = "print/printer"; + } + else + { + error(KIO::ERR_DOES_NOT_EXIST, url.url()); + return; + } + + QPtrListIterator<KMPrinter> it(*(KMManager::self()->printerList())); + for (;it.current();++it) + { + if (!(it.current()->type() & mask) || !it.current()->instanceName().isEmpty()) + { + PRINT_DEBUG << "rejecting " << it.current()->name() << endl; + continue; + } + + //createFileEntry(entry, it.current()->name(), ("print:/"+path[0]+"/"+it.current()->name()), mimeType, "text/html", S_IFDIR); + createDirEntry(entry, it.current()->name(), ("print:/"+group+"/"+KURL::encode_string_no_slash(it.current()->name())), mimeType); + PRINT_DEBUG << "accepting " << it.current()->name() << endl; + listEntry(entry, false); + } + + listEntry(KIO::UDSEntry(), true); + finished(); + } + else + { + //error(KIO::ERR_UNSUPPORTED_ACTION, i18n("Unsupported path %1").arg(url.path())); + // better do nothing + listEntry(KIO::UDSEntry(), true); + totalSize(0); + finished(); + } +} + +void KIO_Print::listRoot() +{ + PRINT_DEBUG << "listing root entry" << endl; + + KIO::UDSEntry entry; + + // Classes entry + createDirEntry(entry, i18n("Classes"), "print:/classes", "print/folder"); + listEntry(entry, false); + + // Printers entry + createDirEntry(entry, i18n("Printers"), "print:/printers", "print/folder"); + listEntry(entry, false); + + // Specials entry + createDirEntry(entry, i18n("Specials"), "print:/specials", "print/folder"); + listEntry(entry, false); + + // Management entry + //createFileEntry(entry, i18n("Manager"), "print:/manager", "print/manager", QString::null, S_IFDIR); + createDirEntry(entry, i18n("Manager"), "print:/manager", "print/manager"); + listEntry(entry, false); + + // Jobs entry + createDirEntry(entry, i18n("Jobs"), "print:/jobs", "print/jobs"); + listEntry(entry, false); + + // finish + totalSize(4); + listEntry(entry, true); + finished(); +} + +void KIO_Print::listDirDB( const KURL& url ) +{ + PRINT_DEBUG << "listDirDB: " << url << endl; + + QStringList pathComps = QStringList::split( '/', url.path(), false ); + KURL remUrl; + + remUrl.setProtocol( "http" ); + remUrl.setHost( url.host() ); + remUrl.setPort( url.port() ); + remUrl.setPath( "/list-data.cgi" ); + switch ( pathComps.size() ) + { + case 0: /* list manufacturers */ + remUrl.addQueryItem( "type", "makes" ); + break; + case 1: /* list printers for the given manufacturer */ + remUrl.addQueryItem( "type", "printers" ); + remUrl.addQueryItem( "make", pathComps[ 0 ] ); + break; + case 2: /* list drivers for given printer */ + remUrl.addQueryItem( "type", "drivers" ); + remUrl.addQueryItem( "printer", pathComps[ 1 ] ); + break; + default: + error( KIO::ERR_UNSUPPORTED_ACTION, "Not implemented" ); + return; + } + remUrl.addQueryItem( "format", "xml" ); + + if ( getDBFile( remUrl ) ) + { + QDomDocument doc; + if ( doc.setContent( &m_httpBuffer, false ) ) + { + QDomNodeList l; + KIO::UDSEntry entry; + switch ( pathComps.size() ) + { + case 0: + l = doc.documentElement().elementsByTagName( "make" ); + for ( unsigned int i=0; i<l.count(); i++ ) + { + QString make = l.item( i ).toElement().text(); + KURL makeUrl = url; + makeUrl.addPath( "/" + make ); + createDirEntry( entry, make, makeUrl.url(), "print/folder" ); + listEntry( entry, false ); + PRINT_DEBUG << "make: " << make << endl; + } + break; + case 1: + l = doc.documentElement().elementsByTagName( "printer" ); + for ( unsigned int i=0; i<l.count(); i++ ) + { + QString ID, name; + for ( QDomNode n=l.item( i ).firstChild(); !n.isNull(); n=n.nextSibling() ) + { + QDomElement e = n.toElement(); + if ( e.tagName() == "id" ) + ID = e.text(); + else if ( e.tagName() == "model" ) + name = e.text(); + } + if ( !ID.isEmpty() && !name.isEmpty() ) + { + KURL printerUrl = url; + printerUrl.addPath( "/" + ID ); + createDirEntry( entry, name, printerUrl.url(), "print/printermodel" ); + listEntry( entry, false ); + PRINT_DEBUG << "printer: " << ID << endl; + } + } + break; + case 2: + l = doc.documentElement().elementsByTagName( "driver" ); + for ( unsigned int i=0; i<l.count(); i++ ) + { + QString driver = l.item( i ).toElement().text(); + KURL driverUrl = url; + driverUrl.addPath( "/" + driver ); + createFileEntry( entry, driver, driverUrl.url(), "print/driver" ); + listEntry( entry, false ); + PRINT_DEBUG << "driver: " << driver << endl; + } + break; + default: + error( KIO::ERR_UNSUPPORTED_ACTION, "Not implemented" ); + return; + } + listEntry( KIO::UDSEntry(), true ); + finished(); + } + else + { + if ( m_httpBuffer.buffer().size() == 0 ) + error( KIO::ERR_INTERNAL, i18n( "Empty data received (%1)." ).arg( url.host() ) ); + else + error( KIO::ERR_INTERNAL, i18n( "Corrupted/incomplete data or server error (%1)." ).arg( url.host() ) ); + } + } + /* + * If error occured while downloading, error has been called by + * getDBFile. No need for a "else" statement. + */ +} + +void KIO_Print::stat(const KURL& url) +{ + if ( url.protocol() == "printdb" ) + { + statDB( url ); + return; + } + + PRINT_DEBUG << "stat: " << url.url() << endl; + QStringList path = QStringList::split('/', url.encodedPathAndQuery(-1), false); + KIO::UDSEntry entry; + QString mime; + bool err(false); + + PRINT_DEBUG << "path components: " << path.join(", ") << endl; + + switch (path.count()) + { + case 0: + createDirEntry(entry, i18n("Print System"), "print:/", "print/folder"); + break; + case 1: + if (path[0].lower() == "classes") + createDirEntry(entry, i18n("Classes"), "print:/classes", "print/folder"); + else if (path[0].lower() == "printers") + createDirEntry(entry, i18n("Printers"), "print:/printers", "print/folder"); + else if (path[0].lower() == "specials") + createDirEntry(entry, i18n("Specials"), "print:/specials", "print/folder"); + else if (path[0].lower() == "manager") + createDirEntry(entry, i18n("Manager"), "print:/manager", "print/manager"); + else if (path[0].lower().startsWith("jobs")) + createFileEntry(entry, i18n("Jobs"), url.url(), "text/html"); + else + err = true; + break; + case 2: + if (path[0].lower() == "printers") + mime = "print/printer"; + else if (path[0].lower() == "classes") + mime = "print/class"; + else if (path[0].lower() == "specials") + mime = "print/printer"; + else + err = true; + createFileEntry(entry, path[1], "print:/"+path[0]+"/"+path[1], "text/html"); + break; + } + + if (!err) + { + statEntry(entry); + finished(); + } + else + error(KIO::ERR_DOES_NOT_EXIST, url.path()); +} + +void KIO_Print::statDB( const KURL& url ) +{ + PRINT_DEBUG << "statDB: " << url << endl; + KIO::UDSEntry entry; + QStringList pathComps = QStringList::split( '/', url.path(), false ); + if ( pathComps.size() == 3 ) + createFileEntry( entry, i18n( "Printer driver" ), url.url(), "print/driver" ); + else + createDirEntry( entry, i18n( "On-line printer driver database" ), url.url(), "inode/directory" ); + statEntry( entry ); + finished(); +} + +bool KIO_Print::getDBFile( const KURL& src ) +{ + PRINT_DEBUG << "downloading " << src.url() << endl; + + /* re-initialize the internal buffer */ + if ( m_httpBuffer.isOpen() ) + m_httpBuffer.close(); + m_httpError = 0; + m_httpBuffer.open( IO_WriteOnly|IO_Truncate ); // be sure to erase the existing data + + /* start the transfer job */ + KIO::TransferJob *job = KIO::get( src, false, false ); + connect( job, SIGNAL( result( KIO::Job* ) ), SLOT( slotResult( KIO::Job* ) ) ); + connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ), SLOT( slotData( KIO::Job*, const QByteArray& ) ) ); + connect( job, SIGNAL( totalSize( KIO::Job*, KIO::filesize_t ) ), SLOT( slotTotalSize( KIO::Job*, KIO::filesize_t ) ) ); + connect( job, SIGNAL( processedSize( KIO::Job*, KIO::filesize_t ) ), SLOT( slotProcessedSize( KIO::Job*, KIO::filesize_t ) ) ); + kapp->enter_loop(); + m_httpBuffer.close(); + + /* return the result */ + if ( m_httpError != 0 ) + error( m_httpError, m_httpErrorTxt ); + return ( m_httpError == 0 ); +} + +void KIO_Print::getDB( const KURL& url ) +{ + PRINT_DEBUG << "downloading PPD file for " << url.url() << endl; + + QStringList pathComps = QStringList::split( '/', url.path(), false ); + if ( pathComps.size() != 3 ) + error( KIO::ERR_MALFORMED_URL, url.url() ); + else + { + KURL remUrl; + + remUrl.setProtocol( "http" ); + remUrl.setHost( url.host() ); + remUrl.setPath( "/ppd-o-matic.cgi" ); + remUrl.addQueryItem( "driver", pathComps[ 2 ] ); + remUrl.addQueryItem( "printer", pathComps[ 1 ] ); + + if ( getDBFile( remUrl ) ) + { + mimeType( "text/plain" ); + data( m_httpBuffer.buffer() ); + finished(); + } + /* + * no "else" statement needed, the error has + * already been emitted by the getDBFile function + */ + } +} + +void KIO_Print::slotResult( KIO::Job *j ) +{ + /* + * store slave results for later user (job gets deleted + * after this function). Store only if no other error + * occured previously (when writing to the buffer). + */ + if ( m_httpError == 0 ) + { + m_httpError = j->error(); + m_httpErrorTxt = j->errorText(); + } + kapp->exit_loop(); +} + +void KIO_Print::slotData( KIO::Job *j, const QByteArray& d ) +{ + PRINT_DEBUG << "HTTP data received (size=" << d.size() << ")" << endl; + if ( d.size() > 0 ) + { + int len = m_httpBuffer.writeBlock( d ); + if ( len == -1 || len != ( int )d.size() ) + { + m_httpError = KIO::ERR_INTERNAL; + m_httpErrorTxt = "Unable to write to the internal buffer."; + j->kill( false ); + } + } +} + +void KIO_Print::slotTotalSize( KIO::Job*, KIO::filesize_t sz ) +{ + totalSize( sz ); +} + +void KIO_Print::slotProcessedSize( KIO::Job*, KIO::filesize_t sz ) +{ + processedSize( sz ); +} + +void KIO_Print::get(const KURL& url) +{ + if ( url.protocol() == "printdb" ) + { + getDB( url ); + return; + } + + QStringList elems = QStringList::split('/', url.encodedPathAndQuery(), false); + QString group(elems[0].lower()), printer(KURL::decode_string(elems[1])), path, query; + KMPrinter *mprinter(0); + + if (group == "manager") + { + PRINT_DEBUG << "opening print management part" << endl; + + mimeType("print/manager"); + finished(); + return; + } + + PRINT_DEBUG << "getting " << url.url() << endl; + + if (group.startsWith("jobs")) + { + int p = group.find('?'); + if (p != -1) + query = group.mid(p+1); + if (!query.isEmpty() && query != "jobs" && query != "completed_jobs") + { + error(KIO::ERR_MALFORMED_URL, QString::null); + return; + } + PRINT_DEBUG << "listing jobs for all printers" << endl; + showJobs(0, query == "completed_jobs"); + return; + } + + int p = printer.find('?'); + if (p != -1) + { + query = printer.mid(p+1); + printer = printer.left(p); + } + + PRINT_DEBUG << "opening " << url.url() << endl; + PRINT_DEBUG << "extracted printer name = " << printer << endl; + + KMManager::self()->printerList(false); + mprinter = KMManager::self()->findPrinter(printer); + if (!mprinter) + path = locateData(printer.isEmpty() ? group : printer); + + if (elems.count() > 2 || (path.isEmpty() && group != "printers" && group != "classes" && group != "specials") + || (mprinter == 0 && path.isEmpty())) + { + error(KIO::ERR_DOES_NOT_EXIST, url.path()); + return; + } + + if (mprinter != 0) + { + if (!query.isEmpty() && query != "general") + { + if (query == "jobs") + showJobs(mprinter, false); + else if (query == "completed_jobs") + showJobs(mprinter, true); + else if (query == "driver") + showDriver(mprinter); + else + error(KIO::ERR_MALFORMED_URL, KURL::decode_string(elems[1])); + } + else if (group == "printers" && mprinter->isPrinter()) + showPrinterInfo(mprinter); + else if (group == "classes" && mprinter->isClass(true)) + showClassInfo(mprinter); + else if (group == "specials" && mprinter->isSpecial()) + showSpecialInfo(mprinter); + else + error(KIO::ERR_INTERNAL, i18n("Unable to determine object type for %1.").arg(printer)); + } + else if (!path.isEmpty()) + showData(path); + else + error(KIO::ERR_INTERNAL, i18n("Unable to determine source type for %1.").arg(printer)); +} + +void KIO_Print::showPrinterInfo(KMPrinter *printer) +{ + if (!KMManager::self()->completePrinter(printer)) + error(KIO::ERR_INTERNAL, i18n("Unable to retrieve printer information for %1.").arg(printer->name())); + else + { + mimeType("text/html"); + + QString content; + if (!loadTemplate(QString::fromLatin1("printer.template"), content)) + { + error(KIO::ERR_INTERNAL, i18n("Unable to load template %1").arg("printer.template")); + return; + } + + content = content + .arg(i18n("Properties of %1").arg(printer->printerName())) + .arg(i18n("Properties of %1").arg(printer->printerName())) + .arg(buildMenu(QStringList::split('|', i18n("General|Driver|Active jobs|Completed jobs"), false), + QStringList::split('|', "?general|?driver|?jobs|?completed_jobs", true), + 0)) + .arg(QString::null) + .arg(printer->pixmap()) + .arg(printer->name()) + .arg(i18n("General Properties")) + .arg(i18n("Type")).arg(printer->isRemote() ? i18n("Remote") : i18n("Local")) + .arg(i18n("State")).arg(printer->stateString()) + .arg(i18n("Location")).arg(printer->location()) + .arg(i18n("Description")).arg(printer->description()) + .arg(i18n("URI")).arg(printer->uri().prettyURL()) + .arg(i18n("Interface (Backend)")).arg(printer->device()) + .arg(i18n("Driver")) + .arg(i18n("Manufacturer")).arg(printer->manufacturer()) + .arg(i18n("Model")).arg(printer->model()) + .arg(i18n("Driver Information")).arg(printer->driverInfo()); + + data(content.local8Bit()); + finished(); + } +} + +void KIO_Print::showClassInfo(KMPrinter *printer) +{ + if (!KMManager::self()->completePrinter(printer)) + error(KIO::ERR_INTERNAL, i18n("Unable to retrieve class information for %1.").arg(printer->name())); + else + { + mimeType("text/html"); + + QString content; + if (!loadTemplate(QString::fromLatin1("class.template"), content)) + { + error(KIO::ERR_INTERNAL, i18n("Unable to load template %1").arg("class.template")); + return; + } + + QString memberContent("<ul>\n"); + QStringList members(printer->members()); + for (QStringList::ConstIterator it=members.begin(); it!=members.end(); ++it) + { + memberContent.append(QString::fromLatin1("<li><a href=\"print:/printers/%1\">%2</a></li>\n").arg(*it).arg(*it)); + } + memberContent.append("</ul>\n"); + + QString typeContent = (printer->isImplicit() ? i18n("Implicit") : (printer->isRemote() ? i18n("Remote") : i18n("Local"))); + + content = content + .arg(i18n("Properties of %1").arg(printer->printerName())) + .arg(i18n("Properties of %1").arg(printer->printerName())) + .arg(buildMenu(QStringList::split('|', i18n("General|Active jobs|Completed jobs"), false), + QStringList::split('|', "?general|?jobs|?completed_jobs", true), + 0)) + .arg(QString::null) + .arg(printer->pixmap()) + .arg(printer->name()) + .arg(i18n("General Properties")) + .arg(i18n("Type")).arg(typeContent) + .arg(i18n("State")).arg(printer->stateString()) + .arg(i18n("Location")).arg(printer->location()) + .arg(i18n("Description")).arg(printer->description()) + .arg(i18n("URI")).arg(printer->uri().prettyURL()) + .arg(i18n("Members")).arg(memberContent); + + data(content.local8Bit()); + finished(); + } +} + +void KIO_Print::showSpecialInfo(KMPrinter *printer) +{ + mimeType("text/html"); + + QString content; + if (!loadTemplate(QString::fromLatin1("pseudo.template"), content)) + { + error(KIO::ERR_INTERNAL, i18n("Unable to load template %1").arg("pseudo.template")); + return; + } + + QString reqContent("<ul>\n"); + QStringList requirements = QStringList::split(",", printer->option("kde-special-require"), false); + for (QStringList::ConstIterator it=requirements.begin(); it!=requirements.end(); ++it) + reqContent += ("<li>" + (*it) + "</li>\n"); + reqContent.append("</ul>\n"); + + content = content + .arg(i18n("Properties of %1").arg(printer->printerName())) + .arg(i18n("Properties of %1").arg(printer->printerName())) + .arg(buildMenu(QStringList::split('|', i18n("General"), false), + QStringList::split('|', "?general", true), + 0)) + .arg(QString::null) + .arg(printer->pixmap()) + .arg(printer->name()) + .arg(i18n("General Properties")) + .arg(i18n("Location")).arg(printer->location()) + .arg(i18n("Description")).arg(printer->description()) + .arg(i18n("Requirements")).arg(reqContent) + .arg(i18n("Command Properties")) + .arg(i18n("Command")).arg("<tt>"+printer->option("kde-special-command")+"</tt>") + .arg(i18n("Use Output File")).arg(printer->option("kde-special-file") == "1" ? i18n("Yes") : i18n("No")) + .arg(i18n("Default Extension")).arg(printer->option("kde-special-extension")); + + data(content.local8Bit()); + finished(); +} + +bool KIO_Print::loadTemplate(const QString& filename, QString& buffer) +{ + QFile f(locate("data", QString::fromLatin1("kdeprint/template/")+filename)); + if (f.exists() && f.open(IO_ReadOnly)) + { + QTextStream t(&f); + buffer = t.read(); + return true; + } + else + { + buffer = QString::null; + return false; + } +} + +void KIO_Print::showData(const QString& pathname) +{ + PRINT_DEBUG << "sending data: " << pathname << endl; + QFile f(pathname); + if (f.exists() && f.open(IO_ReadOnly)) + { + QByteArray arr(f.readAll()); + mimeType(KMimeType::findByURL(KURL(pathname), 0, true, true)->name()); + data(arr); + finished(); + } + else + { + PRINT_DEBUG << "file not found" << endl; + error(KIO::ERR_DOES_NOT_EXIST, pathname); + } +} + +/** + * Locate a data in this order: + * - $KDEDIR/share/apps/kdeprint/template/ + * - as a desktop icon + */ +QString KIO_Print::locateData(const QString& item) +{ + QString path = locate("data", "kdeprint/template/"+item); + if (path.isEmpty()) + path = KGlobal::iconLoader()->iconPath(item, KIcon::Desktop, true); + return path; +} + +void KIO_Print::showJobs(KMPrinter *prt, bool completed) +{ + mimeType("text/html"); + + // Add the printer to the current list in the job manager + KMJobManager::JobType type = (completed ? KMJobManager::CompletedJobs : KMJobManager::ActiveJobs); + KMJobManager *mgr = KMJobManager::self(); + if (prt) + mgr->addPrinter(prt->printerName(), type); + else + { + QPtrListIterator<KMPrinter> pit(*(KMManager::self()->printerList())); + for (; pit.current(); ++pit) + if (pit.current()->isVirtual() || pit.current()->isSpecial()) + continue; + else + mgr->addPrinter(pit.current()->printerName(), type); + } + + QString content; + if (!loadTemplate(QString::fromLatin1("jobs.template"), content)) + { + error(KIO::ERR_INTERNAL, i18n("Unable to load template %1").arg("pseudo.template")); + return; + } + + if (prt) + { + content = content + .arg(i18n("Jobs of %1").arg(prt->printerName())) + .arg(i18n("Jobs of %1").arg(prt->printerName())) + .arg(prt->isClass () ? + buildMenu(QStringList::split('|', i18n("General|Active jobs|Completed jobs"), false), + QStringList::split('|', "?general|?jobs|?completed_jobs", true), + (completed ? 2 : 1)) : + buildMenu(QStringList::split('|', i18n("General|Driver|Active jobs|Completed jobs"), false), + QStringList::split('|', "?general|?driver|?jobs|?completed_jobs", true), + (completed ? 3 : 2))) + .arg(QString::null) + .arg(prt->pixmap()) + .arg(prt->printerName()); + } + else + { + content = content + .arg(i18n("All jobs")) + .arg(buildMenu(QStringList::split('|', i18n("Active jobs|Completed jobs"), false), + QStringList::split('|', "?jobs|?completed_jobs", true), + (completed ? 1 : 0))) + .arg("fileprint") + .arg(i18n("All jobs")); + } + content = content.arg(i18n("ID")).arg(i18n("Owner")).arg(i18n("Printer")).arg(i18n("Name")).arg(i18n("State")); + + QString jobContent, cellContent("<td>%1</td>\n"); + QPtrListIterator<KMJob> it(mgr->jobList()); + bool flag(true); + for (; it.current(); ++it, flag = !flag) + { + jobContent.append("<tr class=\"").append(flag ? "contentyellow" : "contentwhite").append("\">\n"); + jobContent.append(cellContent.arg(it.current()->id())); + jobContent.append(cellContent.arg(it.current()->owner())); + jobContent.append(cellContent.arg(it.current()->printer())); + jobContent.append(cellContent.arg(it.current()->name())); + jobContent.append(cellContent.arg(it.current()->stateString())); + jobContent.append("</tr>\n"); + } + content = content.arg(jobContent); + + // remove the current printer to the current list in the job manager + if (prt) + mgr->removePrinter(prt->printerName(), type); + else + { + QPtrListIterator<KMPrinter> pit(*(KMManager::self()->printerList())); + for (; pit.current(); ++pit) + if (pit.current()->isVirtual() || pit.current()->isSpecial()) + continue; + else + mgr->removePrinter(pit.current()->printerName(), type); + } + + data(content.local8Bit()); + finished(); +} + +void KIO_Print::showDriver(KMPrinter *prt) +{ + mimeType("text/html"); + + QString content; + if (!loadTemplate(QString::fromLatin1("driver.template"), content)) + { + error(KIO::ERR_INTERNAL, i18n("Unable to load template %1").arg("pseudo.template")); + return; + } + + DrMain *driver = KMManager::self()->loadPrinterDriver(prt, true); + content = content + .arg(i18n("Driver of %1").arg(prt->printerName())) + .arg(i18n("Driver of %1").arg(prt->printerName())) + .arg(buildMenu(QStringList::split('|', i18n("General|Driver|Active jobs|Completed jobs"), false), + QStringList::split('|', "?general|?driver|?jobs|?completed_jobs", true), + 1)) + .arg(QString::null) + .arg(prt->pixmap()) + .arg(prt->printerName() + " (" + (driver ? driver->get("text") : i18n("No driver found")) + ")"); + + if (driver) + content = content.arg(buildGroupTable(driver, false)); + else + content = content.arg(QString::null); + + data(content.local8Bit()); + finished(); +} + +#include "kio_print.moc" |