summaryrefslogtreecommitdiffstats
path: root/kdeprint/kmfactory.cpp
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commitce4a32fe52ef09d8f5ff1dd22c001110902b60a2 (patch)
tree5ac38a06f3dde268dc7927dc155896926aaf7012 /kdeprint/kmfactory.cpp
downloadtdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.tar.gz
tdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdelibs@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kdeprint/kmfactory.cpp')
-rw-r--r--kdeprint/kmfactory.cpp453
1 files changed, 453 insertions, 0 deletions
diff --git a/kdeprint/kmfactory.cpp b/kdeprint/kmfactory.cpp
new file mode 100644
index 000000000..4fb7f7ca5
--- /dev/null
+++ b/kdeprint/kmfactory.cpp
@@ -0,0 +1,453 @@
+/*
+ * This file is part of the KDE libraries
+ * Copyright (c) 2001 Michael Goffioul <kdeprint@swing.be>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#include "kmfactory.h"
+#include "kmmanager.h"
+#include "kmjobmanager.h"
+#include "kmuimanager.h"
+#include "kprinterimpl.h"
+#include "kprinter.h"
+#include "kpreloadobject.h"
+#include "kdeprintcheck.h"
+#include "kxmlcommand.h"
+
+#include <qdir.h>
+#include <qfile.h>
+#include <qsettings.h>
+
+#include <klibloader.h>
+#include <kconfig.h>
+#include <kstandarddirs.h>
+#include <kiconloader.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <ksimpleconfig.h>
+#include <kstaticdeleter.h>
+#include <kapplication.h>
+#include <dcopclient.h>
+#include <dcopref.h>
+#include <kio/authinfo.h>
+
+#include <unistd.h>
+
+#define UNLOAD_OBJECT(x) if (x != 0) { delete x; x = 0; }
+
+#ifdef Q_WS_X11
+extern void qt_generate_epsf( bool b );
+#endif
+
+KMFactory* KMFactory::m_self = 0;
+static KStaticDeleter<KMFactory> s_kmfactorysd;
+
+KMFactory* KMFactory::self()
+{
+ if (!m_self)
+ m_self = s_kmfactorysd.setObject(m_self, new KMFactory());
+ return m_self;
+}
+
+bool KMFactory::exists()
+{
+ return m_self != 0L;
+}
+
+void KMFactory::release()
+{
+ if (m_self)
+ {
+ KMFactory* p = m_self;
+ m_self = 0; // so that exists() says false
+ delete p;
+ }
+}
+
+KMFactory::KMFactory()
+ : QObject(NULL, "Factory")
+{
+ m_settings = new Settings;
+ m_settings->application = KPrinter::Dialog;
+ m_settings->pageSelection = KPrinter::SystemSide;
+ m_settings->standardDialogPages = KPrinter::CopiesPage;
+ m_settings->pageSize = -1;
+ m_settings->orientation = -1;
+
+ m_objects.setAutoDelete(false);
+
+ m_manager = 0;
+ m_jobmanager = 0;
+ m_uimanager = 0;
+ m_implementation = 0;
+ m_factory = 0;
+ m_printconfig = 0;
+#if QT_VERSION >= 230
+ // Qt's default behavior, to generate EPS in some cases and not in others, sucks.
+ // This is fixed in Qt 3.0, but for Qt 2.x we need to disable it explicitly.
+ // If this is a problem for anyone, we can add a public method to set this flag.
+ // (David Faure, doing as advised by Lars Knoll)
+#ifdef Q_WS_X11
+ qt_generate_epsf( false );
+#endif
+#endif
+
+ // By default, embed PS fonts
+ bool ok = false;
+ QSettings settings;
+ settings.readBoolEntry( "/qt/embedFonts", true, &ok );
+ if ( !ok )
+ settings.writeEntry( "/qt/embedFonts", true );
+
+ KGlobal::iconLoader()->addAppDir("kdeprint");
+ KGlobal::locale()->insertCatalogue("kdeprint");
+
+ // create DCOP signal connection
+ connectDCOPSignal(0, 0, "pluginChanged(pid_t)", "slot_pluginChanged(pid_t)", false);
+ connectDCOPSignal(0, 0, "configChanged()", "slot_configChanged()", false);
+}
+
+KMFactory::~KMFactory()
+{
+ delete m_settings;
+ // The only object to be destroyed is m_printconfig. All other objects have been
+ // created with "this" as parent, so we don't need to care about their destruction
+ UNLOAD_OBJECT(m_printconfig);
+ m_self = 0;
+}
+
+KMManager* KMFactory::manager()
+{
+ if (!m_manager)
+ createManager();
+ Q_CHECK_PTR(m_manager);
+ return m_manager;
+}
+
+KMJobManager* KMFactory::jobManager()
+{
+ if (!m_jobmanager)
+ createJobManager();
+ Q_CHECK_PTR(m_jobmanager);
+ return m_jobmanager;
+}
+
+KMUiManager* KMFactory::uiManager()
+{
+ if (!m_uimanager)
+ createUiManager();
+ Q_CHECK_PTR(m_uimanager);
+ return m_uimanager;
+}
+
+KPrinterImpl* KMFactory::printerImplementation()
+{
+ if (!m_implementation)
+ createPrinterImpl();
+ Q_CHECK_PTR(m_implementation);
+ return m_implementation;
+}
+
+KMVirtualManager* KMFactory::virtualManager()
+{
+ return manager()->m_virtualmgr;
+}
+
+KMSpecialManager* KMFactory::specialManager()
+{
+ return manager()->m_specialmgr;
+}
+
+KXmlCommandManager* KMFactory::commandManager()
+{
+ return KXmlCommandManager::self();
+}
+
+void KMFactory::createManager()
+{
+ loadFactory();
+ if (m_factory) m_manager = (KMManager*)m_factory->create(this,"Manager","KMManager");
+ if (!m_manager) m_manager = new KMManager(this,"Manager");
+}
+
+void KMFactory::createJobManager()
+{
+ loadFactory();
+ if (m_factory) m_jobmanager = (KMJobManager*)m_factory->create(this,"JobManager","KMJobManager");
+ if (!m_jobmanager) m_jobmanager = new KMJobManager(this,"JobManager");
+}
+
+void KMFactory::createUiManager()
+{
+ loadFactory();
+ if (m_factory) m_uimanager = (KMUiManager*)m_factory->create(this,"UiManager","KMUiManager");
+ if (!m_uimanager) m_uimanager = new KMUiManager(this,"UiManager");
+}
+
+void KMFactory::createPrinterImpl()
+{
+ loadFactory();
+ if (m_factory) m_implementation = (KPrinterImpl*)m_factory->create(this,"PrinterImpl","KPrinterImpl");
+ if (!m_implementation) m_implementation = new KPrinterImpl(this,"PrinterImpl");
+}
+
+void KMFactory::loadFactory(const QString& syst)
+{
+ if (!m_factory)
+ {
+ QString sys(syst);
+ if (sys.isEmpty())
+ // load default configured print plugin
+ sys = printSystem();
+ QString libname = QString::fromLatin1("kdeprint_%1").arg(sys);
+ m_factory = KLibLoader::self()->factory(QFile::encodeName(libname));
+ if (!m_factory)
+ {
+ KMessageBox::error(0,
+ i18n("<qt>There was an error loading %1. The diagnostic is:<p>%2</p></qt>")
+ .arg(libname).arg(KLibLoader::self()->lastErrorMessage()));
+ }
+ }
+}
+
+KConfig* KMFactory::printConfig(const QString& group)
+{
+ if (!m_printconfig)
+ {
+ m_printconfig = new KConfig("kdeprintrc");
+ Q_CHECK_PTR(m_printconfig);
+ }
+ if (!group.isEmpty())
+ m_printconfig->setGroup(group);
+ return m_printconfig;
+}
+
+QString KMFactory::printSystem()
+{
+ KConfig *conf = printConfig();
+ conf->setGroup("General");
+ QString sys = conf->readEntry("PrintSystem");
+ if (sys.isEmpty())
+ {
+ // perform auto-detection (will at least return "lpdunix")
+ sys = autoDetect();
+ // save the result
+ conf->writeEntry("PrintSystem", sys);
+ conf->sync();
+ }
+ else if ( sys.length()==1 && sys[0].isDigit() ) // discard old-style settings
+ sys = "lpdunix";
+ return sys;
+}
+
+void KMFactory::unload()
+{
+ UNLOAD_OBJECT(m_manager);
+ UNLOAD_OBJECT(m_jobmanager);
+ UNLOAD_OBJECT(m_uimanager);
+ UNLOAD_OBJECT(m_implementation);
+ // factory will be automatically unloaded by KLibLoader as all object have been deleted.
+ // But to have loadFactory() to work, we need to set m_factory to NULL.
+ m_factory = 0;
+}
+
+void KMFactory::reload(const QString& syst, bool saveSyst)
+{
+ // notify all registered objects about the coming reload
+ QPtrListIterator<KPReloadObject> it(m_objects);
+ for (;it.current();++it)
+ it.current()->aboutToReload();
+
+ // unload all objects from the plugin
+ unload();
+ if (saveSyst)
+ {
+ KConfig *conf = printConfig();
+ conf->setGroup("General");
+ conf->writeEntry("PrintSystem", syst);
+ conf->sync();
+
+ // notify all other apps using DCOP signal
+ emit pluginChanged(getpid());
+ }
+
+ // reload the factory
+ loadFactory(syst);
+
+ // notify all registered objects
+ for (it.toFirst();it.current();++it)
+ it.current()->reload();
+}
+
+QValueList<KMFactory::PluginInfo> KMFactory::pluginList()
+{
+ QDir d(locate("data", "kdeprint/plugins/"), "*.print", QDir::Name, QDir::Files);
+ QValueList<PluginInfo> list;
+ for (uint i=0; i<d.count(); i++)
+ {
+ PluginInfo info(pluginInfo(d.absFilePath(d[i])));
+ if (info.name.isEmpty())
+ continue;
+ list.append(info);
+ }
+ return list;
+}
+
+KMFactory::PluginInfo KMFactory::pluginInfo(const QString& name)
+{
+ QString path(name);
+ if (path[0] != '/')
+ path = locate("data", QString::fromLatin1("kdeprint/plugins/%1.print").arg(name));
+ KSimpleConfig conf(path);
+ PluginInfo info;
+
+ conf.setGroup("KDE Print Entry");
+ info.name = conf.readEntry("PrintSystem");
+ info.comment = conf.readEntry("Comment");
+ if (info.comment.isEmpty())
+ info.comment = info.name;
+ info.detectUris = conf.readListEntry("DetectUris");
+ info.detectPrecedence = conf.readNumEntry("DetectPrecedence", 0);
+ info.mimeTypes = conf.readListEntry("MimeTypes");
+ if (info.mimeTypes.isEmpty())
+ info.mimeTypes << "application/postscript";
+ info.primaryMimeType = conf.readEntry("PrimaryMimeType", info.mimeTypes[0]);
+
+ return info;
+}
+
+void KMFactory::registerObject(KPReloadObject *obj, bool priority)
+{
+ // check if object already registered, then add it
+ if (m_objects.findRef(obj) == -1)
+ {
+ if (priority)
+ m_objects.prepend(obj);
+ else
+ m_objects.append(obj);
+ kdDebug(500) << "kdeprint: registering " << (void*)obj << ", number of objects = " << m_objects.count() << endl;
+ }
+}
+
+void KMFactory::unregisterObject(KPReloadObject *obj)
+{
+ // remove object from list (not deleted as autoDelete is false)
+ m_objects.removeRef(obj);
+ kdDebug(500) << "kdeprint: unregistering " << (void*)obj << ", number of objects = " << m_objects.count() << endl;
+}
+
+QString KMFactory::autoDetect()
+{
+ QValueList<PluginInfo> plugins = pluginList();
+ int pluginIndex(-1), currentPrecedence(0);
+ for (uint i=0;i<plugins.count();i++)
+ {
+ if (plugins[i].detectUris.count() > 0 && KdeprintChecker::check(plugins[i].detectUris)
+ && (pluginIndex == -1 || plugins[i].detectPrecedence >= currentPrecedence))
+ {
+ pluginIndex = i;
+ currentPrecedence = plugins[i].detectPrecedence;
+ }
+ }
+ return (pluginIndex == -1 ? QString::fromLatin1("lpdunix") : plugins[pluginIndex].name);
+}
+
+void KMFactory::slot_pluginChanged(pid_t pid)
+{
+ // only do something if the notification comes from another process
+ if (pid != getpid())
+ {
+ // Unload config object (avoid saving it)
+ printConfig()->rollback();
+ UNLOAD_OBJECT(m_printconfig);
+ // Then reload everything and notified registered objects.
+ // Do NOT re-save the new print system.
+ QString syst = printSystem();
+ reload(syst, false);
+ }
+}
+
+void KMFactory::slot_configChanged()
+{
+ kdDebug(500) << "KMFactory (" << getpid() << ") receiving DCOP signal configChanged()" << endl;
+ // unload/reload config object (make it non dirty to
+ // avoid saving it and overwriting the newly saved options
+ // in the other application)
+ printConfig()->rollback();
+ UNLOAD_OBJECT(m_printconfig);
+ printConfig();
+
+ // notify all registered objects about the coming reload
+ QPtrListIterator<KPReloadObject> it(m_objects);
+ /*for (;it.current();++it)
+ it.current()->aboutToReload();*/
+
+ // notify all object about the change
+ for (it.toFirst(); it.current();++it)
+ it.current()->configChanged();
+}
+
+void KMFactory::saveConfig()
+{
+ KConfig *conf = printConfig();
+ conf->sync();
+ kdDebug(500) << "KMFactory (" << getpid() << ") emitting DCOP signal configChanged()" << endl;
+ emit configChanged();
+ // normally, the self application should also receive the signal,
+ // anyway the config object has been updated "locally", so ne real
+ // need to reload the config file.
+}
+
+QPair<QString,QString> KMFactory::requestPassword( int& seqNbr, const QString& user, const QString& host, int port )
+{
+ DCOPRef kdeprintd( "kded", "kdeprintd" );
+ /**
+ * We do not use an internal event loop for 2 potential problems:
+ * - the MessageWindow modality (appearing afterwards, it pops up on top
+ * of the password dialog)
+ * - KMTimer should be stopped, but it's unavailable from this object
+ */
+ DCOPReply reply = kdeprintd.call( "requestPassword", user, host, port, seqNbr );
+ if ( reply.isValid() )
+ {
+ QString replyString = reply;
+ if ( replyString != "::" )
+ {
+ QStringList l = QStringList::split( ':', replyString, true );
+ if ( l.count() == 3 )
+ {
+ seqNbr = l[ 2 ].toInt();
+ return QPair<QString,QString>( l[ 0 ], l[ 1 ] );
+ }
+ }
+ }
+ return QPair<QString,QString>( QString::null, QString::null );
+}
+
+void KMFactory::initPassword( const QString& user, const QString& password, const QString& host, int port )
+{
+ DCOPRef kdeprintd( "kded", "kdeprintd" );
+ /**
+ * We do not use an internal event loop for 2 potential problems:
+ * - the MessageWindow modality (appearing afterwards, it pops up on top
+ * of the password dialog)
+ * - KMTimer should be stopped, but it's unavailable from this object
+ */
+ kdeprintd.call( "initPassword", user, password, host, port );
+}
+
+#include "kmfactory.moc"