~ubuntu-branches/ubuntu/lucid/kdebase/lucid

« back to all changes in this revision

Viewing changes to kdeprint/slave/kio_print.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2008-05-27 12:09:48 UTC
  • mfrom: (1.1.13 upstream)
  • Revision ID: james.westby@ubuntu.com-20080527120948-dottsyd5rcwhzd36
Tags: 4:4.0.80-1ubuntu1
* Merge with Debian
 - remove 97_fix_target_link_libraries.diff
 - Add replaces/conflicts on -kde4 packages

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *  This file is part of the KDE libraries
3
 
 *  Copyright (c) 2001 Michael Goffioul <kdeprint@swing.be>
4
 
 *
5
 
 *  This library is free software; you can redistribute it and/or
6
 
 *  modify it under the terms of the GNU Library General Public
7
 
 *  License version 2 as published by the Free Software Foundation.
8
 
 *
9
 
 *  This library is distributed in the hope that it will be useful,
10
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 
 *  Library General Public License for more details.
13
 
 *
14
 
 *  You should have received a copy of the GNU Library General Public License
15
 
 *  along with this library; see the file COPYING.LIB.  If not, write to
16
 
 *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17
 
 *  Boston, MA 02110-1301, USA.
18
 
 **/
19
 
 
20
 
#include "kio_print.h"
21
 
#include <kdeprint/kmprinter.h>
22
 
#include <kdeprint/kmmanager.h>
23
 
#include <kdeprint/kmjobmanager.h>
24
 
#include <kdeprint/kmjob.h>
25
 
#include <kdeprint/driver.h>
26
 
 
27
 
#include <qfile.h>
28
 
#include <qtextstream.h>
29
 
#include <klocale.h>
30
 
#include <kdebug.h>
31
 
#include <kinstance.h>
32
 
#include <kio/global.h>
33
 
#include <kstandarddirs.h>
34
 
#include <kiconloader.h>
35
 
#include <kmimetype.h>
36
 
#include <kio/job.h>
37
 
#include <kapplication.h>
38
 
#include <kcmdlineargs.h>
39
 
#include <kaboutdata.h>
40
 
#include <kprocess.h>
41
 
#include <ktempfile.h>
42
 
#include <qfile.h>
43
 
#include <qdom.h>
44
 
 
45
 
#include <stdio.h>
46
 
#include <stdlib.h>
47
 
#include <sys/stat.h>
48
 
 
49
 
#define PRINT_DEBUG     kdDebug(7019) << "kio_print: "
50
 
 
51
 
extern "C"
52
 
{
53
 
        int KDE_EXPORT kdemain(int argc, char **argv);
54
 
}
55
 
 
56
 
void addAtom(KIO::UDSEntry& entry, unsigned int ID, long l, const QString& s = QString::null)
57
 
{
58
 
        KIO::UDSAtom    atom;
59
 
        atom.m_uds = ID;
60
 
        atom.m_long = l;
61
 
        atom.m_str = s;
62
 
        entry.append(atom);
63
 
}
64
 
 
65
 
static void createDirEntry(KIO::UDSEntry& entry, const QString& name, const QString& url, const QString& mime)
66
 
{
67
 
        entry.clear();
68
 
        addAtom(entry, KIO::UDS_NAME, 0, name);
69
 
        addAtom(entry, KIO::UDS_FILE_TYPE, S_IFDIR);
70
 
        addAtom(entry, KIO::UDS_ACCESS, 0500);
71
 
        addAtom(entry, KIO::UDS_MIME_TYPE, 0, mime);
72
 
        addAtom(entry, KIO::UDS_URL, 0, url);
73
 
        PRINT_DEBUG << "creating dir entry url=" << url << " mimetype=" << mime << endl;
74
 
        addAtom(entry, KIO::UDS_SIZE, 0);
75
 
        //addAtom(entry, KIO::UDS_GUESSED_MIME_TYPE, 0, "application/octet-stream");
76
 
}
77
 
 
78
 
static void createFileEntry(KIO::UDSEntry& entry, const QString& name, const QString& url, const QString& mime)
79
 
{
80
 
        entry.clear();
81
 
        addAtom(entry, KIO::UDS_NAME, 0, name);
82
 
        addAtom(entry, KIO::UDS_FILE_TYPE, S_IFREG);
83
 
        addAtom(entry, KIO::UDS_URL, 0, url);
84
 
        addAtom(entry, KIO::UDS_ACCESS, 0400);
85
 
        addAtom(entry, KIO::UDS_MIME_TYPE, 0, mime);
86
 
        addAtom(entry, KIO::UDS_SIZE, 0);
87
 
        addAtom(entry, KIO::UDS_GUESSED_MIME_TYPE, 0, "application/octet-stream");
88
 
}
89
 
 
90
 
QString buildMenu(const QStringList& items, const QStringList& links, int active)
91
 
{
92
 
        if (items.count() == 0 || items.count() != links.count())
93
 
                return QString("<td height=20 class=\"menu\">&nbsp;</td>");
94
 
 
95
 
        QString s;
96
 
        int     index = 0;
97
 
        for (QStringList::ConstIterator it1=items.begin(), it2=links.begin(); it1!=items.end() && it2!=links.end(); ++it1, ++it2, index++)
98
 
        {
99
 
                if (index == active)
100
 
                        s.append("<td height=20 class=\"menuactive\">&nbsp; ").append(*it1).append("&nbsp;</td>");
101
 
                else
102
 
                        s.append("<td height=20 class=\"menu\">&nbsp; <a class=\"menu\" href=\"").append(*it2).append("\">").append(*it1).append("</a>&nbsp;</td>");
103
 
                if ((unsigned int)index < items.count()-1)
104
 
                        s.append("<td height=20 class=\"menu\">|</td>");
105
 
        }
106
 
        return s;
107
 
}
108
 
 
109
 
