• Skip to content
  • Skip to link menu
KDE 4.0 API Reference
  • KDE API Reference
  • kdeutils
  • Sitemap
  • Contact Us
 

kdelirc

irkick.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           irkick.cpp  -  Implementation of the main window
00003                              -------------------
00004     copyright            : (C) 2002 by Gav Wood
00005     email                : gav@kde.org
00006 ***************************************************************************/
00007 
00008 // This program is free software.
00009 
00010 #include <QWidget>
00011 #include <qdialog.h>
00012 
00013 #include <QRegExp>
00014 #include <QTimer>
00015 #include <qevent.h>
00016 //Added by qt3to4:
00017 #include <QMouseEvent>
00018 #include <Q3ValueList>
00019 #include <Q3CString>
00020 #include <kdeversion.h>
00021 #include <kapplication.h>
00022 #include <kaction.h>
00023 #include <kactioncollection.h>
00024 #include <ksimpleconfig.h>
00025 #include <ksystemtray.h>
00026 #include <kiconloader.h>
00027 #include <kpassivepopup.h>
00028 #include <kmessagebox.h>
00029 #include <kmenu.h>
00030 #include <kdebug.h>
00031 #include <klocale.h>
00032 #include <kwinmodule.h>
00033 #include <kwin.h>
00034 #include <khelpmenu.h>
00035 #include <kglobal.h>
00036 #include <kstdguiitem.h>
00037 
00038 #include <ktoolinvocation.h>
00039 
00040 #include "profileserver.h"
00041 #include "irkick.h"
00042 #include <QtDBus/qdbusconnection.h>
00043 
00044 void IRKTrayIcon::mousePressEvent(QMouseEvent *e)
00045 {
00046     KSystemTray::mousePressEvent(new QMouseEvent(QEvent::MouseButtonPress, e->pos(), e->globalPos(), e->button() == Qt::LeftButton ? Qt::RightButton : e->button(), e->state()));
00047 }
00048 
00049 IRKick::IRKick(const QString &obj)
00050     : QObject(), npApp(QString::null)   //krazy:exclude=nullstrassign for old broken gcc
00051 {
00052     QDBus::sessionBus().registerObject(obj, this, QDBusConnection::ExportSlots);
00053     theClient = new KLircClient();
00054 
00055     theTrayIcon = new IRKTrayIcon();
00056     if(theClient->isConnected())
00057     {   theTrayIcon->setPixmap(SmallIcon("irkick"));
00058         theTrayIcon->setToolTip( i18n("KDE Lirc Server: Ready."));
00059     }
00060     else
00061     {   theTrayIcon->setPixmap(SmallIcon("irkickoff"));
00062         theTrayIcon->setToolTip( i18n("KDE Lirc Server: No infra-red remote controls found."));
00063         QTimer::singleShot(10000, this, SLOT(checkLirc()));
00064     }
00065     theFlashOff = new QTimer(theTrayIcon);
00066     connect(theFlashOff, SIGNAL(timeout()), SLOT(flashOff()));
00067 
00068     theResetCount = 0;
00069     slotReloadConfiguration();
00070     connect(theClient, SIGNAL(connectionClosed()), this, SLOT(slotClosed()));
00071     connect(theClient, SIGNAL(remotesRead()), this, SLOT(resetModes()));
00072     connect(theClient, SIGNAL(commandReceived(const QString &, const QString &, int)), this, SLOT(gotMessage(const QString &, const QString &, int)));
00073 
00074     theTrayIcon->contextMenu()->addTitle( "IRKick");
00075     theTrayIcon->contextMenu()->insertItem(SmallIcon( "configure" ), i18n("&Configure..."), this, SLOT(slotConfigure()));
00076     theTrayIcon->contextMenu()->insertSeparator();
00077     theTrayIcon->contextMenu()->insertItem(SmallIcon( "help-contents" ), KStdGuiItem::help().text(), (new KHelpMenu(theTrayIcon, KGlobal::mainComponent().aboutData()))->menu());
00078     theTrayIcon->actionCollection()->action("file_quit")->disconnect(SIGNAL(activated()));
00079     connect(theTrayIcon->actionCollection()->action("file_quit"), SIGNAL(activated()), SLOT(doQuit()));
00080 
00081     theTrayIcon->show();
00082 }
00083 
00084 IRKick::~IRKick()
00085 {
00086     delete theTrayIcon;
00087     for(QMap<QString,IRKTrayIcon *>::iterator i = currentModeIcons.begin(); i != currentModeIcons.end(); ++i)
00088         if(*i) delete *i;
00089 }
00090 
00091 void IRKick::slotClosed()
00092 {
00093     theTrayIcon->setPixmap(SmallIcon("irkickoff"));
00094     KPassivePopup::message("IRKick", i18n("The infrared system has severed its connection. Remote controls are no longer available."), SmallIcon("irkick"), theTrayIcon);
00095     QTimer::singleShot(1000, this, SLOT(checkLirc()));
00096 }
00097 
00098 void IRKick::checkLirc()
00099 {
00100     if(!theClient->isConnected())
00101         if(theClient->connectToLirc())
00102         {   KPassivePopup::message("IRKick", i18n("A connection to the infrared system has been made. Remote controls may now be available."), SmallIcon("irkick"), theTrayIcon);
00103             theTrayIcon->setPixmap(SmallIcon("irkick"));
00104         }
00105         else
00106             QTimer::singleShot(10000, this, SLOT(checkLirc()));
00107 }
00108 
00109 void IRKick::flashOff()
00110 {
00111     theTrayIcon->setPixmap(SmallIcon("irkick"));
00112 }
00113 
00114 void IRKick::doQuit()
00115 {
00116     KSimpleConfig theConfig("irkickrc");
00117     theConfig.setGroup("General");
00118     switch(KMessageBox::questionYesNoCancel(0, i18n("Should the Infrared Remote Control server start automatically when you begin KDE?"), i18n("Automatically Start?"), i18n("Start Automatically"), i18n("Do Not Start")))
00119     {   case KMessageBox::No: theConfig.writeEntry("AutoStart", false); break;
00120         case KMessageBox::Yes: theConfig.writeEntry("AutoStart", true); break;
00121         case KMessageBox::Cancel: return;
00122     }
00123     KApplication::kApplication()->quit();
00124 }
00125 
00126 void IRKick::resetModes()
00127 {
00128     if(theResetCount > 1)
00129         KPassivePopup::message("IRKick", i18n("Resetting all modes."), SmallIcon("irkick"), theTrayIcon);
00130     if(!theResetCount)
00131         allModes.generateNulls(theClient->remotes());
00132 
00133     QStringList remotes = theClient->remotes();
00134     for(QStringList::iterator i = remotes.begin(); i != remotes.end(); ++i)
00135     {   currentModes[*i] = allModes.getDefault(*i).name();
00136         if(theResetCount && currentModeIcons[*i]) delete currentModeIcons[*i];
00137         currentModeIcons[*i] = 0;
00138     }
00139     updateModeIcons();
00140     theResetCount++;
00141 }
00142 
00143 void IRKick::slotReloadConfiguration()
00144 {
00145     // load configuration from config file
00146     KSimpleConfig theConfig("irkickrc");
00147     allActions.loadFromConfig(theConfig);
00148     allModes.loadFromConfig(theConfig);
00149     if(currentModes.count() && theResetCount)
00150         resetModes();
00151 }
00152 
00153 void IRKick::slotConfigure()
00154 {
00155     KToolInvocation::startServiceByDesktopName("kcmlirc");
00156 }
00157 
00158 void IRKick::updateModeIcons()
00159 {
00160     for(QMap<QString,QString>::iterator i = currentModes.begin(); i != currentModes.end(); ++i)
00161     {   Mode mode = allModes.getMode(i.key(), i.data());
00162         if(mode.iconFile().isNull() || mode.iconFile().isEmpty())
00163         {   if(currentModeIcons[i.key()])
00164             {   delete currentModeIcons[i.key()];
00165                 currentModeIcons[i.key()] = 0;
00166             }
00167         }
00168         else
00169         {   if(!currentModeIcons[i.key()])
00170             {   currentModeIcons[i.key()] = new IRKTrayIcon();
00171                 currentModeIcons[i.key()]->show();
00172                 currentModeIcons[i.key()]->contextMenu()->addTitle( mode.remoteName());
00173                 currentModeIcons[i.key()]->actionCollection()->action("file_quit")->setEnabled(false);
00174             }
00175             currentModeIcons[i.key()]->setPixmap(KIconLoader().loadIcon(mode.iconFile(), KIconLoader::Panel));
00176             currentModeIcons[i.key()]->setToolTip( mode.remoteName() + ": <b>" + mode.name() + "</b>");
00177         }
00178     }
00179 }
00180 
00181 bool IRKick::getPrograms(const IRAction &action, QStringList &programs)
00182 {
00183     DCOPClient *theDC = KApplication::dcopClient();
00184     programs.clear();
00185 
00186     if(action.unique())
00187     {   if(theDC->isApplicationRegistered(action.program().utf8()))
00188             programs += action.program();
00189     }
00190     else
00191     {
00192         QRegExp r = QRegExp("^" + action.program() + "-(\\d+)$");
00193         // find all instances...
00194         DCOPCStringList buf = theDC->registeredApplications();
00195         for(DCOPCStringList::iterator i = buf.begin(); i != buf.end(); ++i)
00196         {
00197             QString program = QString::fromUtf8(*i);
00198             if(program.contains(r))
00199                 programs += program;
00200         }
00201         if(programs.size() > 1 && action.ifMulti() == IM_DONTSEND)
00202             return false;
00203         else if(programs.size() > 1 && action.ifMulti() == IM_SENDTOTOP)
00204         {   Q3ValueList<WId> s = KWinModule().stackingOrder();
00205             // go through all the (ordered) window pids
00206             for(Q3ValueList<WId>::iterator i = s.fromLast(); i != s.end(); i--)
00207             {   int p = KWin::windowInfo(*i,NET::WMPid).win();
00208                 QString id = action.program() + "-" + QString().setNum(p);
00209                 if(programs.contains(id))
00210                 {   programs.clear();
00211                     programs += id;
00212                     break;
00213                 }
00214             }
00215             while(programs.size() > 1) programs.remove(programs.begin());
00216         }
00217         else if(programs.size() > 1 && action.ifMulti() == IM_SENDTOBOTTOM)
00218         {   Q3ValueList<WId> s = KWinModule().stackingOrder();
00219             // go through all the (ordered) window pids
00220             for(Q3ValueList<WId>::iterator i = s.begin(); i != s.end(); ++i)
00221             {   int p = KWin::windowInfo(*i,NET::WMPid).win();
00222                 QString id = action.program() + "-" + QString().setNum(p);
00223                 if(programs.contains(id))
00224                 {   programs.clear();
00225                     programs += id;
00226                     break;
00227                 }
00228             }
00229             while(programs.size() > 1) programs.remove(programs.begin());
00230         }
00231     }
00232     return true;
00233 }
00234 
00235 void IRKick::executeAction(const IRAction &action)
00236 {
00237     DCOPClient *theDC = KApplication::dcopClient();
00238     QStringList programs;
00239 
00240     if(!getPrograms(action, programs)) return;
00241 
00242     // if programs.size()==0 here, then the app is definately not running.
00243     if(action.autoStart() && !programs.size())
00244     {   QString sname = ProfileServer::profileServer()->getServiceName(action.program());
00245         if(!sname.isNull())
00246         {
00247             KPassivePopup::message("IRKick", i18n("Starting <b>%1</b>...", action.application()), SmallIcon("irkick"), theTrayIcon);
00248             KToolInvocation::startServiceByDesktopName(sname);
00249         }
00250     }
00251     if(action.isJustStart()) return;
00252 
00253     if(!getPrograms(action, programs)) return;
00254 
00255     for(QStringList::iterator i = programs.begin(); i != programs.end(); ++i)
00256     {   const QString &program = *i;
00257         if(theDC->isApplicationRegistered(program.utf8()))
00258         {   QByteArray data; QDataStream arg(&data, QIODevice::WriteOnly);
00259  arg.setVersion(QDataStream::Qt_3_1);
00260             kDebug() << "Sending data (" << program << ", " << action.object() << ", " << action.method().prototypeNR() ;
00261             for(Arguments::const_iterator j = action.arguments().begin(); j != action.arguments().end(); ++j)
00262             {   kDebug() << "Got argument..." ;
00263                 switch((*j).type())
00264                 {   case QVariant::Int: arg << (*j).toInt(); break;
00265                     case QVariant::CString: arg << (*j).toCString(); break;
00266                     case QVariant::StringList: arg << (*j).toStringList(); break;
00267                     case QVariant::UInt: arg << (*j).toUInt(); break;
00268                     case QVariant::Bool: arg << (*j).toBool(); break;
00269                     case QVariant::Double: arg << (*j).toDouble(); break;
00270                     default: arg << (*j).toString(); break;
00271                 }
00272             }
00273             theDC->send(program.utf8(), action.object().utf8(), action.method().prototypeNR().utf8(), data);
00274         }
00275     }
00276 }
00277 
00278 void IRKick::gotMessage(const QString &theRemote, const QString &theButton, int theRepeatCounter)
00279 {
00280     kDebug() << "Got message: " << theRemote << ": " << theButton << " (" << theRepeatCounter << ")" ;
00281     theTrayIcon->setPixmap(SmallIcon("irkickflash"));
00282     theFlashOff->start(200, true);
00283     if(!npApp.isNull())
00284     {
00285         QString theApp = npApp;
00286         npApp = QString();
00287         // send notifier by DCOP to npApp/npModule/npMethod(theRemote, theButton);
00288         QByteArray data; QDataStream arg(&data, QIODevice::WriteOnly);
00289  arg.setVersion(QDataStream::Qt_3_1);
00290         arg << theRemote << theButton;
00291         KApplication::dcopClient()->send(theApp.utf8(), npModule.utf8(), npMethod.utf8(), data);
00292     }
00293     else
00294     {
00295         if(currentModes[theRemote].isNull()) currentModes[theRemote] = "";
00296         IRAItList l = allActions.findByModeButton(Mode(theRemote, currentModes[theRemote]), theButton);
00297         if(!currentModes[theRemote].isEmpty())
00298             l += allActions.findByModeButton(Mode(theRemote, ""), theButton);
00299         bool doBefore = true, doAfter = false;
00300         for(IRAItList::const_iterator i = l.begin(); i != l.end(); ++i)
00301             if((**i).isModeChange() && !theRepeatCounter)
00302             {   // mode switch
00303                 currentModes[theRemote] = (**i).modeChange();
00304                 Mode mode = allModes.getMode(theRemote, (**i).modeChange());
00305                 updateModeIcons();
00306                 doBefore = (**i).doBefore();
00307                 doAfter = (**i).doAfter();
00308                 break;
00309             }
00310 
00311         for(int after = 0; after < 2; after++)
00312         {   if(doBefore && !after || doAfter && after)
00313                 for(IRAItList::const_iterator i = l.begin(); i != l.end(); ++i)
00314                     if(!(**i).isModeChange() && ((**i).repeat() || !theRepeatCounter))
00315                     {   executeAction(**i);
00316                     }
00317             if(!after && doAfter)
00318             {   l = allActions.findByModeButton(Mode(theRemote, currentModes[theRemote]), theButton);
00319                 if(!currentModes[theRemote].isEmpty())
00320                     l += allActions.findByModeButton(Mode(theRemote, ""), theButton);
00321             }
00322         }
00323     }
00324 }
00325 
00326 void IRKick::stealNextPress(QString app, QString module, QString method)
00327 {
00328     npApp = app;
00329     npModule = module;
00330     npMethod = method;
00331 }
00332 
00333 void IRKick::dontStealNextPress()
00334 {
00335     npApp = QString();
00336 }
00337 
00338 #include "irkick.moc"

kdelirc

Skip menu "kdelirc"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members

kdeutils

Skip menu "kdeutils"
  • ark
  • kcalc
  • kcharselect
  • kdelirc
  • kdessh
  • kdf
  • kfloppy
  • kgpg
  • kjots
  • klaptopdaemon
  • kmilo
  • ksim
  • ktimer
  • kwallet
  • superkaramba
Generated for kdeutils by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal