kdeprint Library API Documentation

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