QString buildOptionRow(DrBase *opt, bool f)
110
 
{
111
 
        QString s("<tr class=\"%1\"><td width=\"41%\">%1</td><td width=\"59%\">%1</td></tr>\n");
112
 
        s = s.arg(f ? "contentwhite" : "contentyellow").arg(opt->get("text")).arg(opt->prettyText());
113
 
        return s;
114
 
}
115
 
 
116
 
QString buildGroupTable(DrGroup *grp, bool showHeader = true)
117
 
{
118
 
        QString s("<tr class=\"top\"><td colspan=\"2\">%1</td></tr>\n");
119
 
        if (showHeader)
120
 
                s = s.arg(grp->get("text"));
121
 
        else
122
 
                s = QString::null;
123
 
 
124
 
        QPtrListIterator<DrBase>        oit(grp->options());
125
 
        bool    f(false);
126
 
        for (; oit.current(); ++oit, f = !f)
127
 
                s.append(buildOptionRow(oit.current(), f));
128
 
 
129
 
        QPtrListIterator<DrGroup>       git(grp->groups());
130
 
        for (; git.current(); ++git)
131
 
                s.append(buildGroupTable(git.current()));
132
 
 
133
 
        return s;
134
 
}
135
 
 
136
 
int kdemain(int argc, char **argv)
137
 
{
138
 
        KInstance  instance("kio_print");
139
 
 
140
 
        PRINT_DEBUG << "starting ioslave" << endl;
141
 
        if (argc != 4)
142
 
        {
143
 
                fprintf(stderr, "Usage: kio_print protocol domain-socket1 domain-socket2\n");
144
 
                exit(-1);
145
 
        }
146
 
 
147
 
        /* create fake KApplicatiom object, needed for job stuffs */
148
 
        KAboutData about( "kio_print", "kio_print", "fake_version", 
149
 
                        "KDEPrint IO slave", KAboutData::License_GPL, "(c) 2003, Michael Goffioul" );
150
 
        KCmdLineArgs::init( &about );
151
 
        KApplication app;
152
 
 
153
 
        KIO_Print        slave(argv[2], argv[3]);
154
 
        slave.dispatchLoop();
155
 
 
156
 
        PRINT_DEBUG << "done" << endl;
157
 
        return 0;
158
 
}
159
 
 
160
 
KIO_Print::KIO_Print(const QCString& pool, const QCString& app)
161
 
: KIO::SlaveBase("print", pool, app)
162
 
{
163
 
}
164
 
 
165
 
void KIO_Print::listDir(const KURL& url)
166
 
{
167
 
        if ( url.protocol() == "printdb" )
168
 
        {
169
 
                listDirDB( url );
170
 
                return;
171
 
        }
172
 
 
173
 
        QStringList     path = QStringList::split('/', url.path(), false);
174
 
 
175
 
        PRINT_DEBUG << "listing " << url.path() << endl;
176
 
        QString group = path[0].lower();
177
 
        if (path.count() == 0)
178
 
                listRoot();
179
 
        else if (path.count() == 1 && group != "manager" && group != "jobs")
180
 
        {
181
 
                PRINT_DEBUG << "listing group " << path[0] << endl;
182
 
 
183
 
                int     mask;
184
 
                QString mimeType;
185
 
                KIO::UDSEntry   entry;
186
 
 
187
 
                if (group == "printers")
188
 
                {
189
 
                        mask = KMPrinter::Printer;
190
 
                        mimeType = "print/printer";
191
 
                }
192
 
                else if (group == "classes")
193
 
                {
194
 
                        mask = KMPrinter::Class | KMPrinter::Implicit;
195
 
                        mimeType = "print/class";
196
 
                }
197
 
                else if (group == "specials")
198
 
                {
199
 
                        mask = KMPrinter::Special;
200
 
                        mimeType = "print/printer";
201
 
                }
202
 
                else
203
 
                {
204
 
                        error(KIO::ERR_DOES_NOT_EXIST, url.url());
205
 
                        return;
206
 
                }
207
 
 
208
 
                QPtrListIterator<KMPrinter>     it(*(KMManager::self()->printerList()));
209
 
                for (;it.current();++it)
210
 
                {
211
 
                        if (!(it.current()->type() & mask) || !it.current()->instanceName().isEmpty())
212
 
                        {
213
 
                                PRINT_DEBUG << "rejecting " << it.current()->name() << endl;
214
 
                                continue;
215
 
                        }
216
 
 
217
 
                        //createFileEntry(entry, it.current()->name(), ("print:/"+path[0]+"/"+it.current()->name()), mimeType, "text/html", S_IFDIR);
218
 
                        createDirEntry(entry, it.current()->name(), ("print:/"+group+"/"+KURL::encode_string_no_slash(it.current()->name())), mimeType);
219
 
                        PRINT_DEBUG << "accepting " << it.current()->name() << endl;
220
 
                        listEntry(entry, false);
221
 
                }
222
 
 
223
 
                listEntry(KIO::UDSEntry(), true);
224
 
                finished();
225
 
        }
226
 
        else
227
 
        {
228
 
                //error(KIO::ERR_UNSUPPORTED_ACTION, i18n("Unsupported path %1").arg(url.path()));
229
 
                // better do nothing
230
 
                listEntry(KIO::UDSEntry(), true);
231
 
                totalSize(0);
232
 
                finished();
233
 
        }
234
 
}
235
 
 
236
 
