[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