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.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sun Oct 17 11:32:32 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003