void KIO_Print::listRoot()
237
 
{
238
 
        PRINT_DEBUG << "listing root entry" << endl;
239
 
 
240
 
        KIO::UDSEntry   entry;
241
 
 
242
 
        // Classes entry
243
 
        createDirEntry(entry, i18n("Classes"), "print:/classes", "print/folder");
244
 
        listEntry(entry, false);
245
 
 
246
 
        // Printers entry
247
 
        createDirEntry(entry, i18n("Printers"), "print:/printers", "print/folder");
248
 
        listEntry(entry, false);
249
 
 
250
 
        // Specials entry
251
 
        createDirEntry(entry, i18n("Specials"), "print:/specials", "print/folder");
252
 
        listEntry(entry, false);
253
 
 
254
 
        // Management entry
255
 
        //createFileEntry(entry, i18n("Manager"), "print:/manager", "print/manager", QString::null, S_IFDIR);
256
 
        createDirEntry(entry, i18n("Manager"), "print:/manager", "print/manager");
257
 
        listEntry(entry, false);
258
 
 
259
 
        // Jobs entry
260
 
        createDirEntry(entry, i18n("Jobs"), "print:/jobs", "print/jobs");
261
 
        listEntry(entry, false);
262
 
 
263
 
        // finish
264
 
        totalSize(4);
265
 
        listEntry(entry, true);
266
 
        finished();
267
 
}
268
 
 
269
 
void KIO_Print::listDirDB( const KURL& url )
270
 
{
271
 
        PRINT_DEBUG << "listDirDB: " << url << endl;
272
 
 
273
 
        QStringList pathComps = QStringList::split( '/', url.path(), false );
274
 
        KURL remUrl;
275
 
 
276
 
        remUrl.setProtocol( "http" );
277
 
        remUrl.setHost( url.host() );
278
 
        remUrl.setPort( url.port() );
279
 
        remUrl.setPath( "/list-data.cgi" );
280
 
        switch ( pathComps.size() )
281
 
        {
282
 
                case 0: /* list manufacturers */
283
 
                        remUrl.addQueryItem( "type", "makes" );
284
 
                        break;
285
 
                case 1: /* list printers for the given manufacturer */
286
 
                        remUrl.addQueryItem( "type", "printers" );
287
 
                        remUrl.addQueryItem( "make", pathComps[ 0 ] );
288
 
                        break;
289
 
                case 2: /* list drivers for given printer */
290
 
                        remUrl.addQueryItem( "type", "drivers" );
291
 
                        remUrl.addQueryItem( "printer", pathComps[ 1 ] );
292
 
                        break;
293
 
                default:
294
 
                        error( KIO::ERR_UNSUPPORTED_ACTION, "Not implemented" );
295
 
                        return;
296
 
        }
297
 
        remUrl.addQueryItem( "format", "xml" );
298
 
 
299
 
        if ( getDBFile( remUrl ) )
300
 
        {
301
 
                QDomDocument doc;
302
 
                if ( doc.setContent( &m_httpBuffer, false ) )
303
 
                {
304
 
                        QDomNodeList l;
305
 
                        KIO::UDSEntry entry;
306
 
                        switch ( pathComps.size() )
307
 
                        {
308
 
                                case 0:
309
 
                                        l = doc.documentElement().elementsByTagName( "make" );
310
 
                                        for ( unsigned int i=0; i<l.count(); i++ )
311
 
                                        {
312
 
                                                QString make = l.item( i ).toElement().text();
313
 
                                                KURL makeUrl = url;
314
 
                                                makeUrl.addPath( "/" + make );
315
 
                                                createDirEntry( entry, make, makeUrl.url(), "print/folder" );
316
 
                                                listEntry( entry, false );
317
 
                                                PRINT_DEBUG << "make: " << make << endl;
318
 
                                        }
319
 
                                        break;
320
 
                                case 1:
321
 
                                        l = doc.documentElement().elementsByTagName( "printer" );
322
 
                                        for ( unsigned int i=0; i<l.count(); i++ )
323
 
                                        {
324
 
                                                QString ID, name;
325
 
                                                for ( QDomNode n=l.item( i ).firstChild(); !n.isNull(); n=n.nextSibling() )
326
 
                                                {
327
 
                                                        QDomElement e = n.toElement();
328
 
                                                        if ( e.tagName() == "id" )
329
 
                                                                ID = e.text();
330
 
                                                        else if ( e.tagName() == "model" )
331
 
                                                                name = e.text();
332
 
                                                }
333
 
                                                if ( !ID.isEmpty() && !name.isEmpty() )
334
 
                                                {
335
 
                                                        KURL printerUrl = url;
336
 
                                                        printerUrl.addPath( "/" + ID );
337
 
                                                        createDirEntry( entry, name, printerUrl.url(), "print/printermodel" );
338
 
                                                        listEntry( entry, false );
339
 
                                                        PRINT_DEBUG << "printer: " << ID << endl;
340
 
                                                }
341
 
                                        }
342
 
                                        break;
343
 
                                case 2:
344
 
                                        l = doc.documentElement().elementsByTagName( "driver" );
345
 
                                        for ( unsigned int i=0; i<l.count(); i++ )
346
 
                                        {
347
 
                                                QString driver = l.item( i ).toElement().text();
348
 
                                                KURL driverUrl = url;
349
 
                                                driverUrl.addPath( "/" + driver );
350
 
                                                createFileEntry( entry, driver, driverUrl.url(), "print/driver" );
351
 
                                                listEntry( entry, false );
352
 
                                                PRINT_DEBUG << "driver: " << driver << endl;
353
 
                                        }
354
 
                                        break;
355
 
                                default:
356
 
                                        error( KIO::ERR_UNSUPPORTED_ACTION, "Not implemented" );
357
 
                                        return;
358
 
                        }
359
 
                        listEntry( KIO::UDSEntry(), true );
360
 
                        finished();
361
 
                }
362
 
                else
363
 
                {
364
 
                        if ( m_httpBuffer.buffer().size() == 0 )
365
 
                                error( KIO::ERR_INTERNAL, i18n( "Empty data received (%1)." ).arg( url.host() ) );
366
 
                        else
367
 
                                error( KIO::ERR_INTERNAL, i18n( "Corrupted/incomplete data or server error (%1)." ).arg( url.host() ) );
368
 
                }
369
 
        }
370
 
        /*
371
 
         * If error occured while downloading, error has been called by
372
 
         * getDBFile. No need for a "else" statement.
373
 
         */
374
 
}
375
 
 
376
 
