[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-core-devel
Subject: Re: An action in KNotify
From: Olivier Goffart <ogoffart () tiscalinet ! be>
Date: 2003-08-23 7:39:59
[Download RAW message or body]
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Le Samedi 23 Août 2003 02:27, Zack Rusin a écrit :
> On Wednesday 20 August 2003 04:59, Olivier Goffart wrote:
> > What do you think?
>
> Could you please send the diff so that I could see what you've changed.
> The cross dependencies between the modules are not really an option but
> maybe we can implement exactly what you want in some other way.
I don't see how we can make the kdecore module depend from kdeui since kdeui
is compiled after.
anyway, i joined the diff.
I don't think the diff is interesting because a lot of things has changed, but
mainly, i moved a lot of code from the knotify deamon to the knotifyclient. I
just left the sound playing here to not make application dirrectly acess to
arts (i think that's why knotify is a deamon)
I did that because it is impossible to translate a QT slot with DCop
(it can be possible, but harldy, and that would be more and more slow)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (GNU/Linux)
iD8DBQE/Rxpfz58lY8jWrL0RAiUPAJ9H+FqMBLtRtP5dqlh+BX0WvLC8pQCeIuLh
vr7eCwsMeC8RXW/NWAZIqZY=
=ZkcV
-----END PGP SIGNATURE-----
["knotifyclient.diff" (text/x-diff)]
diff -updb --from-file=. ./knotifyclient.cpp \
../../kdenonbeta/kopete/libkopete/compat/knotifyclient.cpp
--- ./knotifyclient.cpp 2003-06-21 02:29:25.000000000 +0200
+++ ../../kdenonbeta/kopete/libkopete/compat/knotifyclient.cpp 2003-08-19 \
14:59:40.000000000 +0200 @@ -2,6 +2,7 @@
Copyright (C) 2000 Charles Samuels <charles@altair.dhs.org>
2000 Malte Starostik <starosti@zedat.fu-berlin.de>
2000,2003 Carsten Pfeiffer <pfeiffer@kde.org>
+ 2003 Olivier Goffart <ogoffart@tiscalinet.be>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -20,22 +21,38 @@
#include "knotifyclient.h"
-#include <qdatastream.h>
+// QT headers
+#include <qfile.h>
+#include <qvbox.h>
+#include <qsignal.h>
+#include <qfileinfo.h>
#include <qptrstack.h>
+#include <qstringlist.h>
+#include <qtextstream.h>
+#include <qdatastream.h>
-#include <kapplication.h>
-#include <kstandarddirs.h>
-#include <kapplication.h>
+
+// KDE headers
+#include <kwin.h>
+#include <kdebug.h>
#include <kconfig.h>
+#include <kglobal.h>
+#include <klocale.h>
+#include <kprocess.h>
#include <dcopclient.h>
-#include <kdebug.h>
+#include <kiconloader.h>
+#include <kmessagebox.h>
+#include <kapplication.h>
+#include <kactivelabel.h>
+#include <kpassivepopup.h>
+#include <kstandarddirs.h>
#include <kstaticdeleter.h>
+
+
static const char daemonName[] = "knotify";
-static int sendNotifyEvent(const QString &message, const QString &text,
- int present, int level, const QString &sound,
- const QString &file, int winId )
+static int notifyBySound(const QString &filename , const QString &appname, int \
uniqueId) {
if (!kapp) return 0;
@@ -47,25 +64,180 @@ static int sendNotifyEvent(const QString
return 0;
}
- int uniqueId = kMax( 1, kapp->random() ); // must not be 0 -- means failure!
+ if ( !KNotifyClient::startDaemon() )
+ return 0;
+
QByteArray data;
QDataStream ds(data, IO_WriteOnly);
- QString appname = KNotifyClient::instance()->instanceName();
- ds << message << appname << text << sound << file << present << level
- << winId << uniqueId;
- if ( !KNotifyClient::startDaemon() )
- return 0;
+#if 0 //TODO: when knotify support it, use this method insteads of the following
+ ds << filename << appname << uniqueId;
+ if ( client->send(daemonName, "Notify", "notifyBySound(QString,QString,int)", \
data) ) +#elif KDE_IS_VERSION( 3, 1, 90 )
+ ds << QString::null << appname << QString::null << filename << QString::null << 1 \
<< KNotifyClient::Default << 0 << uniqueId; if ( client->send(daemonName, "Notify", \
"notify(QString,QString,QString,QString,QString,int,int,int,int)", \
data) )
- {
return uniqueId;
- }
+#else
+ ds << QString::null << appname << QString::null << filename << QString::null << 1 \
<< KNotifyClient::Default << 0 ; + if ( client->send(daemonName, "Notify", \
"notify(QString,QString,QString,QString,QString,int,int,int)", data) ) + return \
uniqueId; +#endif
return 0;
}
+
+static bool notifyByMessagebox(const QString &text, int level, const KGuiItem \
&action , QObject* receiver , const char* slot) +{
+ // ignore empty messages
+ if ( text.isEmpty() )
+ return false;
+
+
+ if(!receiver || !slot) {
+ // display message box for specified event level
+ switch( level ) {
+ default:
+ case KNotifyClient::Notification:
+ KMessageBox::information( 0, text, i18n("Notification"), 0, false );
+ break;
+ case KNotifyClient::Warning:
+ KMessageBox::sorry( 0, text, i18n("Warning"), false );
+ break;
+ case KNotifyClient::Error:
+ KMessageBox::error( 0, text, i18n("Error"), false );
+ break;
+ case KNotifyClient::Catastrophe:
+ KMessageBox::error( 0, text, i18n("Catastrophe!"), false );
+ break;
+ }
+ } else { //we may show the specific action button
+ int result=0;
+ QSignal signal;
+ signal.connect(receiver, slot);
+ switch( level ) {
+ default:
+ case KNotifyClient::Notification:
+ result=KMessageBox::questionYesNo(0, text, i18n("Notification"), action, \
KStdGuiItem::cancel() , QString::null, false ); + break;
+ case KNotifyClient::Warning:
+ result=KMessageBox::warningYesNo( 0, text, i18n("Warning"), action, \
KStdGuiItem::cancel() , QString::null, false ); + break;
+ case KNotifyClient::Error:
+ result=KMessageBox::warningYesNo( 0, text, i18n("Error"), action, \
KStdGuiItem::cancel() , QString::null, false ); + break;
+ case KNotifyClient::Catastrophe:
+ result=KMessageBox::warningYesNo( 0, text, i18n("Catastrophe!"), action, \
KStdGuiItem::cancel() , QString::null, false ); + break;
+ }
+ if(result==KMessageBox::Yes)
+ signal.activate();
+
+ }
+
+
+ return true;
+}
+
+static bool notifyByPassivePopup( const QString &text, const QString &appName,WId \
senderWinId, + const KGuiItem &action , QObject* receiver , \
const char* slot ) +{
+ KIconLoader iconLoader( appName );
+ KConfig eventsFile( KNotifyClient::instance()->instanceName()+"/eventsrc", true, \
false, "data"); + KConfigGroup config( &eventsFile, "!Global!" );
+ QString iconName = config.readEntry( "IconName", appName );
+ QPixmap icon = iconLoader.loadIcon( iconName, KIcon::Small );
+ QString title = config.readEntry( "Comment", appName );
+ //KPassivePopup::message(title, text, icon, senderWinId);
+
+ KPassivePopup *pop = new KPassivePopup( senderWinId );
+
+ QVBox *vb = pop->standardView( title, text, icon );
+
+ if ( receiver && slot )
+ {
+ KActiveLabel *link = new KActiveLabel( "<p align=\"right\"><a href=\" \">"+ \
action.plainText() +"</a></p>", vb, "msg_label" ); + //link->setAlignment( \
AlignRight ); + QObject::disconnect(link, SIGNAL(linkClicked(const QString &)), \
link, SLOT(openLink(const QString &))); + QObject::connect(link, \
SIGNAL(linkClicked(const QString &)), receiver, slot); + QObject::connect(link, \
SIGNAL(linkClicked(const QString &)), pop, SLOT(hide())); + }
+
+ pop->setAutoDelete( true );
+ pop->setTimeout(-1);
+
+ pop->setView( vb );
+ pop->show();
+
+ return true;
+}
+
+static bool notifyByExecute(const QString &command) {
+ if (!command.isEmpty()) {
+ // kdDebug() << "executing command '" << command << "'" << endl;
+ KProcess p;
+ p.setUseShell(true);
+ p << command;
+ p.start(KProcess::DontCare);
+ return true;
+ }
+ return false;
+}
+
+
+static bool notifyByLogfile(const QString &text, const QString &file)
+{
+ // ignore empty messages
+ if ( text.isEmpty() )
+ return true;
+
+ // open file in append mode
+ QFile logFile(file);
+ if ( !logFile.open(IO_WriteOnly | IO_Append) )
+ return false;
+
+ // append msg
+ QTextStream strm( &logFile );
+ strm << "- KNotify " << QDateTime::currentDateTime().toString() << ": ";
+ strm << text << endl;
+
+ // close file
+ logFile.close();
+ return true;
+}
+
+static bool notifyByStderr(const QString &text)
+{
+ // ignore empty messages
+ if ( text.isEmpty() )
+ return true;
+
+ // open stderr for output
+ QTextStream strm( stderr, IO_WriteOnly );
+
+ // output msg
+ strm << "KNotify " << QDateTime::currentDateTime().toString() << ": ";
+ strm << text << endl;
+
+ return true;
+}
+
+static bool notifyByTaskbar( WId win )
+{
+ if( win == 0 )
+ return false;
+
+#if KDE_IS_VERSION( 3, 1, 90 )
+ KWin::demandAttention( win );
+ return true;
+#else
+ return false;
+#endif
+}
+
+
int KNotifyClient::event( StandardEvent type, const QString& text )
{
return event( 0, type, text );
@@ -83,6 +255,7 @@ int KNotifyClient::userEvent(const QStri
}
+
int KNotifyClient::event( int winId, StandardEvent type, const QString& text )
{
QString message;
@@ -105,21 +278,113 @@ int KNotifyClient::event( int winId, Sta
break;
}
- return sendNotifyEvent( message, text, Default, Default,
- QString::null, QString::null, winId );
+ return event( winId, message, text );
}
+
int KNotifyClient::event(int winId, const QString &message,
const QString &text)
{
- return sendNotifyEvent(message, text, Default, Default, QString::null, \
QString::null, winId); + return event( winId , message, text, KGuiItem() , 0L , \
0L) ; }
int KNotifyClient::userEvent(int winId, const QString &text, int present,
int level,
const QString &sound, const QString &file)
{
- return sendNotifyEvent(QString::null, text, present, level, sound, file, winId);
+ return userEvent(winId, text, present , level, sound, file, QString::null , \
KGuiItem() , 0L , 0L); +}
+
+
+
+int KNotifyClient::event(int winId, const QString &message, const QString &text,
+ const KGuiItem &action , QObject* receiver , const char* slot)
+{
+ if (message.isEmpty()) return 0;
+
+ int level=Default;
+ QString sound;
+ QString file;
+ QString commandline;
+
+ // get config file
+ KConfig eventsFile( KNotifyClient::instance()->instanceName()+"/eventsrc", true, \
false, "data"); + eventsFile.setGroup(message);
+
+ KConfig configFile( KNotifyClient::instance()->instanceName()+".eventsrc", true, \
false); + configFile.setGroup(message);
+
+ int present=getPresentation(message);
+ if(present==-1)
+ present=getDefaultPresentation(message);
+ if(present==-1)
+ present=0;
+
+ // get sound file name
+ if( present & KNotifyClient::Sound ) {
+ sound = configFile.readPathEntry( "soundfile" );
+ if ( sound.length()==0 )
+ sound = eventsFile.readPathEntry( "default_sound" );
+ }
+
+ // get log file name
+ if( present & KNotifyClient::Logfile ) {
+ file = configFile.readPathEntry( "logfile" );
+ if ( file.length()==0 )
+ file = eventsFile.readPathEntry( "default_logfile" );
+ }
+
+ // get default event level
+ if( present & KNotifyClient::Messagebox )
+ level = eventsFile.readNumEntry( "level", 0 );
+
+ // get command line
+ if (present & KNotifyClient::Execute ) {
+ commandline = configFile.readPathEntry( "commandline" );
+ if ( commandline.length()==0 )
+ commandline = eventsFile.readPathEntry( "default_commandline" );
+ }
+
+
+ return userEvent(winId, text, present , level, sound, file, commandline, \
action, receiver, slot); +}
+
+int KNotifyClient::userEvent(int winId, const QString &text, int present, int level,
+ const QString &sound, const QString &file, const \
QString& commandline, + const KGuiItem &action , \
QObject* receiver , const char* slot) +{
+ int uniqueId = kMax( 1, kapp->random() ); // must not be 0 -- means failure!
+
+ QString appname = KNotifyClient::instance()->instanceName();
+
+ if(winId==0 && kapp->mainWidget())
+ {
+ winId=kapp->mainWidget()->winId();
+ }
+
+ // emit event
+ if ( present & KNotifyClient::Sound ) // && QFile(sound).isReadable()
+ notifyBySound( sound , appname , uniqueId ) ;
+
+ if ( present & KNotifyClient::PassivePopup )
+ notifyByPassivePopup( text, appname, winId, action, receiver, slot );
+
+ else if ( present & KNotifyClient::Messagebox )
+ notifyByMessagebox( text, level, action, receiver, slot );
+
+ if ( present & KNotifyClient::Logfile ) // && QFile(file).isWritable()
+ notifyByLogfile( text, file );
+
+ if ( present & KNotifyClient::Stderr )
+ notifyByStderr( text );
+
+ if ( present & KNotifyClient::Execute )
+ notifyByExecute( commandline );
+
+ if ( present & KNotifyClient::Taskbar )
+ notifyByTaskbar( winId );
+
+ return uniqueId;
}
int KNotifyClient::getPresentation(const QString &eventname)
@@ -164,6 +429,7 @@ int KNotifyClient::getDefaultPresentatio
present=eventsfile.readNumEntry("default_presentation", -1);
return present;
+
}
QString KNotifyClient::getDefaultFile(const QString &eventname, int present)
diff -updb --from-file=. ./knotifyclient.h \
../../kdenonbeta/kopete/libkopete/compat/knotifyclient.h
--- ./knotifyclient.h 2003-08-16 21:44:57.000000000 +0200
+++ ../../kdenonbeta/kopete/libkopete/compat/knotifyclient.h 2003-08-18 \
17:50:04.000000000 +0200 @@ -15,9 +15,12 @@
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
-#ifndef _KNOTIFY_CLIENT
+#ifndef _KNOTIFY_CLIENT_
+#define _KNOTIFY_CLIENT_
#define _KNOTIFY_CLIENT
+
#include <qstring.h>
+#include <kguiitem.h>
class KInstance;
#undef None // X11 headers...
@@ -209,7 +212,6 @@ namespace KNotifyClient
//#endif
/**
- * This should be the most used method in here.
* Pass the origin-widget's winId() here so that a PassivePopup can be
* placed appropriately.
*
@@ -257,6 +259,52 @@ namespace KNotifyClient
int userEvent(int winId, const QString &text=QString::null, int present=Default, \
int level=Default,
const QString &sound=QString::null, const QString \
&file=QString::null);
+
+
+ /**
+ * This should be the most used method in here.
+ * Pass the origin-widget's winId() here so that a PassivePopup can be
+ * placed appropriately.
+ *
+ * Call it by KNotifyClient::event(widget->winId(), "EventName");
+ * It will use KApplication::kApplication->dcopClient() to communicate to
+ * the server
+ * @param winId The winId() of the widget where the event originates
+ * @param message The name of the event
+ * @param text The text to put in a dialog box. This won't be shown if
+ * the user connected the event to sound, only. Can be QString::null.
+ * @param action The text to show in the message box, or in the passive popup
+ * @param receiver The @p slot's parent
+ * @param slot The SLOT to invoque when the @p action is fired
+ * @return a value > 0, unique for this event if successful, 0 otherwise
+ * @since 3.2
+ */
+ int event( int winId, const QString& message, const QString& text ,
+ const KGuiItem& action, QObject *receiver, const char *slot);
+
+ /**
+ * Will fire an event that's not registered.
+ * You should
+ * pass the origin-widget's winId() here so that a PassivePopup can be
+ * placed appropriately.
+ * @param winId The winId() of the originating widget
+ * @param text The error message text, if applicable
+ * @param present The presentation method(s) of the event
+ * @param level The error message level, defaulting to "Default"
+ * @param sound The sound file to play if selected with @p present
+ * @param file The log file to play if selected with @p present
+ * @param commandline The command to execute if selected with @p present
+ * @param action The text to show in the message box, or in the passive popup
+ * @param receiver The @p slot's parent
+ * @param slot The SLOT to invoque when the @p action is fired
+ * @return a value > 0, unique for this event if successful, 0 otherwise
+ * @since 3.2
+ */
+ int userEvent(int winId, const QString &text, int present, int level, const QString \
&sound, + const QString &file, const QString &commandline,
+ const KGuiItem &action=KGuiItem() , QObject *receiver=0L, const char *slot=0L);
+
+
/**
* This is a simple substitution for QApplication::beep().
* It simply calls
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic