00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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;
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
00099
00100
00101
00102 qt_generate_epsf( false );
00103 #endif
00104
00105
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
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
00124
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
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","cups");
00240 if (sys.isEmpty())
00241 {
00242
00243 sys = autoDetect();
00244
00245 conf->writeEntry("PrintSystem", sys);
00246 conf->sync();
00247 }
00248 else if ( sys.length()==1 && sys[0].isDigit() )
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
00260
00261 m_factory = 0;
00262 }
00263
00264 void KMFactory::reload(const QString& syst, bool saveSyst)
00265 {
00266
00267 QPtrListIterator<KPReloadObject> it(m_objects);
00268 for (;it.current();++it)
00269 it.current()->aboutToReload();
00270
00271
00272 unload();
00273 if (saveSyst)
00274 {
00275 KConfig *conf = printConfig();
00276 conf->setGroup("General");
00277 conf->writeEntry("PrintSystem", syst);
00278 conf->sync();
00279
00280
00281 emit pluginChanged(getpid());
00282 }
00283
00284
00285 loadFactory(syst);
00286
00287
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
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
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
00368 if (pid != getpid())
00369 {
00370
00371 printConfig()->rollback();
00372 UNLOAD_OBJECT(m_printconfig);
00373
00374
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
00384
00385
00386 printConfig()->rollback();
00387 UNLOAD_OBJECT(m_printconfig);
00388 printConfig();
00389
00390
00391 QPtrListIterator<KPReloadObject> it(m_objects);
00392
00393
00394
00395
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
00407
00408
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"