diff options
Diffstat (limited to 'tdeprint/kmvirtualmanager.cpp')
-rw-r--r-- | tdeprint/kmvirtualmanager.cpp | 371 |
1 files changed, 371 insertions, 0 deletions
diff --git a/tdeprint/kmvirtualmanager.cpp b/tdeprint/kmvirtualmanager.cpp new file mode 100644 index 000000000..78757decd --- /dev/null +++ b/tdeprint/kmvirtualmanager.cpp @@ -0,0 +1,371 @@ +/* + * This file is part of the KDE libraries + * Copyright (c) 2001 Michael Goffioul <tdeprint@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 "kmvirtualmanager.h" +#include "kmprinter.h" +#include "kmfactory.h" +#include "kmmanager.h" +#include "kprinter.h" + +#include <stdlib.h> +#include <tqfile.h> +#include <tqtextstream.h> +#include <tqdir.h> +#include <tqfileinfo.h> +#include <klocale.h> +#include <kstandarddirs.h> +#include <kurl.h> +#include <kdebug.h> +#include <kmessagebox.h> + +#include <unistd.h> + +static TQString instanceName(const TQString& prname, const TQString& instname) +{ + QString str(prname); + if (!instname.isEmpty()) + str.append("/"+instname); + return str; +} + +KMVirtualManager::KMVirtualManager(KMManager *parent, const char *name) +: TQObject(parent,name), m_manager(parent) +{ +} + +KMVirtualManager::~KMVirtualManager() +{ +} + +KMPrinter* KMVirtualManager::findPrinter(const TQString& name) +{ + return m_manager->findPrinter(name); +} + +KMPrinter* KMVirtualManager::findInstance(KMPrinter *p, const TQString& name) +{ + QString instname(instanceName(p->printerName(),name)); + return findPrinter(instname); +} + +void KMVirtualManager::addPrinter(KMPrinter *p) +{ + if (p && p->isValid()) + { + KMPrinter *other = findPrinter(p->name()); + if (other) + { + other->copy(*p); + // Replace default options with the new loaded ones: this is needed + // if we want to handle 2 lpoptions correctly (system-wide and local). + // Anyway, the virtual printers will be reloaded only if something has + // changed in one of the files, so it's better to reset everything, to + // be sure to use the new changes. Edited options will be left unchanged. + other->setDefaultOptions(p->defaultOptions()); + delete p; + } + else + m_manager->addPrinter(p); + } + else + delete p; +} + +void KMVirtualManager::setDefault(KMPrinter *p, bool saveflag) +{ + m_manager->setSoftDefault(p); + m_defaultprinter = (p ? p->printerName() : TQString::null); + if (saveflag) triggerSave(); +} + +bool KMVirtualManager::isDefault(KMPrinter *p, const TQString& name) +{ + QString instname(instanceName(p->printerName(),name)); + KMPrinter *printer = findPrinter(instname); + if (printer) + return printer->isSoftDefault(); + else + return false; +} + +void KMVirtualManager::create(KMPrinter *p, const TQString& name) +{ + QString instname = instanceName(p->printerName(),name); + if (findPrinter(instname) != NULL) return; + KMPrinter *printer = new KMPrinter; + printer->setName(instname); + printer->setPrinterName(p->printerName()); + printer->setInstanceName(name); + if (!name.isEmpty()) + printer->setType(p->type()|KMPrinter::Virtual); + // we need some options to know how to load the driver + if (p->isSpecial()) + printer->setOptions(p->options()); + m_manager->addPrinter(printer); + triggerSave(); +} + +void KMVirtualManager::copy(KMPrinter *p, const TQString& src, const TQString& name) +{ + QString instsrc(instanceName(p->printerName(),src)), instname(instanceName(p->printerName(),name)); + KMPrinter *prsrc = findPrinter(instsrc); + if (!prsrc || findPrinter(instname) != NULL) return; + KMPrinter *printer = new KMPrinter; + printer->copy(*prsrc); + printer->setName(instname); + printer->setInstanceName(name); + printer->setDefaultOptions(prsrc->defaultOptions()); + m_manager->addPrinter(printer); + triggerSave(); +} + +void KMVirtualManager::remove(KMPrinter *p, const TQString& name) +{ + QString instname = instanceName(p->printerName(),name); + KMPrinter *printer = findPrinter(instname); + if (!printer) return; + if (name.isEmpty()) + { // remove default instance => only remove options, keep the KMPrinter object + printer->setDefaultOptions(TQMap<TQString,TQString>()); + printer->setEditedOptions(TQMap<TQString,TQString>()); + printer->setEdited(false); + } + else + m_manager->m_printers.removeRef(printer); + triggerSave(); +} + +void KMVirtualManager::setAsDefault(KMPrinter *p, const TQString& name, TQWidget *parent) +{ + QString instname(instanceName(p->printerName(),name)); + + if ( p->isSpecial() ) + { + if ( KMessageBox::warningContinueCancel( parent, + i18n( "<qt>You are about to set a pseudo-printer as your personal default. " + "This setting is specific to KDE and will not be available outside KDE " + "applications. Note that this will only make your personal default printer " + "as undefined for non-KDE applications and should not prevent you from " + "printing normally. Do you really want to set <b>%1</b> as your personal default?</qt>" ).arg( instname ), + TQString::null, i18n("Set as Default"), "setSpecialAsDefault" ) == KMessageBox::No ) + return; + } + + KMPrinter *printer = findPrinter(instname); + if (!printer) + { // create it if necessary + create(p,name); + printer = findPrinter(instname); + } + if (printer) + setDefault(printer,true); +} + +void KMVirtualManager::refresh() +{ + TQFileInfo fi(TQDir::homeDirPath() + TQFile::decodeName("/.cups/lpoptions")); + TQFileInfo fi2(TQFile::decodeName("/etc/cups/lpoptions")); + + // if root, then only use global file: trick -> use twice the same file + if (getuid() == 0) + fi.setFile(fi2.absFilePath()); + + if (!m_checktime.isValid() || m_checktime < QMAX(fi.lastModified(),fi2.lastModified())) + { + m_defaultprinter = TQString::null; + if (fi2.exists()) + loadFile(fi2.absFilePath()); + if (fi.exists() && fi.absFilePath() != fi2.absFilePath()) + loadFile(fi.absFilePath()); + m_checktime = QMAX(fi.lastModified(),fi2.lastModified()); + } + else + { // parse printers looking for instances -> undiscarded them, real printers + // are undiscarded by the manager itself. Also update printer status. + TQPtrListIterator<KMPrinter> it(m_manager->m_printers); + for (;it.current();++it) + if (!it.current()->instanceName().isEmpty()) + { + checkPrinter(it.current()); + if (it.current()->isValid()) it.current()->setDiscarded(false); + } + } +} + +void KMVirtualManager::checkPrinter(KMPrinter *p) +{ + KMPrinter *realprinter = m_manager->findPrinter(p->printerName()); + if (!realprinter || realprinter->isDiscarded()) + { + p->setType(KMPrinter::Invalid); + p->setState(KMPrinter::Unknown); + } + else + { + if (!p->instanceName().isEmpty()) + p->setType(realprinter->type()|KMPrinter::Virtual); + p->setState(realprinter->state()); + } +} + +TQString KMVirtualManager::defaultPrinterName() +{ + return m_defaultprinter; +} + +void KMVirtualManager::virtualList(TQPtrList<KMPrinter>& list, const TQString& prname) +{ + // load printers if necessary + refresh(); + + // then look for instances + list.setAutoDelete(false); + list.clear(); + kdDebug(500) << "KMVirtualManager::virtualList() prname=" << prname << endl; + TQPtrListIterator<KMPrinter> it(m_manager->m_printers); + for (;it.current();++it) + if (it.current()->printerName() == prname) + list.append(it.current()); +} + +void KMVirtualManager::loadFile(const TQString& filename) +{ + TQFile f(filename); + if (f.exists() && f.open(IO_ReadOnly)) + { + TQTextStream t(&f); + + TQString line; + TQStringList words; + TQStringList pair; + KMPrinter *printer, *realprinter; + + while (!t.eof()) + { + line = t.readLine().stripWhiteSpace(); + if (line.isEmpty()) continue; + words = TQStringList::split(' ',line,false); + if (words.count() < 2) continue; + pair = TQStringList::split('/',words[1],false); + realprinter = m_manager->findPrinter(KURL::decode_string(pair[0])); + if (realprinter && !realprinter->isDiscarded()) + { // keep only instances corresponding to an existing and + // non discarded printer. + // "clone" the real printer and modify settings as needed + printer = new KMPrinter(*realprinter); + printer->setName(KURL::decode_string(words[1])); + printer->setPrinterName(KURL::decode_string(pair[0])); + if (pair.count() > 1) + { + printer->setInstanceName(KURL::decode_string(pair[1])); + printer->addType(KMPrinter::Virtual); + } + // parse options + for (uint i=2; i<words.count(); i++) + { + pair = TQStringList::split('=',words[i],false); + printer->setDefaultOption(pair[0],(pair.count() > 1 ? pair[1] : TQString::null)); + } + // add printer to the manager + addPrinter(printer); // don't use "printer" after this point !!! + // check default state + if (words[0].lower().startsWith("default")) + setDefault(findPrinter(KURL::decode_string(words[1])),false); + } + } + } +} + +void KMVirtualManager::triggerSave() +{ + QString filename; + if (getuid() == 0) + { + if (KStandardDirs::makeDir(TQFile::decodeName("/etc/cups"))) + filename = TQFile::decodeName("/etc/cups/lpoptions"); + } + else + { + TQDir cupsDir(TQDir::home().absPath()+"/.cups"); + if (!cupsDir.exists()) + cupsDir.mkdir(TQDir::home().absPath()+"/.cups"); + filename = TQDir::homeDirPath() + TQFile::decodeName("/.cups/lpoptions"); + } + + if (!filename.isEmpty()) + { + saveFile(filename); + m_checktime = TQFileInfo(filename).lastModified(); + } +} + +void KMVirtualManager::saveFile(const TQString& filename) +{ + TQFile f(filename); + if (f.open(IO_WriteOnly)) + { + TQTextStream t(&f); + TQPtrListIterator<KMPrinter> it(m_manager->m_printers); + for (;it.current();++it) + { + if (it.current()->isSpecial()) + { + t << ( it.current()->isSoftDefault() ? "DefaultSpecial " : "Special " ); + t << KURL::encode_string_no_slash( it.current()->printerName() ); + if ( !it.current()->instanceName().isEmpty() ) + t << "/" << KURL::encode_string_no_slash( it.current()->instanceName() ); + } + else + t << (it.current()->isSoftDefault() ? "Default " : "Dest ") << it.current()->name(); + TQMap<TQString,TQString> opts = it.current()->defaultOptions(); + for (TQMap<TQString,TQString>::ConstIterator oit=opts.begin(); oit!=opts.end(); ++oit) + { + t << ' ' << oit.key(); + if (!oit.data().isEmpty()) + t << '=' << oit.data(); + } + t << endl; + } + } +} + +bool KMVirtualManager::testInstance(KMPrinter *p) +{ + TQString testpage = KMManager::self()->testPage(); + if (testpage.isEmpty()) + return false; + else + { + KPrinter pr; + pr.setPrinterName(p->printerName()); + pr.setSearchName(p->name()); + pr.setOptions(p->defaultOptions()); + return (pr.printFiles(testpage)); + } +} + +void KMVirtualManager::reload() +{ + reset(); +} + +void KMVirtualManager::configChanged() +{ + reset(); +} |