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 #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;
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
00101
00102
00103
00104 #ifdef Q_WS_X11
00105 qt_generate_epsf( false );
00106 #endif
00107 #endif
00108
00109
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
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
00128
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
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
00230 if (!m_printconfig)
00231 {
00232 m_printconfig = new KConfig("kdeprintrc");
00233 Q_CHECK_PTR(m_printconfig);
00234 }
00235 if (!group.isEmpty())
00236 m_printconfig->setGroup(group);
00237 return m_printconfig;
00238 }
00239
00240 QString KMFactory::printSystem()
00241 {
00242 KConfig *conf = printConfig();
00243 conf->setGroup("General");
00244 QString sys = conf->readEntry("PrintSystem");
00245 if (sys.isEmpty())
00246 {
00247
00248 sys = autoDetect();
00249
00250 conf->writeEntry("PrintSystem", sys);
00251 conf->sync();
00252 }
00253 else if ( sys.length()==1 && sys[0].isDigit() )
00254 sys = "lpdunix";
00255 else{
00256
00257
00258
00259
00260 if(conf->readEntry("AlwaysSearch") != "no" ){
00261 sys = autoDetect();
00262 conf->writeEntry("PrintSystem",sys);
00263 conf->writeEntry("AlwaysSearch","yes");
00264 conf->sync();
00265 }
00266
00267 }
00268 return sys;
00269 }
00270
00271 void KMFactory::unload()
00272 {
00273 UNLOAD_OBJECT(m_manager);
00274 UNLOAD_OBJECT(m_jobmanager);
00275 UNLOAD_OBJECT(m_uimanager);
00276 UNLOAD_OBJECT(m_implementation);
00277
00278
00279 m_factory = 0;
00280 }
00281
00282 void KMFactory::reload(const QString& syst, bool saveSyst)
00283 {
00284
00285 QPtrListIterator<KPReloadObject> it(m_objects);
00286 for (;it.current();++it)
00287 it.current()->aboutToReload();
00288
00289
00290 unload();
00291 if (saveSyst)
00292 {
00293 KConfig *conf = printConfig();
00294 conf->setGroup("General");
00295
00296 conf->writeEntry("AlwaysSearch","no");
00297 conf->writeEntry("PrintSystem", syst);
00298 conf->sync();
00299
00300
00301 emit pluginChanged(getpid());
00302 }
00303
00304
00305 loadFactory(syst);
00306
00307
00308 for (it.toFirst();it.current();++it)
00309 it.current()->reload();
00310 }
00311
00312 QValueList<KMFactory::PluginInfo> KMFactory::pluginList()
00313 {
00314 QDir d(locate("data", "kdeprint/plugins/"), "*.print", QDir::Name, QDir::Files);
00315 QValueList<PluginInfo> list;
00316 for (uint i=0; i<d.count(); i++)
00317 {
00318 PluginInfo info(pluginInfo(d.absFilePath(d[i])));
00319 if (info.name.isEmpty())
00320 continue;
00321 list.append(info);
00322 }
00323 return list;
00324 }
00325
00326 KMFactory::PluginInfo KMFactory::pluginInfo(const QString& name)
00327 {
00328 QString path(name);
00329 if (path[0] != '/')
00330 path = locate("data", QString::fromLatin1("kdeprint/plugins/%1.print").arg(name));
00331 KSimpleConfig conf(path);
00332 PluginInfo info;
00333
00334 conf.setGroup("KDE Print Entry");
00335 info.name = conf.readEntry("PrintSystem");
00336 info.comment = conf.readEntry("Comment");
00337 if (info.comment.isEmpty())
00338 info.comment = info.name;
00339 info.detectUris = conf.readListEntry("DetectUris");
00340 info.detectPrecedence = conf.readNumEntry("DetectPrecedence", 0);
00341 info.mimeTypes = conf.readListEntry("MimeTypes");
00342 if (info.mimeTypes.isEmpty())
00343 info.mimeTypes << "application/postscript";
00344 info.primaryMimeType = conf.readEntry("PrimaryMimeType", info.mimeTypes[0]);
00345
00346 return info;
00347 }
00348
00349 void KMFactory::registerObject(KPReloadObject *obj, bool priority)
00350 {
00351
00352 if (m_objects.findRef(obj) == -1)
00353 {
00354 if (priority)
00355 m_objects.prepend(obj);
00356 else
00357 m_objects.append(obj);
00358 kdDebug(500) << "kdeprint: registering " << (void*)obj << ", number of objects = " << m_objects.count() << endl;
00359 }
00360 }
00361
00362 void KMFactory::unregisterObject(KPReloadObject *obj)
00363 {
00364
00365 m_objects.removeRef(obj);
00366 kdDebug(500) << "kdeprint: unregistering " << (void*)obj << ", number of objects = " << m_objects.count() << endl;
00367 }
00368
00369 QString KMFactory::autoDetect()
00370 {
00371 QValueList<PluginInfo> plugins = pluginList();
00372 int pluginIndex(-1), currentPrecedence(0);
00373 for (uint i=0;i<plugins.count();i++)
00374 {
00375 if (plugins[i].detectUris.count() > 0 && KdeprintChecker::check(plugins[i].detectUris)
00376 && (pluginIndex == -1 || plugins[i].detectPrecedence >= currentPrecedence))
00377 {
00378 pluginIndex = i;
00379 currentPrecedence = plugins[i].detectPrecedence;
00380 }
00381 }
00382 return (pluginIndex == -1 ? QString::fromLatin1("lpdunix") : plugins[pluginIndex].name);
00383 }
00384
00385 void KMFactory::slot_pluginChanged(pid_t pid)
00386 {
00387
00388 if (pid != getpid())
00389 {
00390
00391 printConfig()->rollback();
00392 UNLOAD_OBJECT(m_printconfig);
00393
00394
00395 QString syst = printSystem();
00396 reload(syst, false);
00397 }
00398 }
00399
00400 void KMFactory::slot_configChanged()
00401 {
00402 kdDebug(500) << "KMFactory (" << getpid() << ") receiving DCOP signal configChanged()" << endl;
00403
00404
00405
00406 printConfig()->rollback();
00407 UNLOAD_OBJECT(m_printconfig);
00408 printConfig();
00409
00410
00411 QPtrListIterator<KPReloadObject> it(m_objects);
00412
00413
00414
00415
00416 for (it.toFirst(); it.current();++it)
00417 it.current()->configChanged();
00418 }
00419
00420 void KMFactory::saveConfig()
00421 {
00422 KConfig *conf = printConfig();
00423 conf->sync();
00424 kdDebug(500) << "KMFactory (" << getpid() << ") emitting DCOP signal configChanged()" << endl;
00425 emit configChanged();
00426
00427
00428
00429 }
00430
00431 QPair<QString,QString> KMFactory::requestPassword( int& seqNbr, const QString& user, const QString& host, int port )
00432 {
00433 DCOPRef kdeprintd( "kded", "kdeprintd" );
00440 DCOPReply reply = kdeprintd.call( "requestPassword", user, host, port, seqNbr );
00441 if ( reply.isValid() )
00442 {
00443 QString replyString = reply;
00444 if ( replyString != "::" )
00445 {
00446 QStringList l = QStringList::split( ':', replyString, true );
00447 if ( l.count() == 3 )
00448 {
00449 seqNbr = l[ 2 ].toInt();
00450 return QPair<QString,QString>( l[ 0 ], l[ 1 ] );
00451 }
00452 }
00453 }
00454 return QPair<QString,QString>( QString::null, QString::null );
00455 }
00456
00457 void KMFactory::initPassword( const QString& user, const QString& password, const QString& host, int port )
00458 {
00459 DCOPRef kdeprintd( "kded", "kdeprintd" );
00466 kdeprintd.call( "initPassword", user, password, host, port );
00467 }
00468
00469 #include "kmfactory.moc"