# kdeprint Library API Documentation

Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# kmfactory.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 "kmfactory.h"
    00021 #include "kmmanager.h"
    00022 #include "kmjobmanager.h"
    00023 #include "kmuimanager.h"
    00024 #include "kprinterimpl.h"
    00025 #include "kprinter.h"
    00026 #include "kpreloadobject.h"
    00027 #include "kdeprintcheck.h"
    00028 #include "kxmlcommand.h"
    00029
    00030 #include <qdir.h>
    00031 #include <qfile.h>
    00032 #include <qsettings.h>
    00033
    00034 #include <klibloader.h>
    00035 #include <kconfig.h>
    00036 #include <kstandarddirs.h>
    00037 #include <kiconloader.h>
    00038 #include <kdebug.h>
    00039 #include <kmessagebox.h>
    00040 #include <klocale.h>
    00041 #include <ksimpleconfig.h>
    00042 #include <kstaticdeleter.h>
    00043 #include <kapplication.h>
    00044 #include <dcopclient.h>
    00045 #include <dcopref.h>
    00046 #include <kio/authinfo.h>
    00047
    00048 #include <unistd.h>
    00049
    00050 #define UNLOAD_OBJECT(x) if (x != 0) { delete x; x = 0; }
    00051
    00052 #ifdef Q_WS_X11
    00053 extern void qt_generate_epsf( bool b );
    00054 #endif
    00055
    00056 KMFactory* KMFactory::m_self = 0;
    00057 static KStaticDeleter<KMFactory> s_kmfactorysd;
    00058
    00059 KMFactory* KMFactory::self()
    00060 {
    00061     if (!m_self)
    00062         m_self = s_kmfactorysd.setObject(m_self, new KMFactory());
    00063     return m_self;
    00064 }
    00065
    00066 bool KMFactory::exists()
    00067 {
    00068     return m_self != 0L;
    00069 }
    00070
    00071 void KMFactory::release()
    00072 {
    00073     if (m_self)
    00074     {
    00075         KMFactory* p = m_self;
    00076         m_self = 0; // so that exists() says false
    00077         delete p;
    00078     }
    00079 }
    00080
    00081 KMFactory::KMFactory()
    00082     : QObject(NULL, "Factory")
    00083 {
    00084     m_settings = new Settings;
    00085     m_settings->application = KPrinter::Dialog;
    00086     m_settings->pageSelection = KPrinter::SystemSide;
    00087     m_settings->standardDialogPages = KPrinter::CopiesPage;
    00088     m_settings->pageSize = -1;
    00089     m_settings->orientation = -1;
    00090
    00091     m_objects.setAutoDelete(false);
    00092
    00093     m_manager = 0;
    00094     m_jobmanager = 0;
    00095     m_uimanager = 0;
    00096     m_implementation = 0;
    00097     m_factory = 0;
    00098     m_printconfig = 0;
    00099 #if QT_VERSION >= 230
    00100     // Qt's default behavior, to generate EPS in some cases and not in others, sucks.
    00101     // This is fixed in Qt 3.0, but for Qt 2.x we need to disable it explicitly.
    00102     // If this is a problem for anyone, we can add a public method to set this flag.
    00103     // (David Faure, doing as advised by Lars Knoll)
    00104 #ifdef Q_WS_X11
    00105     qt_generate_epsf( false );
    00106 #endif
    00107 #endif
    00108
    00109     // By default, embed PS fonts
    00110     bool ok = false;
    00111     QSettings settings;
    00112     settings.readBoolEntry( "/qt/embedFonts", true, &ok );
    00113     if ( !ok )
    00114         settings.writeEntry( "/qt/embedFonts", true );
    00115
    00116     KGlobal::iconLoader()->addAppDir("kdeprint");
    00117         KGlobal::locale()->insertCatalogue("kdeprint");
    00118
    00119     // create DCOP signal connection
    00120     connectDCOPSignal(0, 0, "pluginChanged(pid_t)", "slot_pluginChanged(pid_t)", false);
    00121     connectDCOPSignal(0, 0, "configChanged()", "slot_configChanged()", false);
    00122 }
    00123
    00124 KMFactory::~KMFactory()
    00125 {
    00126     delete m_settings;
    00127     // The only object to be destroyed is m_printconfig. All other objects have been
    00128     // created with "this" as parent, so we don't need to care about their destruction
    00129     UNLOAD_OBJECT(m_printconfig);
    00130     m_self = 0;
    00131 }
    00132
    00133 KMManager* KMFactory::manager()
    00134 {
    00135     if (!m_manager)
    00136         createManager();
    00137     Q_CHECK_PTR(m_manager);
    00138     return m_manager;
    00139 }
    00140
    00141 KMJobManager* KMFactory::jobManager()
    00142 {
    00143     if (!m_jobmanager)
    00144         createJobManager();
    00145     Q_CHECK_PTR(m_jobmanager);
    00146     return m_jobmanager;
    00147 }
    00148
    00149 KMUiManager* KMFactory::uiManager()
    00150 {
    00151     if (!m_uimanager)
    00152         createUiManager();
    00153     Q_CHECK_PTR(m_uimanager);
    00154     return m_uimanager;
    00155 }
    00156
    00157 KPrinterImpl* KMFactory::printerImplementation()
    00158 {
    00159     if (!m_implementation)
    00160         createPrinterImpl();
    00161     Q_CHECK_PTR(m_implementation);
    00162     return m_implementation;
    00163 }
    00164
    00165 KMVirtualManager* KMFactory::virtualManager()
    00166 {
    00167     return manager()->m_virtualmgr;
    00168 }
    00169
    00170 KMSpecialManager* KMFactory::specialManager()
    00171 {
    00172     return manager()->m_specialmgr;
    00173 }
    00174
    00175 KXmlCommandManager* KMFactory::commandManager()
    00176 {
    00177     return KXmlCommandManager::self();
    00178 }
    00179
    00180 void KMFactory::createManager()
    00181 {
    00182     loadFactory();
    00183     if (m_factory) m_manager = (KMManager*)m_factory->create(this,"Manager","KMManager");
    00184     if (!m_manager) m_manager = new KMManager(this,"Manager");
    00185 }
    00186
    00187 void KMFactory::createJobManager()
    00188 {
    00189     loadFactory();
    00190     if (m_factory) m_jobmanager = (KMJobManager*)m_factory->create(this,"JobManager","KMJobManager");
    00191     if (!m_jobmanager) m_jobmanager = new KMJobManager(this,"JobManager");
    00192 }
    00193
    00194 void KMFactory::createUiManager()
    00195 {
    00196     loadFactory();
    00197     if (m_factory) m_uimanager = (KMUiManager*)m_factory->create(this,"UiManager","KMUiManager");
    00198     if (!m_uimanager) m_uimanager = new KMUiManager(this,"UiManager");
    00199 }
    00200
    00201 void KMFactory::createPrinterImpl()
    00202 {
    00203     loadFactory();
    00204     if (m_factory) m_implementation = (KPrinterImpl*)m_factory->create(this,"PrinterImpl","KPrinterImpl");
    00205     if (!m_implementation) m_implementation = new KPrinterImpl(this,"PrinterImpl");
    00206 }
    00207
    00208 void KMFactory::loadFactory(const QString& syst)
    00209 {
    00210     if (!m_factory)
    00211     {
    00212         QString sys(syst);
    00213         if (sys.isEmpty())
    00214             // load default configured print plugin
    00215             sys = printSystem();
    00216         QString libname = QString::fromLatin1("kdeprint_%1").arg(sys);
    00217         m_factory = KLibLoader::self()->factory(QFile::encodeName(libname));
    00218                 if (!m_factory)
    00219                 {
    00220                         KMessageBox::error(0,
    00221                             i18n("<qt>There was an error loading %1. The diagnostic is:<p>%2</p></qt>")
    00222                             .arg(libname).arg(KLibLoader::self()->lastErrorMessage()));
    00223                 }
    00224     }
    00225 }
    00226
    00227 KConfig* KMFactory::printConfig(const QString& group)
    00228 {
    00229     if (!m_printconfig)
    00230     {
    00231         m_printconfig = new KConfig("kdeprintrc");
    00232         Q_CHECK_PTR(m_printconfig);
    00233     }
    00234     if (!group.isEmpty())
    00235         m_printconfig->setGroup(group);
    00236     return m_printconfig;
    00237 }
    00238
    00239 QString KMFactory::printSystem()
    00240 {
    00241     KConfig *conf = printConfig();
    00242     conf->setGroup("General");
    00243     QString sys = conf->readEntry("PrintSystem");
    00244     if (sys.isEmpty())
    00245     {
    00246         // perform auto-detection (will at least return "lpdunix")
    00247         sys = autoDetect();
    00248         // save the result
    00249         conf->writeEntry("PrintSystem", sys);
    00250         conf->sync();
    00251     }
    00252     else if ( sys.length()==1 && sys[0].isDigit() ) // discard old-style settings
    00253             sys = "lpdunix";
    00254     return sys;
    00255 }
    00256
    00257 void KMFactory::unload()
    00258 {
    00259     UNLOAD_OBJECT(m_manager);
    00260     UNLOAD_OBJECT(m_jobmanager);
    00261     UNLOAD_OBJECT(m_uimanager);
    00262     UNLOAD_OBJECT(m_implementation);
    00263     // factory will be automatically unloaded by KLibLoader as all object have been deleted.
    00264     // But to have loadFactory() to work, we need to set m_factory to NULL.
    00265     m_factory = 0;
    00266 }
    00267
    00268 void KMFactory::reload(const QString& syst, bool saveSyst)
    00269 {
    00270     // notify all registered objects about the coming reload
    00271     QPtrListIterator<KPReloadObject>    it(m_objects);
    00272     for (;it.current();++it)
    00273         it.current()->aboutToReload();
    00274
    00275     // unload all objects from the plugin
    00276     unload();
    00277     if (saveSyst)
    00278     {
    00279         KConfig *conf = printConfig();
    00280         conf->setGroup("General");
    00281         conf->writeEntry("PrintSystem", syst);
    00282         conf->sync();
    00283
    00284         // notify all other apps using DCOP signal
    00285         emit pluginChanged(getpid());
    00286     }
    00287
    00288     // reload the factory
    00289     loadFactory(syst);
    00290
    00291     // notify all registered objects
    00292     for (it.toFirst();it.current();++it)
    00293         it.current()->reload();
    00294 }
    00295
    00296 QValueList<KMFactory::PluginInfo> KMFactory::pluginList()
    00297 {
    00298     QDir    d(locate("data", "kdeprint/plugins/"), "*.print", QDir::Name, QDir::Files);
    00299     QValueList<PluginInfo>  list;
    00300     for (uint i=0; i<d.count(); i++)
    00301     {
    00302         PluginInfo  info(pluginInfo(d.absFilePath(d[i])));
    00303         if (info.name.isEmpty())
    00304             continue;
    00305         list.append(info);
    00306     }
    00307     return list;
    00308 }
    00309
    00310 KMFactory::PluginInfo KMFactory::pluginInfo(const QString& name)
    00311 {
    00312     QString path(name);
    00313     if (path[0] != '/')
    00314         path = locate("data", QString::fromLatin1("kdeprint/plugins/%1.print").arg(name));
    00315     KSimpleConfig   conf(path);
    00316     PluginInfo  info;
    00317
    00318     conf.setGroup("KDE Print Entry");
    00319     info.name = conf.readEntry("PrintSystem");
    00320     info.comment = conf.readEntry("Comment");
    00321     if (info.comment.isEmpty())
    00322         info.comment = info.name;
    00323     info.detectUris = conf.readListEntry("DetectUris");
    00324     info.detectPrecedence = conf.readNumEntry("DetectPrecedence", 0);
    00325     info.mimeTypes = conf.readListEntry("MimeTypes");
    00326     if (info.mimeTypes.isEmpty())
    00327         info.mimeTypes << "application/postscript";
    00328     info.primaryMimeType = conf.readEntry("PrimaryMimeType", info.mimeTypes[0]);
    00329
    00330     return info;
    00331 }
    00332
    00333 void KMFactory::registerObject(KPReloadObject *obj, bool priority)
    00334 {
    00335     // check if object already registered, then add it
    00336     if (m_objects.findRef(obj) == -1)
    00337     {
    00338         if (priority)
    00339             m_objects.prepend(obj);
    00340         else
    00341             m_objects.append(obj);
    00342         kdDebug(500) << "kdeprint: registering " << (void*)obj << ", number of objects = " << m_objects.count() << endl;
    00343     }
    00344 }
    00345
    00346 void KMFactory::unregisterObject(KPReloadObject *obj)
    00347 {
    00348     // remove object from list (not deleted as autoDelete is false)
    00349     m_objects.removeRef(obj);
    00350     kdDebug(500) << "kdeprint: unregistering " << (void*)obj << ", number of objects = " << m_objects.count() << endl;
    00351 }
    00352
    00353 QString KMFactory::autoDetect()
    00354 {
    00355     QValueList<PluginInfo>  plugins = pluginList();
    00356     int pluginIndex(-1), currentPrecedence(0);
    00357     for (uint i=0;i<plugins.count();i++)
    00358     {
    00359         if (plugins[i].detectUris.count() > 0 && KdeprintChecker::check(plugins[i].detectUris)
    00360             && (pluginIndex == -1 || plugins[i].detectPrecedence >= currentPrecedence))
    00361         {
    00362             pluginIndex = i;
    00363             currentPrecedence = plugins[i].detectPrecedence;
    00364         }
    00365     }
    00366     return (pluginIndex == -1 ? QString::fromLatin1("lpdunix") : plugins[pluginIndex].name);
    00367 }
    00368
    00369 void KMFactory::slot_pluginChanged(pid_t pid)
    00370 {
    00371     // only do something if the notification comes from another process
    00372     if (pid != getpid())
    00373     {
    00374         // Unload config object (avoid saving it)
    00375         printConfig()->rollback();
    00376         UNLOAD_OBJECT(m_printconfig);
    00377         // Then reload everything and notified registered objects.
    00378         // Do NOT re-save the new print system.
    00379         QString syst = printSystem();
    00380         reload(syst, false);
    00381     }
    00382 }
    00383
    00384 void KMFactory::slot_configChanged()
    00385 {
    00386     kdDebug(500) << "KMFactory (" << getpid() << ") receiving DCOP signal configChanged()" << endl;
    00387     // unload/reload config object (make it non dirty to
    00388     // avoid saving it and overwriting the newly saved options
    00389     // in the other application)
    00390     printConfig()->rollback();
    00391     UNLOAD_OBJECT(m_printconfig);
    00392     printConfig();
    00393
    00394     // notify all registered objects about the coming reload
    00395     QPtrListIterator<KPReloadObject>    it(m_objects);
    00396     /*for (;it.current();++it)
    00397         it.current()->aboutToReload();*/
    00398
    00399     // notify all object about the change
    00400     for (it.toFirst(); it.current();++it)
    00401         it.current()->configChanged();
    00402 }
    00403
    00404 void KMFactory::saveConfig()
    00405 {
    00406     KConfig *conf = printConfig();
    00407     conf->sync();
    00408     kdDebug(500) << "KMFactory (" << getpid() << ") emitting DCOP signal configChanged()" << endl;
    00409     emit configChanged();
    00410     // normally, the self application should also receive the signal,
    00411     // anyway the config object has been updated "locally", so ne real
    00412     // need to reload the config file.
    00413 }
    00414
    00415 QPair<QString,QString> KMFactory::requestPassword( int& seqNbr, const QString& user, const QString& host, int port )
    00416 {
    00417     DCOPRef kdeprintd( "kded", "kdeprintd" );
    00424     DCOPReply reply = kdeprintd.call( "requestPassword", user, host, port, seqNbr );
    00425     if ( reply.isValid() )
    00426     {
    00427         QString replyString = reply;
    00428         if ( replyString != "::" )
    00429         {
    00430             QStringList l = QStringList::split( ':', replyString, true );
    00431             if ( l.count() == 3 )
    00432             {
    00433                 seqNbr = l[ 2 ].toInt();
    00434                 return QPair<QString,QString>( l[ 0 ], l[ 1 ] );
    00435             }
    00436         }
    00437     }
    00438     return QPair<QString,QString>( QString::null, QString::null );
    00439 }
    00440
    00441 void KMFactory::initPassword( const QString& user, const QString& password, const QString& host, int port )
    00442 {
    00443     DCOPRef kdeprintd( "kded", "kdeprintd" );
    00450     kdeprintd.call( "initPassword", user, password, host, port );
    00451 }
    00452
    00453 #include "kmfactory.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:02 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003