void KIO_Print::stat(const KURL& url)
377
 
{
378
 
        if ( url.protocol() == "printdb" )
379
 
        {
380
 
                statDB( url );
381
 
                return;
382
 
        }
383
 
 
384
 
        PRINT_DEBUG << "stat: " << url.url() << endl;
385
 
        QStringList     path = QStringList::split('/', url.encodedPathAndQuery(-1), false);
386
 
        KIO::UDSEntry   entry;
387
 
        QString mime;
388
 
        bool err(false);
389
 
 
390
 
        PRINT_DEBUG << "path components: " << path.join(", ") << endl;
391
 
 
392
 
        switch (path.count())
393
 
        {
394
 
                case 0:
395
 
                        createDirEntry(entry, i18n("Print System"), "print:/", "print/folder");
396
 
                        break;
397
 
                case 1:
398
 
                        if (path[0].lower() == "classes")
399
 
                                createDirEntry(entry, i18n("Classes"), "print:/classes", "print/folder");
400
 
                        else if (path[0].lower() == "printers")
401
 
                                createDirEntry(entry, i18n("Printers"), "print:/printers", "print/folder");
402
 
                        else if (path[0].lower() == "specials")
403
 
                                createDirEntry(entry, i18n("Specials"), "print:/specials", "print/folder");
404
 
                        else if (path[0].lower() == "manager")
405
 
                                createDirEntry(entry, i18n("Manager"), "print:/manager", "print/manager");
406
 
                        else if (path[0].lower().startsWith("jobs"))
407
 
                                createFileEntry(entry, i18n("Jobs"), url.url(), "text/html");
408
 
                        else
409
 
                                err = true;
410
 
                        break;
411
 
                case 2:
412
 
                        if (path[0].lower() == "printers")
413
 
                                mime = "print/printer";
414
 
                        else if (path[0].lower() == "classes")
415
 
                                mime = "print/class";
416
 
                        else if (path[0].lower() == "specials")
417
 
                                mime = "print/printer";
418
 
                        else
419
 
                                err = true;
420
 
                        createFileEntry(entry, path[1], "print:/"+path[0]+"/"+path[1], "text/html");
421
 
                        break;
422
 
        }
423
 
 
424
 
        if (!err)
425
 
        {
426
 
                statEntry(entry);
427
 
                finished();
428
 
        }
429
 
        else
430
 
                error(KIO::ERR_DOES_NOT_EXIST, url.path());
431
 
}
432
 
 
433
 
void KIO_Print::statDB( const KURL& url )
434
 
{
435
 
        PRINT_DEBUG << "statDB: " << url << endl;
436
 
        KIO::UDSEntry entry;
437
 
        QStringList pathComps = QStringList::split( '/', url.path(), false );
438
 
        if ( pathComps.size() == 3 )
439
 
                createFileEntry( entry, i18n( "Printer driver" ), url.url(), "print/driver" );
440
 
        else
441
 
                createDirEntry( entry, i18n( "On-line printer driver database" ), url.url(), "inode/directory" );
442
 
        statEntry( entry );
443
 
        finished();
444
 
}
445
 
 
446
 
bool KIO_Print::getDBFile( const KURL& src )
447
 
{
448
 
        PRINT_DEBUG << "downloading " << src.url() << endl;
449
 
 
450
 
        /* re-initialize the internal buffer */
451
 
        if ( m_httpBuffer.isOpen() )
452
 
                m_httpBuffer.close();
453
 
        m_httpError = 0;
454
 
        m_httpBuffer.open( IO_WriteOnly|IO_Truncate ); // be sure to erase the existing data
455
 
 
456
 
        /* start the transfer job */
457
 
        KIO::TransferJob *job = KIO::get( src, false, false );
458
 
        connect( job, SIGNAL( result( KIO::Job* ) ), SLOT( slotResult( KIO::Job* ) ) );
459
 
        connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ), SLOT( slotData( KIO::Job*, const QByteArray& ) ) );
