mirror of
https://bitbucket.org/smil3y/kde-extraapps.git
synced 2025-02-24 02:42:52 +00:00
298 lines
11 KiB
C++
298 lines
11 KiB
C++
/***************************************************************************
|
|
* Copyright (C) 2010-2012 by Daniel Nicoletti *
|
|
* dantti12@gmail.com *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This program 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 General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License *
|
|
* along with this program; see the file COPYING. If not, write to *
|
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
|
|
* Boston, MA 02110-1301, USA. *
|
|
***************************************************************************/
|
|
|
|
#include "NewPrinterNotification.h"
|
|
#include "newprinternotificationadaptor.h"
|
|
|
|
#include <KLocale>
|
|
#include <KNotification>
|
|
#include <KIcon>
|
|
#include <KToolInvocation>
|
|
#include <KDebug>
|
|
|
|
#include <KCupsRequest.h>
|
|
|
|
#include <QThread>
|
|
#include <QtDBus/QDBusMessage>
|
|
#include <QtDBus/QDBusConnection>
|
|
#include <QtDBus/QDBusServiceWatcher>
|
|
#include <QtDBus/QDBusReply>
|
|
|
|
#define STATUS_SUCCESS 0
|
|
#define STATUS_MODEL_MISMATCH 1
|
|
#define STATUS_GENERIC_DRIVER 2
|
|
#define STATUS_NO_DRIVER 3
|
|
|
|
#define PRINTER_NAME "PrinterName"
|
|
#define DEVICE_ID "DeviceId"
|
|
|
|
NewPrinterNotification::NewPrinterNotification()
|
|
{
|
|
// Make sure the password dialog is created on the main threas
|
|
KCupsConnection::global();
|
|
|
|
// Make all our init code run on the thread since
|
|
// the DBus calls were made blocking
|
|
QTimer::singleShot(0, this, SLOT(init()));
|
|
|
|
m_thread = new QThread(this);
|
|
moveToThread(m_thread);
|
|
m_thread->start();
|
|
}
|
|
|
|
NewPrinterNotification::~NewPrinterNotification()
|
|
{
|
|
}
|
|
|
|
void NewPrinterNotification::GetReady()
|
|
{
|
|
kDebug();
|
|
// This method is all about telling the user a new printer was detected
|
|
KNotification *notify = new KNotification("GetReady");
|
|
notify->setComponentData(KComponentData("printmanager"));
|
|
notify->setPixmap(KIcon("printer").pixmap(64, 64));
|
|
notify->setTitle(i18n("A New Printer was detected"));
|
|
notify->setText(i18n("Configuring new printer..."));
|
|
notify->sendEvent();
|
|
}
|
|
|
|
//status: 0
|
|
//name: PSC_1400_series
|
|
//mfg: HP
|
|
//mdl: PSC 1400 series
|
|
//des:
|
|
//cmd: LDL,MLC,PML,DYN
|
|
void NewPrinterNotification::NewPrinter(int status,
|
|
const QString &name,
|
|
const QString &make,
|
|
const QString &model,
|
|
const QString &description,
|
|
const QString &cmd)
|
|
{
|
|
kDebug() << status << name << make << model << description << cmd;
|
|
// 1
|
|
// "usb://Samsung/SCX-3400%20Series?serial=Z6Y1BQAC500079K&interface=1"
|
|
// mfg "Samsung"
|
|
// mdl "SCX-3400 Series" "" "SPL,FWV,PIC,BDN,EXT"
|
|
// This method is all about telling the user a new printer was detected
|
|
KNotification *notify = new KNotification("NewPrinterNotification");
|
|
notify->setComponentData(KComponentData("printmanager"));
|
|
notify->setPixmap(KIcon("printer").pixmap(64, 64));
|
|
notify->setFlags(KNotification::Persistent);
|
|
|
|
QString title;
|
|
QString text;
|
|
QString devid;
|
|
QStringList actions;
|
|
devid = QString("MFG:%1;MDL:%2;DES:%3;CMD:%4;").arg(make, model, description, cmd);
|
|
|
|
if (name.contains(QLatin1Char('/'))) {
|
|
// name is a URI, no queue was generated, because no suitable
|
|
// driver was found
|
|
title = i18n("Missing printer driver");
|
|
if (!make.isEmpty() && !model.isEmpty()) {
|
|
text = i18n("No printer driver for %1 %2.", make, model);
|
|
} else if (!description.isEmpty()) {
|
|
text = i18n("No printer driver for %1.", description);
|
|
} else {
|
|
text = i18n("No driver for this printer.");
|
|
}
|
|
|
|
actions << i18n("Search");
|
|
connect(notify, SIGNAL(action1Activated()), this, SLOT(setupPrinter()));
|
|
} else {
|
|
// name is the name of the queue which hal_lpadmin has set up
|
|
// automatically.
|
|
|
|
if (status < STATUS_GENERIC_DRIVER) {
|
|
title = i18n("The New Printer was Added");
|
|
} else {
|
|
title = i18n("The New Printer is Missing Drivers");
|
|
}
|
|
|
|
QStringList attr;
|
|
attr << KCUPS_PRINTER_MAKE_AND_MODEL;
|
|
|
|
// Get the new printer attributes
|
|
QPointer<KCupsRequest> request = new KCupsRequest;
|
|
request->getPrinterAttributes(name, false, attr);
|
|
request->waitTillFinished();
|
|
if (!request) {
|
|
return;
|
|
}
|
|
|
|
QString driver;
|
|
// Get the new printer driver
|
|
if (!request->printers().isEmpty()){
|
|
KCupsPrinter printer = request->printers().first();
|
|
driver = printer.makeAndModel();
|
|
}
|
|
request->deleteLater();
|
|
|
|
QString ppdFileName;
|
|
request = new KCupsRequest;
|
|
request->getPrinterPPD(name);
|
|
request->waitTillFinished();
|
|
if (!request) {
|
|
return;
|
|
}
|
|
ppdFileName = request->printerPPD();
|
|
request->deleteLater();
|
|
|
|
// Get a list of missing executables
|
|
QStringList missingExecutables = getMissingExecutables(ppdFileName);
|
|
|
|
if (!missingExecutables.isEmpty()) {
|
|
// TODO check with PackageKit about missing drivers
|
|
kWarning();
|
|
} else if (status == STATUS_SUCCESS) {
|
|
text = i18n("'%1' is ready for printing.", name);
|
|
actions << i18n("Print test page");
|
|
connect(notify, SIGNAL(action1Activated()), this, SLOT(printTestPage()));
|
|
actions << i18n("Configure");
|
|
connect(notify, SIGNAL(action2Activated()), this, SLOT(configurePrinter()));
|
|
} else {
|
|
// Model mismatch
|
|
|
|
|
|
// The cups request might have failed
|
|
if (driver.isEmpty()) {
|
|
text = i18n("'%1' has been added, please check its driver.", name);
|
|
actions << i18n("Configure");
|
|
connect(notify, SIGNAL(action1Activated()), this, SLOT(configurePrinter()));
|
|
} else {
|
|
text = i18n("'%1' has been added, using the '%2' driver.", name, driver);
|
|
actions << i18n("Print test page");
|
|
connect(notify, SIGNAL(action1Activated()), this, SLOT(printTestPage()));
|
|
actions << i18n("Find driver");
|
|
connect(notify, SIGNAL(action2Activated()), this, SLOT(findDriver()));
|
|
}
|
|
}
|
|
}
|
|
notify->setTitle(title);
|
|
notify->setText(text);
|
|
notify->setProperty(PRINTER_NAME, name);
|
|
notify->setProperty(DEVICE_ID, devid);
|
|
notify->setActions(actions);
|
|
notify->sendEvent();
|
|
}
|
|
|
|
void NewPrinterNotification::init()
|
|
{
|
|
// Creates our new adaptor
|
|
(void) new NewPrinterNotificationAdaptor(this);
|
|
|
|
// Register the com.redhat.NewPrinterNotification interface
|
|
if (!registerService()) {
|
|
// in case registration fails due to another user or application running
|
|
// keep an eye on it so we can register when available
|
|
QDBusServiceWatcher *watcher;
|
|
watcher = new QDBusServiceWatcher(QLatin1String("com.redhat.NewPrinterNotification"),
|
|
QDBusConnection::systemBus(),
|
|
QDBusServiceWatcher::WatchForUnregistration,
|
|
this);
|
|
connect(watcher, SIGNAL(serviceUnregistered(QString)), this, SLOT(registerService()));
|
|
}
|
|
}
|
|
|
|
bool NewPrinterNotification::registerService()
|
|
{
|
|
if (!QDBusConnection::systemBus().registerService("com.redhat.NewPrinterNotification")) {
|
|
kDebug() << "unable to register service to dbus";
|
|
return false;
|
|
}
|
|
|
|
if (!QDBusConnection::systemBus().registerObject("/com/redhat/NewPrinterNotification", this)) {
|
|
kDebug() << "unable to register object to dbus";
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void NewPrinterNotification::configurePrinter()
|
|
{
|
|
QDBusMessage message;
|
|
message = QDBusMessage::createMethodCall(QLatin1String("org.kde.ConfigurePrinter"),
|
|
QLatin1String("/"),
|
|
QLatin1String("org.kde.ConfigurePrinter"),
|
|
QLatin1String("ConfigurePrinter"));
|
|
// TODO setup wid
|
|
message << sender()->property(PRINTER_NAME);
|
|
QDBusConnection::sessionBus().send(message);
|
|
}
|
|
|
|
void NewPrinterNotification::searchDrivers()
|
|
{
|
|
}
|
|
|
|
void NewPrinterNotification::printTestPage()
|
|
{
|
|
kDebug();
|
|
QPointer<KCupsRequest> request = new KCupsRequest;
|
|
request->printTestPage(sender()->property(PRINTER_NAME).toString(), false);
|
|
request->waitTillFinished();
|
|
if (request) {
|
|
request->deleteLater();
|
|
}
|
|
}
|
|
|
|
void NewPrinterNotification::findDriver()
|
|
{
|
|
kDebug();
|
|
// This function will show the PPD browser dialog
|
|
// to choose a better PPD to the already added printer
|
|
QStringList args;
|
|
args << "--change-ppd";
|
|
args << sender()->property(PRINTER_NAME).toString();
|
|
KToolInvocation::kdeinitExec(QLatin1String("kde-add-printer"), args);
|
|
}
|
|
|
|
void NewPrinterNotification::installDriver()
|
|
{
|
|
kDebug();
|
|
}
|
|
|
|
void NewPrinterNotification::setupPrinter()
|
|
{
|
|
kDebug();
|
|
// This function will show the PPD browser dialog
|
|
// to choose a better PPD, queue name, location
|
|
// in this case the printer was not added
|
|
QStringList args;
|
|
args << "--new-printer-from-device";
|
|
args << sender()->property(PRINTER_NAME).toString() % QLatin1Char('/') % sender()->property(DEVICE_ID).toString();
|
|
KToolInvocation::kdeinitExec(QLatin1String("kde-add-printer"), args);
|
|
}
|
|
|
|
QStringList NewPrinterNotification::getMissingExecutables(const QString &ppdFileName) const
|
|
{
|
|
kDebug();
|
|
QDBusMessage message;
|
|
message = QDBusMessage::createMethodCall(QLatin1String("org.fedoraproject.Config.Printing"),
|
|
QLatin1String("/org/fedoraproject/Config/Printing"),
|
|
QLatin1String("org.fedoraproject.Config.Printing"),
|
|
QLatin1String("MissingExecutables"));
|
|
message << ppdFileName;
|
|
QDBusReply<QStringList> reply = QDBusConnection::sessionBus().call(message);
|
|
if (!reply.isValid()) {
|
|
kWarning() << "Invalid reply" << reply.error();
|
|
}
|
|
return reply;
|
|
}
|