/* -*- c++ -*- * * mldonkeyapplet.cpp * * Copyright (C) 2002, 2003 Petter E. Stokke * Copyright (C) 2003 Sebastian Sauer * * 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; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "version.h" #include "appletconfig.h" #include "mldonkeyappletgui.h" #include "mldonkeyapplet.h" #include "mldonkeyapplet.moc" extern "C" { KDE_EXPORT KPanelApplet* init( QWidget *parent, const QString& configFile ) { return new MLDonkeyApplet( configFile, KPanelApplet::Normal, KPanelApplet::Preferences | KPanelApplet::About, parent, "kmldonkey" ); } } MLDonkeyApplet::MLDonkeyApplet( const QString& configFile, Type type, int actions, QWidget *parent, const char *name ) : DCOPObject("MLDonkeyAppletIface") , KPanelApplet( configFile, type, actions, parent, name ) { aboutData = new KAboutData("mldonkeyapplet", I18N_NOOP("MLDonkey Applet"), KMLDONKEY_VERSION, I18N_NOOP("

MLDonkey Applet

MLDonkey status displays and KMLDonkey launcher.

"), KAboutData::License_GPL_V2, I18N_NOOP("Copyright (C) 2002-2004 The KMLDonkey Authors"), I18N_NOOP("

Part of the KMLDonkey package.

"), "http://www.kmldonkey.org"); aboutData->addAuthor("Petter E. Stokke", I18N_NOOP("Maintainer"), "gibreel@kmldonkey.org"); aboutData->addAuthor("Sebastian Sauer", I18N_NOOP("Developer"), "mail@dipe.org"); aboutData->setTranslator(I18N_NOOP("_: NAME OF TRANSLATORS\nYour names"), I18N_NOOP("_: EMAIL OF TRANSLATORS\nYour emails")); setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed, 0, 0, sizePolicy().hasHeightForWidth() ) ); client = new DCOPClient(); client->registerAs("mldonkeyapplet", false); client->setNotifications(true); connect(client, SIGNAL(applicationRemoved(const QCString&)), this, SLOT(applicationRemoved(const QCString&))); connectDCOPSignal("kmldonkey", "KMLDonkeyIface", "kmldonkeyAppeared(bool)", "kmldonkeyAppeared(bool)", false); restoreConfiguration(); configDialog = new AppletConfig(this); connect(configDialog, SIGNAL(applyClicked()), this, SLOT(applyConfig())); connect(configDialog, SIGNAL(okClicked()), this, SLOT(applyConfig())); setFrameStyle( StyledPanel | Sunken ); QHBoxLayout *layout = new QHBoxLayout(this); layout->setAlignment(Qt::AlignRight); gui = new MLDonkeyAppletGUI(this); layout->add(gui); gui->setLaunchState(isGUIVisible()); updateLabels(); connect(gui, SIGNAL(toggledLaunch(bool)), this, SLOT(showGUI(bool))); connect(gui, SIGNAL(toggledMute(bool)), this, SLOT(muteDonkey(bool))); hostManager = new HostManager(this); donkey = new DonkeyProtocol(true, this); connect(donkey, SIGNAL(clientStats(int64, int64, int64, int, int, int, int, int, int, int, QMap*)), this, SLOT(updateStatus(int64, int64, int64, int, int, int, int, int, int, int, QMap*))); connect(donkey, SIGNAL(signalDisconnected(int)), this, SLOT(donkeyDisconnected(int))); connect(donkey, SIGNAL(signalConnected()), this, SLOT(donkeyConnected())); connect(donkey, SIGNAL(updatedDownloadFiles()), this, SLOT(updateDownloadFiles())); connect(donkey, SIGNAL(updatedDownloadedFiles()), this, SLOT(updateDownloadedFiles())); connect(donkey, SIGNAL(updatedConnectedServers()), this, SLOT(updateServers())); connect(donkey, SIGNAL(consoleMessage(QString&)), this, SLOT(consoleMessage(QString&))); connect(hostManager, SIGNAL(hostListUpdated()), this, SLOT(connectToCore())); setAcceptDrops(true); menu = new KPopupMenu(this); menu->insertTitle(SmallIcon("kmldonkey"), i18n("MLDonkey Applet")); menu->insertItem(SmallIcon("configure"), i18n("Configure MLDonkey Applet..."), 1); menu->insertSeparator(); menu->insertItem(SmallIcon("kmldonkey"), i18n("About MLDonkey Applet..."), 2); menu->insertSeparator(); menu->connectItem(1, this, SLOT(configure())); menu->connectItem(2, this, SLOT(showAbout())); menu->setCheckable(true); m_connectAction = new HostSelectAction(i18n("Connect To..."), "connect_creating", hostManager, this); m_connectAction->plug(menu); connect(m_connectAction, SIGNAL(hostSelected(HostInterface*)), SLOT(connectToCore(HostInterface*))); reconnect = 0; timer = new QTimer(this); connect( timer, SIGNAL( timeout() ), SLOT( refreshDisplay() )); timer->start(5000); connectToCore(); } MLDonkeyApplet::~MLDonkeyApplet() { delete client; } void MLDonkeyApplet::updateLabels() { QString first, second; QString tfirst, tsecond; if (activeDisplays.count() >= 1) { first = configDialog->itemTitles[activeDisplays[0]]; tfirst = configDialog->itemTooltips[activeDisplays[0]]; } if (activeDisplays.count() >= 2) { second = configDialog->itemTitles[activeDisplays[1]]; tsecond = configDialog->itemTooltips[activeDisplays[1]]; } gui->updateLabels(first, second); gui->updateTooltips(tfirst, tsecond); emit updateLayout(); } QString humanReadableSize(int64 rsz) { QString foo; double sz = (double)rsz; if (sz >= (double)(1024 * 1024 * 1024)) { sz = sz / (1024 * 1024 * 1024); foo = i18n("gigabyte suffix", "%1G").arg(KGlobal::locale()->formatNumber(sz, 1)); } else if (sz >= (double)(1024 * 1024)) { sz = sz / (1024 * 1024); foo = i18n("megabyte suffix", "%1M").arg(KGlobal::locale()->formatNumber(sz, 1)); } else if (sz >= (double)1024) { sz = sz / 1024; foo = i18n("kilobyte suffix", "%1K").arg(KGlobal::locale()->formatNumber(sz, 1)); } else foo = KGlobal::locale()->formatNumber(sz, 0); return foo; } QString MLDonkeyApplet::produceStatus(const QString& key, int64 ul, int64 dl, int64 sh, int nsh, int tul, int tdl, int uul, int udl, int ndl, int ncp) { QString txt; QTextOStream s(&txt); if (key == "speed") s << QString::number((double)(tul+uul) / 1024.0, 'f', 1) << "/" << QString::number((double)(tdl+udl) / 1024.0, 'f', 1); else if (key == "files") s << QString::number(ncp) << "/" << QString::number(ndl); else if (key == "transfer") s << humanReadableSize(ul) << "/" << humanReadableSize(dl); else if (key == "shared") s << QString::number(nsh) << "/" << humanReadableSize(sh); return txt; } void MLDonkeyApplet::updateStatus(int64 ul, int64 dl, int64 sh, int nsh, int tul, int tdl, int uul, int udl, int ndl, int ncp, QMap*) { QString first, second; if (activeDisplays.count() >= 1) first = produceStatus(activeDisplays[0], ul, dl, sh, nsh, tul, tdl, uul, udl, ndl, ncp); if (activeDisplays.count() >= 2) second = produceStatus(activeDisplays[1], ul, dl, sh, nsh, tul, tdl, uul, udl, ndl, ncp); gui->updateStatus(first, second); emit updateLayout(); //delete map; } void MLDonkeyApplet::donkeyDisconnected(int err) { switch (err) { case ProtocolInterface::AuthenticationError: QMessageBox::critical(this, i18n("KMLDonkey Applet"), i18n("Authentication error. Incorrect name or password.")); break; case ProtocolInterface::ConnectionRefusedError: reconnect = 1; break; case ProtocolInterface::HostNotFoundError: { HostInterface* host = hostManager->defaultHost(); QMessageBox::critical(this, i18n("KMLDonkey Applet"), host ? i18n("Host '%1' not found!").arg(host->address()) : i18n("No Host defined!")); } break; case ProtocolInterface::CommunicationError: if (!reconnect) QMessageBox::critical(this, i18n("KMLDonkey Applet"), i18n("Disconnected due to a communication error.")); reconnect = 1; break; case ProtocolInterface::IncompatibleProtocolError: QMessageBox::critical(this, i18n("KMLDonkey Applet"), i18n("Your mldonkey core uses an obsolete communications protocol. " "Please upgrade it to a more recent version!")); break; case ProtocolInterface::NoError: reconnect = 1; break; default: QMessageBox::critical(this, i18n("KMLDonkey Applet"), i18n("Unknown error!")); break; } gui->donkeyDisconnected(); emit updateLayout(); } void MLDonkeyApplet::donkeyConnected() { reconnect = 0; } void MLDonkeyApplet::refreshDisplay() { if (reconnect && (!donkey || !donkey->isConnected())) { if (!donkey) donkey = new DonkeyProtocol(this); connectToCore(); } } void MLDonkeyApplet::connectToCore() { connectToCore(hostManager->defaultHost()); } void MLDonkeyApplet::connectToCore(HostInterface* host) { donkey->setHost(host); donkey->connectToCore(); } void MLDonkeyApplet::restoreConfiguration() { KConfig *conf = config(); conf->setGroup("Helper"); bool usedBefore = conf->readBoolEntry("UsedBefore", false); conf->setGroup("Layout"); showLabels = conf->readBoolEntry("ShowLabels", false); showDouble = conf->readBoolEntry("ShowLabelsOnlyInDouble", false); showMute = conf->readBoolEntry("ShowMuteInSingle", true); activeDisplays = conf->readListEntry("ActiveDisplays"); if (!usedBefore && activeDisplays.empty()) { activeDisplays.push_back("files"); activeDisplays.push_back("speed"); } appletfont = KGlobalSettings::generalFont(); appletfont = conf->readFontEntry("font", &appletfont); conf->setGroup("Mute"); muteUploadRate = conf->readUnsignedNumEntry("MuteUploadRate",4); muteDownloadRate = conf->readUnsignedNumEntry("MuteDownloadRate",4); normalUploadRate = conf->readUnsignedNumEntry("NormalUploadRate",0); normalDownloadRate = conf->readUnsignedNumEntry("NormalDownloadRate",0); } void MLDonkeyApplet::writeConfiguration() { KConfig *conf = config(); conf->setGroup("Helper"); conf->writeEntry("UsedBefore", true); conf->setGroup("Layout"); conf->writeEntry("ShowLabels", showLabels); conf->writeEntry("ShowLabelsOnlyInDouble", showDouble); conf->writeEntry("ShowMuteInSingle", showMute); conf->writeEntry("ActiveDisplays", activeDisplays); conf->writeEntry("font", appletfont); conf->setGroup("Mute"); conf->writeEntry("MuteUploadRate", muteUploadRate); conf->writeEntry("MuteDownloadRate", muteDownloadRate); conf->writeEntry("NormalUploadRate", normalUploadRate); conf->writeEntry("NormalDownloadRate", normalDownloadRate); conf->sync(); } void MLDonkeyApplet::applyConfig() { showLabels = configDialog->showLabelsSelect->isChecked(); showDouble = configDialog->showDoubleSelect->isChecked(); showMute = configDialog->showMuteSelect->isChecked(); activeDisplays = configDialog->active(); appletfont = configDialog->appletFont(); normalDownloadRate = configDialog->normalDownloadEntry->value(); normalUploadRate = configDialog->normalUploadEntry->value(); muteDownloadRate = configDialog->muteDownloadEntry->value(); muteUploadRate = configDialog->muteUploadEntry->value(); writeConfiguration(); gui->updateLayout(); updateLabels(); emit updateLayout(); } void MLDonkeyApplet::preferences() { configDialog->showLabelsSelect->setChecked(showLabels); configDialog->showDoubleSelect->setChecked(showDouble); configDialog->showMuteSelect->setChecked(showMute); configDialog->setActive(activeDisplays); configDialog->setAppletFont(appletfont); configDialog->normalDownloadEntry->setValue(normalDownloadRate); configDialog->normalUploadEntry->setValue(normalUploadRate); configDialog->muteDownloadEntry->setValue(muteDownloadRate); configDialog->muteUploadEntry->setValue(muteUploadRate); configDialog->show(); } void MLDonkeyApplet::configure() { preferences(); } int MLDonkeyApplet::widthForHeight(int height) const { if (height < 32) gui->relayoutWidgets(1); else gui->relayoutWidgets(0); return gui->width(); } int MLDonkeyApplet::heightForWidth(int) const { return gui->height(); } void MLDonkeyApplet::resizeEvent(QResizeEvent* e) { KPanelApplet::resizeEvent(e); emit updateLayout(); } void MLDonkeyApplet::about() { KAboutApplication dialog(aboutData); dialog.exec(); } void MLDonkeyApplet::showAbout() { about(); } void MLDonkeyApplet::applicationRemoved(const QCString& appId) { if (appId == QCString("kmldonkey")) gui->setLaunchState(false); } void MLDonkeyApplet::showGUI(bool state) { if (state && !isGUIRunning()) { // launch gui if (KApplication::startServiceByDesktopName(QString("kmldonkey")) > 0) gui->setLaunchState(false); return; } QByteArray data; QDataStream arg(data, IO_WriteOnly); if (state) arg << true; else arg << false; client->send("kmldonkey", "KMLDonkey", "setShown(bool)", data); } bool MLDonkeyApplet::isGUIRunning() const { QCString name = "kmldonkey"; QCStringList apps = client->registeredApplications(); QCStringList::iterator it; for (it = apps.begin(); it != apps.end(); ++it) if (*it == name) return true; return false; } bool MLDonkeyApplet::isGUIVisible() const { QCString replyType; QByteArray data, replyData; QDataStream reply(replyData, IO_ReadOnly); if (!client->call("kmldonkey", "KMLDonkey", "isVisible()", data, replyType, replyData, true)) return false; if (replyType != "bool") return false; bool state; reply >> state; return state; } void MLDonkeyApplet::muteDonkey(bool m) { donkey->setOption("max_hard_upload_rate", QString::number(m ? muteUploadRate : normalUploadRate)); donkey->setOption("max_hard_download_rate", QString::number(m ? muteDownloadRate : normalDownloadRate)); } void MLDonkeyApplet::dragEnterEvent(QDragEnterEvent* event) { event->accept(QUriDrag::canDecode(event)); } void MLDonkeyApplet::dropEvent(QDropEvent* event) { KURL::List uri; if (KURLDrag::decode(event, uri)) { QValueListConstIterator it; for (it = uri.begin(); it != uri.end(); ++it) donkey->submitURL((*it).url()); } } void MLDonkeyApplet::mousePressEvent(QMouseEvent *event) { if (event == 0) return; if (event->button() == RightButton) menu->popup(mapToGlobal(event->pos())); } // DCOP methods void MLDonkeyApplet::kmldonkeyAppeared(bool a) { gui->setLaunchState(a); } void MLDonkeyApplet::mute(bool m) { gui->mute(m); } bool MLDonkeyApplet::isMute() { return gui->isMute(); }