460
 
        connect( job, SIGNAL( totalSize( KIO::Job*, KIO::filesize_t ) ), SLOT( slotTotalSize( KIO::Job*, KIO::filesize_t ) ) );
461
 
        connect( job, SIGNAL( processedSize( KIO::Job*, KIO::filesize_t ) ), SLOT( slotProcessedSize( KIO::Job*, KIO::filesize_t ) ) );
462
 
        kapp->enter_loop();
463
 
        m_httpBuffer.close();
464
 
 
465
 
        /* return the result */
466
 
        if ( m_httpError != 0 )
467
 
                error( m_httpError, m_httpErrorTxt );
468
 
        return ( m_httpError == 0 );
469
 
}
470
 
 
471
 
void KIO_Print::getDB( const KURL& url )
472
 
{
473
 
        PRINT_DEBUG << "downloading PPD file for " << url.url() << endl;
474
 
 
475
 
        QStringList pathComps = QStringList::split( '/', url.path(), false );
476
 
        if ( pathComps.size() != 3 )
477
 
                error( KIO::ERR_MALFORMED_URL, url.url() );
478
 
        else
479
 
        {
480
 
                KURL remUrl;
481
 
 
482
 
                remUrl.setProtocol( "http" );
483
 
                remUrl.setHost( url.host() );
484
 
                remUrl.setPath( "/ppd-o-matic.cgi" );
485
 
                remUrl.addQueryItem( "driver", pathComps[ 2 ] );
486
 
                remUrl.addQueryItem( "printer", pathComps[ 1 ] );
487
 
 
488
 
                if ( getDBFile( remUrl ) )
489
 
                {
490
 
                        mimeType( "text/plain" );
491
 
                        data( m_httpBuffer.buffer() );
492
 
                        finished();
493
 
                }
494
 
                /*
495
 
                 * no "else" statement needed, the error has
496
 
                 * already been emitted by the getDBFile function
497
 
                 */
498
 
        }
499
 
}
500
 
 
501
 
void KIO_Print::slotResult( KIO::Job *j )
502
 
{
503
 
        /*
504
 
         * store slave results for later user (job gets deleted 
505
 
         * after this function). Store only if no other error
506
 
         * occured previously (when writing to the buffer).
507
 
         */
508
 
        if ( m_httpError == 0 )
509
 
        {
510
 
                m_httpError = j->error();
511
 
                m_httpErrorTxt = j->errorText();
512
 
        }
513
 
        kapp->exit_loop();
514
 
}
515
 
 
516
 
void KIO_Print::slotData( KIO::Job *j, const QByteArray& d )
517
 
{
518
 
        PRINT_DEBUG << "HTTP data received (size=" << d.size() << ")" << endl;
519
 
        if ( d.size() > 0 )
520
 
        {
521
 
                int len = m_httpBuffer.writeBlock( d );
522
 
                if ( len == -1 || len != ( int )d.size() )
523
 
                {
524
 
                        m_httpError = KIO::ERR_INTERNAL;
525
 
                        m_httpErrorTxt = "Unable to write to the internal buffer.";
526
 
                        j->kill( false );
527
 
                }
528
 
        }
529
 
}
530
 
 
531
 
void KIO_Print::slotTotalSize( KIO::Job*, KIO::filesize_t sz )
532
 
{
533
 
        totalSize( sz );
534
 
}
535
 
 
536
 
void KIO_Print::slotProcessedSize( KIO::Job*, KIO::filesize_t sz )
537
 
{
538
 
        processedSize( sz );
539
 
}
540
 
 
541
 
void KIO_Print::get(const KURL& url)
542
 
{
543
 
        if ( url.protocol() == "printdb" )
544
 
        {
545
 
                getDB( url );
546
 
                return;
547
 
        }
548
 
 
549
 
        QStringList     elems = QStringList::split('/', url.encodedPathAndQuery(), false);
550
 
        QString         group(elems[0].lower()), printer(KURL::decode_string(elems[1])), path, query;
551
 
        KMPrinter       *mprinter(0);
552
 
 
553
 
        if (group == "manager")
554
 
        {
555
 
                PRINT_DEBUG << "opening print management part" << endl;
556
 
 
557
 
                mimeType("print/manager");
558
 
                finished();
559
 
                return;
560
 
        }
561
 
 
562
 
        PRINT_DEBUG << "getting " << url.url() << endl;
563
 
 
564
 
        if (group.startsWith("jobs"))
565
 
        {
566
 
                int     p = group.find('?');
567
 
                if (p != -1)
568
 
                        query = group.mid(p+1);
569
 
                if (!query.isEmpty() && query != "jobs" && query != "completed_jobs")
570
 
                {
571
 
                        error(KIO::ERR_MALFORMED_URL, QString::null);
572
 
                        return;
573
 
                }
574
 
                PRINT_DEBUG << "listing jobs for all printers" << endl;
575
 
                showJobs(0, query == "completed_jobs");
576
 
                return;
577
 
        }
578
 
 
579
 
        int     p = printer.find('?');
580
 
        if (p != -1)
581
 
        {
582
 
                query = printer.mid(p+1);
583
 
                printer = printer.left(p);
584
 
        }
585
 
 
586
 
        PRINT_DEBUG << "opening " << url.url() << endl;
587
 
        PRINT_DEBUG << "extracted printer name = " << printer << endl;
588
 
 
589
 
        KMManager::self()->printerList(false);
590
 
        mprinter = KMManager::self()->findPrinter(printer);
591
 
        if (!mprinter)
592
 
                path = locateData(printer.isEmpty() ? group : printer);
593
 
 
594
 
        if (elems.count() > 2 || (path.isEmpty() && group != "printers" && group != "classes" && group != "specials")
595
 
            || (mprinter == 0 && path.isEmpty()))
596
 
        {
597
 
                error(KIO::ERR_DOES_NOT_EXIST, url.path());
598
 
                return;
599
 
        }
600
 
 
601
 
        if (mprinter != 0)
602
 
        {
603
 
                if (!query.isEmpty() && query != "general")
604
 
                {
605
 
                        if (query == "jobs")
606
 
                                showJobs(mprinter, false);
607
 
                        else if (query == "completed_jobs")
608
 
                                showJobs(mprinter, true);
609
 
                        else if (query == "driver")
610
 
                                showDriver(mprinter);
611
 
                        else
612
 
                                error(KIO::ERR_MALFORMED_URL, KURL::decode_string(elems[1]));
613
 
                }
614
 
                else if (group == "printers" && mprinter->isPrinter())
615
 
                        showPrinterInfo(mprinter);
616
 
                else if (group == "classes" && mprinter->isClass(true))
617
 
                        showClassInfo(mprinter);
618
 
                else if (group == "specials" && mprinter->isSpecial())
619
 
                        showSpecialInfo(mprinter);
620
 
                else
621
 
                        error(KIO::ERR_INTERNAL, i18n("Unable to determine object type for %1.").arg(printer));
622
 
        }
623
 
        else if (!path.isEmpty())
624
 
                showData(path);
625
 
        else
626
 
                error(KIO::ERR_INTERNAL, i18n("Unable to determine source type for %1.").arg(printer));
627
 
}
628
 
 
629
 
void KIO_Print::showPrinterInfo(KMPrinter *printer)
630
 
{
631
 
        if (!KMManager::self()->completePrinter(printer))
632
 
                error(KIO::ERR_INTERNAL, i18n("Unable to retrieve printer information for %1.").arg(printer->name()));
633
 
        else
634
 
        {
635
 
                mimeType("text/html");
636
 
 
637
 
                QString content;
638
 
                if (!loadTemplate(QString::fromLatin1("printer.template"), content))
639
 
                {
640
 
                        error(KIO::ERR_INTERNAL, i18n("Unable to load template %1").arg("printer.template"));
641
 
                        return;
642
 
                }
643
 
 
644
 
                content = content
645
 
                                 .arg(i18n("Properties of %1").arg(printer->printerName()))
646
 
                                 .arg(i18n("Properties of %1").arg(printer->printerName()))
647
 
                                 .arg(buildMenu(QStringList::split('|', i18n("General|Driver|Active jobs|Completed jobs"), false),
648
 
                                                         QStringList::split('|', "?general|?driver|?jobs|?completed_jobs", true),
649
 
                                                         0))
650
 
                                 .arg(QString::null)
651
 
                                 .arg(printer->pixmap())
652
 
                                 .arg(printer->name())
653
 
                                 .arg(i18n("General Properties"))
654
 
                                 .arg(i18n("Type")).arg(printer->isRemote() ? i18n("Remote") : i18n("Local"))
655
 
                                 .arg(i18n("State")).arg(printer->stateString())
656
 
                                 .arg(i18n("Location")).arg(printer->location())
657
 
                                 .arg(i18n("Description")).arg(printer->description())
658
 
                                 .arg(i18n("URI")).arg(printer->uri().prettyURL())
659
 
                                 .arg(i18n("Interface (Backend)")).arg(printer->device())
660
 
                                 .arg(i18n("Driver"))
661
 
                                 .arg(i18n("Manufacturer")).arg(printer->manufacturer())
662
 
                                 .arg(i18n("Model")).arg(printer->model())
663
 
                                 .arg(i18n("Driver Information")).arg(printer->driverInfo());
664
 
 
665
 
                data(content.local8Bit());
666
 
                finished();
667
 
        }
668
 
}
669
 
 
670
 
void KIO_Print::showClassInfo(KMPrinter *printer)
671
 
{
672
 
        if (!KMManager::self()->completePrinter(printer))
673
 
                error(KIO::ERR_INTERNAL, i18n("Unable to retrieve class information for %1.").arg(printer->name()));
674
 
        else
675
 
        {
676
 
                mimeType("text/html");
677
 
 
678
 
                QString content;
679
 
                if (!loadTemplate(QString::fromLatin1("class.template"), content))
680
 
                {
681
 
                        error(KIO::ERR_INTERNAL, i18n("Unable to load template %1").arg("class.template"));
682
 
                        return;
683
 
                }
684
 
 
685
 
                QString         memberContent("<ul>\n");
686
 
                QStringList     members(printer->members());
687
 
                for (QStringList::ConstIterator it=members.begin(); it!=members.end(); ++it)
688
 
                {
689
 
                        memberContent.append(QString::fromLatin1("<li><a href=\"print:/printers/%1\">%2</a></li>\n").arg(*it).arg(*it));
690
 
                }
691
 
                memberContent.append("</ul>\n");
692
 
 
693
 
                QString         typeContent = (printer->isImplicit() ? i18n("Implicit") : (printer->isRemote() ? i18n("Remote") : i18n("Local")));
694
 
 
695
 
                content = content
696
 
                                 .arg(i18n("Properties of %1").arg(printer->printerName()))
697
 
                                 .arg(i18n("Properties of %1").arg(printer->printerName()))
698
 
                                 .arg(buildMenu(QStringList::split('|', i18n("General|Active jobs|Completed jobs"), false),
699
 
                                                         QStringList::split('|', "?general|?jobs|?completed_jobs", true),
700
 
                                                         0))
701
 
                                 .arg(QString::null)
702
 
                                 .arg(printer->pixmap())
703
 
                                 .arg(printer->name())
704
 
                                 .arg(i18n("General Properties"))
705
 
                                 .arg(i18n("Type")).arg(typeContent)
706
 
                                 .arg(i18n("State")).arg(printer->stateString())
707
 
                                 .arg(i18n("Location")).arg(printer->location())
708
 
                                 .arg(i18n("Description")).arg(printer->description())
709
 
                                 .arg(i18n("URI")).arg(printer->uri().prettyURL())
710
 
                                 .arg(i18n("Members")).arg(memberContent);
711
 
 
712
 
                data(content.local8Bit());
713
 
                finished();
714
 
        }
715
 
}
716
 
 
717
 
void KIO_Print::showSpecialInfo(KMPrinter *printer)
718
 
{
719
 
        mimeType("text/html");
720
 
 
721
 
        QString content;
722
 
        if (!loadTemplate(QString::fromLatin1("pseudo.template"), content))
723
 
        {
724
 
                error(KIO::ERR_INTERNAL, i18n("Unable to load template %1").arg("pseudo.template"));
725
 
                return;
726
 
        }
727
 
 
728
 
        QString reqContent("<ul>\n");
729
 
        QStringList     requirements = QStringList::split(",", printer->option("kde-special-require"), false);
730
 
        for (QStringList::ConstIterator it=requirements.begin(); it!=requirements.end(); ++it)
731
 
                reqContent += ("<li>" + (*it) + "</li>\n");
732
 
        reqContent.append("</ul>\n");
733
 
 
734
 
        content = content
735
 
                         .arg(i18n("Properties of %1").arg(printer->printerName()))
736
 
                         .arg(i18n("Properties of %1").arg(printer->printerName()))
737
 
                         .arg(buildMenu(QStringList::split('|', i18n("General"), false),
738
 
                                                 QStringList::split('|', "?general", true),
739
 
                                                 0))
740
 
                         .arg(QString::null)
741
 
                         .arg(printer->pixmap())
742
 
                         .arg(printer->name())
743
 
                         .arg(i18n("General Properties"))
744
 
                         .arg(i18n("Location")).arg(printer->location())
745
 
                         .arg(i18n("Description")).arg(printer->description())
746
 
                         .arg(i18n("Requirements")).arg(reqContent)
747
 
                         .arg(i18n("Command Properties"))
748
 
                         .arg(i18n("Command")).arg("<tt>"+printer->option("kde-special-command")+"</tt>")
749
 
                         .arg(i18n("Use Output File")).arg(printer->option("kde-special-file") == "1" ? i18n("Yes") : i18n("No"))
750
 
                         .arg(i18n("Default Extension")).arg(printer->option("kde-special-extension"));
751
 
 
752
 
        data(content.local8Bit());
753
 
        finished();
754
 
}
755
 
 
756
 
bool KIO_Print::loadTemplate(const QString& filename, QString& buffer)
757
 
{
758
 
        QFile   f(locate("data", QString::fromLatin1("kdeprint/template/")+filename));
759
 
        if (f.exists() && f.open(IO_ReadOnly))
760
 
        {
761
 
                QTextStream     t(&f);
762
 
                buffer = t.read();
763
 
                return true;
764
 
        }
765
 
        else
766
 
        {
767
 
                buffer = QString::null;
768
 
                return false;
769
 
        }
770
 
}
771
 
 
772
 
void KIO_Print::showData(const QString& pathname)
773
 
{
774
 
        PRINT_DEBUG << "sending data: " << pathname << endl;
775
 
        QFile   f(pathname);
776
 
        if (f.exists() && f.open(IO_ReadOnly))
777
 
        {
778
 
                QByteArray      arr(f.readAll());
779
 
                mimeType(KMimeType::findByURL(KURL(pathname), 0, true, true)->name());
780
 
                data(arr);
781
 
                finished();
782
 
        }
783
 
        else
784
 
        {
785
 
                PRINT_DEBUG << "file not found" << endl;
786
 
                error(KIO::ERR_DOES_NOT_EXIST, pathname);
787
 
        }
788
 
}
789
 
 
790
 
/**
791
 
 * Locate a data in this order:
792
 
 *      - $KDEDIR/share/apps/kdeprint/template/
793
 
 *      - as a desktop icon
794
 
 */
795
 
QString KIO_Print::locateData(const QString& item)
796
 
{
797
 
        QString path = locate("data", "kdeprint/template/"+item);
798
 
        if (path.isEmpty())
799
 
                path = KGlobal::iconLoader()->iconPath(item, KIcon::Desktop, true);
800
 
        return path;
801
 
}
802
 
 
803
 
void KIO_Print::showJobs(KMPrinter *prt, bool completed)
804
 
{
805
 
        mimeType("text/html");
806
 
 
807
 
        // Add the printer to the current list in the job manager
808
 
        KMJobManager::JobType   type = (completed ? KMJobManager::CompletedJobs : KMJobManager::ActiveJobs);
809
 
        KMJobManager    *mgr = KMJobManager::self();
810
 
        if (prt)
811
 
                mgr->addPrinter(prt->printerName(), type);
812
 
        else
813
 
        {
814
 
                QPtrListIterator<KMPrinter>     pit(*(KMManager::self()->printerList()));
815
 
                for (; pit.current(); ++pit)
816
 
                        if (pit.current()->isVirtual() || pit.current()->isSpecial())
817
 
                                continue;
818
 
                        else
819
 
                                mgr->addPrinter(pit.current()->printerName(), type);
820
 
        }
821
 
 
822
 
        QString content;
823
 
        if (!loadTemplate(QString::fromLatin1("jobs.template"), content))
824
 
        {
825
 
                error(KIO::ERR_INTERNAL, i18n("Unable to load template %1").arg("pseudo.template"));
826
 
                return;
827
 
        }
828
 
 
829
 
        if (prt)
830
 
        {
831
 
                content = content
832
 
                                 .arg(i18n("Jobs of %1").arg(prt->printerName()))
833
 
                                 .arg(i18n("Jobs of %1").arg(prt->printerName()))
834
 
                                 .arg(prt->isClass () ?
835
 
                                                 buildMenu(QStringList::split('|', i18n("General|Active jobs|Completed jobs"), false),
836
 
                                                         QStringList::split('|', "?general|?jobs|?completed_jobs", true),
837
 
                                                         (completed ? 2 : 1)) :
838
 
                                                 buildMenu(QStringList::split('|', i18n("General|Driver|Active jobs|Completed jobs"), false),
839
 
                                                         QStringList::split('|', "?general|?driver|?jobs|?completed_jobs", true),
840
 
                                                         (completed ? 3 : 2)))
841
 
                                 .arg(QString::null)
842
 
                                 .arg(prt->pixmap())
843
 
                                 .arg(prt->printerName());
844
 
        }
845
 
        else
846
 
        {
847
 
                content = content
848
 
                                 .arg(i18n("All jobs"))
849
 
                                 .arg(buildMenu(QStringList::split('|', i18n("Active jobs|Completed jobs"), false),
850
 
                                                         QStringList::split('|', "?jobs|?completed_jobs", true),
851
 
                                                         (completed ? 1 : 0)))
852
 
                                 .arg("fileprint")
853
 
                                 .arg(i18n("All jobs"));
854
 
        }
855
 
        content = content.arg(i18n("ID")).arg(i18n("Owner")).arg(i18n("Printer")).arg(i18n("Name")).arg(i18n("State"));
856
 
 
857
 
        QString jobContent, cellContent("<td>%1</td>\n");
858
 
        QPtrListIterator<KMJob> it(mgr->jobList());
859
 
        bool    flag(true);
860
 
        for (; it.current(); ++it, flag = !flag)
861
 
        {
862
 
                jobContent.append("<tr class=\"").append(flag ? "contentyellow" : "contentwhite").append("\">\n");
863
 
                jobContent.append(cellContent.arg(it.current()->id()));
864
 
                jobContent.append(cellContent.arg(it.current()->owner()));
865
 
                jobContent.append(cellContent.arg(it.current()->printer()));
866
 
                jobContent.append(cellContent.arg(it.current()->name()));
867
 
                jobContent.append(cellContent.arg(it.current()->stateString()));
868
 
                jobContent.append("</tr>\n");
869
 
        }
870
 
        content = content.arg(jobContent);
871
 
 
872
 
        // remove the current printer to the current list in the job manager
873
 
        if (prt)
874
 
                mgr->removePrinter(prt->printerName(), type);
875
 
        else
876
 
        {
877
 
                QPtrListIterator<KMPrinter>     pit(*(KMManager::self()->printerList()));
878
 
                for (; pit.current(); ++pit)
879
 
                        if (pit.current()->isVirtual() || pit.current()->isSpecial())
880
 
                                continue;
881
 
                        else
882
 
                                mgr->removePrinter(pit.current()->printerName(), type);
883
 
        }
884
 
 
885
 
        data(content.local8Bit());
886
 
        finished();
887
 
}
888
 
 
889
 
void KIO_Print::showDriver(KMPrinter *prt)
890
 
{
891
 
        mimeType("text/html");
892
 
 
893
 
        QString content;
894
 
        if (!loadTemplate(QString::fromLatin1("driver.template"), content))
895
 
        {
896
 
                error(KIO::ERR_INTERNAL, i18n("Unable to load template %1").arg("pseudo.template"));
897
 
                return;
898
 
        }
899
 
 
900
 
        DrMain  *driver = KMManager::self()->loadPrinterDriver(prt, true);
901
 
        content = content
902
 
                         .arg(i18n("Driver of %1").arg(prt->printerName()))
903
 
                         .arg(i18n("Driver of %1").arg(prt->printerName()))
904
 
                         .arg(buildMenu(QStringList::split('|', i18n("General|Driver|Active jobs|Completed jobs"), false),
905
 
                                                 QStringList::split('|', "?general|?driver|?jobs|?completed_jobs", true),
906
 
                                                 1))
907
 
                         .arg(QString::null)
908
 
                         .arg(prt->pixmap())
909
 
                         .arg(prt->printerName() + "&nbsp;(" + (driver ? driver->get("text") : i18n("No driver found")) + ")");
910
 
 
911
 
        if (driver)
912
 
                content = content.arg(buildGroupTable(driver, false));
913
 
        else
914
 
                content = content.arg(QString::null);
915
 
 
916
 
        data(content.local8Bit());
917
 
        finished();
918
 
}
919
 
 
920
 
#include "kio_print.moc"