mirror of
https://github.com/igniterealtime/Spark.git
synced 2025-12-01 12:27:58 +00:00
Fixed GrowlPlugin for OSX10.6
!!!! No more support for Apple.Java.1.5 !!!! git-svn-id: http://svn.igniterealtime.org/svn/repos/spark/trunk@12230 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
committed by
wolf.posdorfer
parent
0e7190fab4
commit
44db6a5b26
@ -141,23 +141,17 @@ public class ApplePlugin implements Plugin, NativeHandler {
|
||||
}
|
||||
|
||||
public void flashWindow(Window window) {
|
||||
_appleUtils.bounceDockIcon(true);
|
||||
// statusMenu.showActiveIcon();
|
||||
_appleUtils.bounceDockIcon(false);
|
||||
}
|
||||
|
||||
public void flashWindowStopWhenFocused(Window window) {
|
||||
_appleUtils.bounceDockIcon(true);
|
||||
// statusMenu.showActiveIcon();
|
||||
_appleUtils.bounceDockIcon(false);
|
||||
|
||||
}
|
||||
|
||||
public void stopFlashing(Window window) {
|
||||
_appleUtils.resetDock();
|
||||
// try {
|
||||
// statusMenu.showBlackIcon();
|
||||
// } catch (Exception e) {
|
||||
// Log.error(e);
|
||||
// }
|
||||
_appleUtils.bounceDockIcon(false);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,103 @@
|
||||
package com.jivesoftware.spark.plugin.apple;
|
||||
|
||||
import java.awt.MenuItem;
|
||||
import java.awt.PopupMenu;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.UIManager.LookAndFeelInfo;
|
||||
|
||||
import org.jivesoftware.resource.Res;
|
||||
import org.jivesoftware.smack.packet.Presence;
|
||||
import org.jivesoftware.spark.PresenceManager;
|
||||
import org.jivesoftware.spark.SparkManager;
|
||||
|
||||
import com.apple.eawt.Application;
|
||||
|
||||
public class AppleTest implements ActionListener {
|
||||
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
new AppleTest();
|
||||
}
|
||||
|
||||
public AppleTest() throws InterruptedException {
|
||||
|
||||
for (LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) {
|
||||
System.out.println(laf.getClassName() + " " + laf.getName());
|
||||
}
|
||||
|
||||
System.out.println(UIManager.getLookAndFeel().getName());
|
||||
//
|
||||
// JFrame f = new JFrame("Test");
|
||||
// JButton b = new JButton("B");
|
||||
// f.add(b);
|
||||
// f.setVisible(true);
|
||||
//
|
||||
// Application app = new Application();
|
||||
// System.out.println("go to background now");
|
||||
// Thread.sleep(1500);
|
||||
//
|
||||
// System.out.println("request attention");
|
||||
// app.requestUserAttention(false);
|
||||
//
|
||||
// Thread.sleep(3000);
|
||||
// System.out.println("bounce again");
|
||||
//
|
||||
// app.requestUserAttention(false);
|
||||
//
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// MenuItem online = new MenuItem(Res.getString("status.online"));
|
||||
// online.addActionListener(this);
|
||||
//
|
||||
// MenuItem away = new MenuItem(Res.getString("status.away"));
|
||||
// away.addActionListener(this);
|
||||
//
|
||||
// MenuItem extaway = new MenuItem(Res.getString("status.extended.away"));
|
||||
// extaway.addActionListener(this);
|
||||
// MenuItem dnd = new MenuItem(Res.getString("status.do.not.disturb"));
|
||||
// dnd.addActionListener(this);
|
||||
// MenuItem onpho = new MenuItem(Res.getString("status.on.phone"));
|
||||
// onpho.addActionListener(this);
|
||||
// MenuItem ftc = new MenuItem(Res.getString("status.free.to.chat"));
|
||||
// ftc.addActionListener(this);
|
||||
// statusmenu.add(online);
|
||||
// statusmenu.add(away);
|
||||
// statusmenu.add(extaway);
|
||||
// statusmenu.add(dnd);
|
||||
// statusmenu.add(onpho);
|
||||
// statusmenu.add(ftc);
|
||||
|
||||
// menu.add(statusmenu);
|
||||
//
|
||||
// JFrame frame = new JFrame();
|
||||
// frame.setVisible(true);
|
||||
// frame.add(menu);
|
||||
//
|
||||
// // set dock menu
|
||||
// app.setDockMenu(menu);
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
|
||||
System.out.println(e.getActionCommand());
|
||||
|
||||
Presence presence = null;
|
||||
for (Presence p : PresenceManager.getPresences()) {
|
||||
if (p.getStatus().equals(e.getActionCommand())) {
|
||||
presence = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println(presence);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
<!-- Define your plugins -->
|
||||
<plugin>
|
||||
<name>Mac OSX 10.6 Plugin</name>
|
||||
<version>2.0 - OSX10.6.7</version>
|
||||
<version>2.0</version>
|
||||
<author>Wolf Posdorfer</author>
|
||||
<homePage>http://www.jivesoftware.com</homePage>
|
||||
<email>9posdorf@informatik.uni-hamburg.de</email>
|
||||
|
||||
@ -2,16 +2,20 @@
|
||||
|
||||
<property name="client.dir" value="../../.."/>
|
||||
<property name="client.lib.dir" value="${client.dir}/target/build/lib"/>
|
||||
<property name="plugin.lib.dir" value="${basedir}/build/lib"/>
|
||||
<property name="client.classes.dir" value="${client.dir}/target/classes"/>
|
||||
<property name="apple.plugin.classes" value="../apple/classes"/>
|
||||
|
||||
<property name="target.dir" value="${basedir}/target"/>
|
||||
<property name="target.lib.dir" value="${basedir}/target/lib"/>
|
||||
<property name="classes.dir" value="${basedir}/classes"/>
|
||||
<property name="src.dir" value="${basedir}/src"/>
|
||||
<property name="jar.file" value="${client.dir}/target/build/plugins/growl.jar"/>
|
||||
|
||||
<path id="lib.classpath">
|
||||
<fileset dir="${client.lib.dir}" includes="**/*.jar"/>
|
||||
<fileset dir="${plugin.lib.dir}" includes="**/*.jar"/>
|
||||
<fileset dir="${plugin.lib.dir}" includes="**/*.jnilib"/>
|
||||
<pathelement location="/System/Library/Java"/>
|
||||
<pathelement location="${client.classes.dir}"/>
|
||||
<pathelement location="${apple.plugin.classes}"/>
|
||||
@ -28,22 +32,39 @@
|
||||
<javac srcdir="${src.dir}"
|
||||
destdir="${classes.dir}"
|
||||
classpathref="lib.classpath"
|
||||
source="1.5"
|
||||
source="1.6"
|
||||
debug="true"
|
||||
target="1.5"/>
|
||||
target="1.6"/>
|
||||
|
||||
</target>
|
||||
|
||||
<target name="jar.classes" depends="compile">
|
||||
<mkdir dir="${target.dir}/lib"/>
|
||||
<jar basedir="${classes.dir}" file="${target.dir}/lib/growl.jar"/>
|
||||
<jar basedir="${classes.dir}" file="${target.dir}/lib/growl.jar">
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="jar" depends="clean,jar.classes">
|
||||
<copy todir="${target.dir}">
|
||||
<fileset dir="${src.dir}" includes="**/*.xml"/>
|
||||
</copy>
|
||||
<copy todir="${target.lib.dir}">
|
||||
<fileset file="${plugin.lib.dir}/*.*"/>
|
||||
</copy>
|
||||
<jar basedir="${target.dir}" file="${jar.file}" update="false"/>
|
||||
</target>
|
||||
|
||||
<target name="jni-compile">
|
||||
<mkdir dir="${target.dir}"/>
|
||||
|
||||
<javac srcdir="src"
|
||||
destdir="${target.dir}"
|
||||
classpathref="lib.classpath"
|
||||
source="1.6"
|
||||
debug="true"
|
||||
target="1.6"/>
|
||||
|
||||
<javah destdir="src/" class="com.jivesoftware.spark.plugin.growl.GrowlNative" classpath="${target.dir}"/>
|
||||
</target>
|
||||
|
||||
</project>
|
||||
|
||||
BIN
src/plugins/growl/build/lib/libgrowl.jnilib
Normal file
BIN
src/plugins/growl/build/lib/libgrowl.jnilib
Normal file
Binary file not shown.
@ -1,474 +0,0 @@
|
||||
/**
|
||||
* $RCSfile: ,v $
|
||||
* $Revision: $
|
||||
* $Date: $
|
||||
*
|
||||
* Copyright (C) 2004-2010 Jive Software. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jivesoftware.spark.plugin.growl;
|
||||
|
||||
import com.apple.cocoa.foundation.NSDistributedNotificationCenter;
|
||||
import com.apple.cocoa.foundation.NSArray;
|
||||
import com.apple.cocoa.foundation.NSDictionary;
|
||||
import com.apple.cocoa.foundation.NSMutableDictionary;
|
||||
import com.apple.cocoa.foundation.NSData;
|
||||
import com.apple.cocoa.application.NSImage;
|
||||
|
||||
/**
|
||||
* A class that encapsulates the "work" of talking to growl
|
||||
*
|
||||
* @author Karl Adam
|
||||
*/
|
||||
public class Growl {
|
||||
|
||||
// defines
|
||||
/** The name of the growl registration notification for DNC. */
|
||||
public static final String GROWL_APP_REGISTRATION = "GrowlApplicationRegistrationNotification";
|
||||
|
||||
// Ticket Defines
|
||||
/** Ticket key for the application name. */
|
||||
public static final String GROWL_APP_NAME = "ApplicationName";
|
||||
/** Ticket key for the application icon. */
|
||||
public static final String GROWL_APP_ICON = "ApplicationIcon";
|
||||
/** Ticket key for the default notifactions. */
|
||||
public static final String GROWL_NOTIFICATIONS_DEFAULT = "DefaultNotifications";
|
||||
/** Ticket key for all notifactions. */
|
||||
public static final String GROWL_NOTIFICATIONS_ALL = "AllNotifications";
|
||||
|
||||
// Notification Defines
|
||||
/** The name of the growl notification for DNC. */
|
||||
public static final String GROWL_NOTIFICATION = "GrowlNotification";
|
||||
/** Notification key for the name. */
|
||||
public static final String GROWL_NOTIFICATION_NAME = "NotificationName";
|
||||
/** Notification key for the title. */
|
||||
public static final String GROWL_NOTIFICATION_TITLE = "NotificationTitle";
|
||||
/** Notification key for the description. */
|
||||
public static final String GROWL_NOTIFICATION_DESCRIPTION = "NotificationDescription";
|
||||
/** Notification key for the icon. */
|
||||
public static final String GROWL_NOTIFICATION_ICON = "NotificationIcon";
|
||||
/** Notification key for the application icon. */
|
||||
public static final String GROWL_NOTIFICATION_APP_ICON = "NotificationAppIcon";
|
||||
/** Notification key for the sticky flag. */
|
||||
public static final String GROWL_NOTIFICATION_STICKY = "NotificationSticky";
|
||||
|
||||
// Actual instance data
|
||||
private boolean registered; // We should only register once
|
||||
private String appName; // "Application" Name
|
||||
private NSData appImageData; // "application" Icon
|
||||
private NSArray allNotes; // All notifications
|
||||
private NSArray defNotes; // Default Notifications
|
||||
private NSDistributedNotificationCenter theCenter;
|
||||
|
||||
//************ Constructors **************//
|
||||
|
||||
/**
|
||||
* Convenience method to contruct a growl instance, defers to Growl(String
|
||||
* inAppName, NSData inImageData, NSArray inAllNotes, NSArray inDefNotes,
|
||||
* boolean registerNow) with empty arrays for your notifications.
|
||||
*
|
||||
*
|
||||
* @param inAppName - The Name of your "application"
|
||||
* @param inImage - The NSImage Icon for your Application
|
||||
*
|
||||
*/
|
||||
public Growl(String inAppName, NSImage inImage) {
|
||||
|
||||
this(inAppName,
|
||||
inImage.TIFFRepresentation(),
|
||||
new NSArray(),
|
||||
new NSArray(),
|
||||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to contruct a growl instance, defers to Growl(String
|
||||
* inAppName, NSData inImageData, NSArray inAllNotes, NSArray inDefNotes,
|
||||
* boolean registerNow) with empty arrays for your notifications.
|
||||
*
|
||||
* @param inAppName - The Name of your "Application"
|
||||
* @param inImageData - The NSData for your NSImage
|
||||
*/
|
||||
public Growl(String inAppName, NSData inImageData) {
|
||||
|
||||
this(inAppName,
|
||||
inImageData,
|
||||
new NSArray(),
|
||||
new NSArray(),
|
||||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to contruct a growl instance, defers to Growl(String
|
||||
* inAppName, NSData inImageData, NSArray inAllNotes, NSArray inDefNotes,
|
||||
* boolean registerNow) with empty arrays for your notifications.
|
||||
*
|
||||
* @param inAppName - The Name of your "Application"
|
||||
* @param inImagePath - The path to your icon
|
||||
*
|
||||
*/
|
||||
public Growl(String inAppName, String inImagePath) {
|
||||
|
||||
this(inAppName,
|
||||
new NSImage(inImagePath, false).TIFFRepresentation(),
|
||||
new NSArray(),
|
||||
new NSArray(),
|
||||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to contruct a growl instance, defers to Growl(String
|
||||
* inAppName, NSData inImageData, NSArray inAllNotes, NSArray inDefNotes,
|
||||
* boolean registerNow) with the arrays passed here and empty Data for the icon.
|
||||
*
|
||||
* @param inAppName - The Name of your "Application"
|
||||
* @param inAllNotes - A String Array with the name of all your notifications
|
||||
* @param inDefNotes - A String Array with the na,es of the Notifications on
|
||||
* by default
|
||||
*/
|
||||
public Growl(String inAppName, String [] inAllNotes, String [] inDefNotes) {
|
||||
|
||||
this(inAppName,
|
||||
new NSData(),
|
||||
new NSArray(inAllNotes),
|
||||
new NSArray(inDefNotes),
|
||||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to contruct a growl instance, defers to Growl(String
|
||||
* inAppName, NSData inImageData, NSArray inAllNotes, NSArray inDefNotes,
|
||||
* boolean registerNow) with empty arrays for your notifications.
|
||||
*
|
||||
* @param inAppName - The Name of your "Application"
|
||||
* @param inImageData - The Data of your "Application"'s icon
|
||||
* @param inAllNotes - The NSArray of Strings of all your Notifications
|
||||
* @param inDefNotes - The NSArray of Strings of your default Notifications
|
||||
* @param registerNow - Since we have all the necessary info we can go ahead
|
||||
* and register
|
||||
*/
|
||||
public Growl(String inAppName, NSData inImageData, NSArray inAllNotes,
|
||||
NSArray inDefNotes, boolean registerNow) {
|
||||
appName = inAppName;
|
||||
appImageData = inImageData;
|
||||
allNotes = inAllNotes;
|
||||
defNotes = inDefNotes;
|
||||
|
||||
theCenter = (NSDistributedNotificationCenter)NSDistributedNotificationCenter.defaultCenter();
|
||||
|
||||
if (registerNow) {
|
||||
register();
|
||||
}
|
||||
}
|
||||
|
||||
//************ Commonly Used Methods **************//
|
||||
|
||||
/**
|
||||
* Register all our notifications with Growl, this should only be called
|
||||
* once.
|
||||
* @return <code>true</code>.
|
||||
*/
|
||||
public boolean register() {
|
||||
if (!registered) {
|
||||
|
||||
// Construct our dictionary
|
||||
// Make the arrays of objects then keys
|
||||
Object [] objects = { appName, allNotes, defNotes, appImageData };
|
||||
String [] keys = { GROWL_APP_NAME,
|
||||
GROWL_NOTIFICATIONS_ALL,
|
||||
GROWL_NOTIFICATIONS_DEFAULT,
|
||||
GROWL_APP_ICON};
|
||||
|
||||
// Make the Dictionary
|
||||
NSDictionary regDict = new NSDictionary(objects, keys);
|
||||
|
||||
theCenter.postNotification(GROWL_APP_REGISTRATION, // notificationName
|
||||
null, // anObject
|
||||
regDict, // userInfoDictionary
|
||||
true); // deliverImmediately
|
||||
|
||||
registered = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* The fun part is actually sending those notifications we worked so hard for
|
||||
* so here we let growl know about things we think the user would like, and growl
|
||||
* decides if that is the case.
|
||||
*
|
||||
* @param inNotificationName - The name of one of the notifications we told growl
|
||||
* about.
|
||||
* @param inIconData - The NSData for the icon for this notification, can be null
|
||||
* @param inTitle - The Title of our Notification as Growl will show it
|
||||
* @param inDescription - The Description of our Notification as Growl will
|
||||
* display it
|
||||
* @param inExtraInfo - Growl is flexible and allows Display Plugins to do as they
|
||||
* please with thier own special keys and values, you may use
|
||||
* them here. These may be ignored by either the user's
|
||||
* preferences or the current Display Plugin. This can be null
|
||||
* @param inSticky - Whether the Growl notification should be sticky
|
||||
*
|
||||
* @throws Exception When a notification is not known
|
||||
*/
|
||||
public void notifyGrowlOf(String inNotificationName, NSData inIconData,
|
||||
String inTitle, String inDescription,
|
||||
NSDictionary inExtraInfo, boolean inSticky) throws Exception {
|
||||
NSMutableDictionary noteDict = new NSMutableDictionary();
|
||||
|
||||
if (!allNotes.containsObject(inNotificationName)) {
|
||||
throw new Exception("Undefined Notification attempted");
|
||||
}
|
||||
|
||||
noteDict.setObjectForKey(inNotificationName, GROWL_NOTIFICATION_NAME);
|
||||
noteDict.setObjectForKey(inTitle, GROWL_NOTIFICATION_TITLE);
|
||||
noteDict.setObjectForKey(inDescription, GROWL_NOTIFICATION_DESCRIPTION);
|
||||
noteDict.setObjectForKey(appName, GROWL_APP_NAME);
|
||||
if (inIconData != null) {
|
||||
noteDict.setObjectForKey(inIconData, GROWL_NOTIFICATION_ICON);
|
||||
}
|
||||
|
||||
if (inSticky) {
|
||||
noteDict.setObjectForKey(1, GROWL_NOTIFICATION_STICKY);
|
||||
}
|
||||
|
||||
if (inExtraInfo != null) {
|
||||
noteDict.addEntriesFromDictionary(inExtraInfo);
|
||||
}
|
||||
|
||||
theCenter.postNotification(GROWL_NOTIFICATION,
|
||||
null,
|
||||
noteDict,
|
||||
true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method that defers to notifyGrowlOf(String inNotificationName,
|
||||
* NSData inIconData, String inTitle, String inDescription,
|
||||
* NSDictionary inExtraInfo, boolean inSticky)
|
||||
* This is primarily for compatibility with older code
|
||||
*
|
||||
* @param inNotificationName - The name of one of the notifications we told growl
|
||||
* about.
|
||||
* @param inIconData - The NSData for the icon for this notification, can be null
|
||||
* @param inTitle - The Title of our Notification as Growl will show it
|
||||
* @param inDescription - The Description of our Notification as Growl will
|
||||
* display it
|
||||
* @param inExtraInfo - Growl is flexible and allows Display Plugins to do as
|
||||
* they please with their own special keys and values, you
|
||||
* may use them here. These may be ignored by either the
|
||||
* user's preferences or the current Display Plugin. This
|
||||
* can be null.
|
||||
*
|
||||
* @throws Exception When a notification is not known
|
||||
*
|
||||
*/
|
||||
public void notifyGrowlOf(String inNotificationName, NSData inIconData,
|
||||
String inTitle, String inDescription,
|
||||
NSDictionary inExtraInfo) throws Exception {
|
||||
|
||||
notifyGrowlOf(inNotificationName, inIconData, inTitle, inDescription,
|
||||
inExtraInfo, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenienve method that defers to notifyGrowlOf(String inNotificationName,
|
||||
* NSData inIconData, String inTitle, String inDescription,
|
||||
* NSDictionary inExtraInfo) with null passed for icon and extraInfo arguments
|
||||
*
|
||||
* @param inNotificationName - The name of one of the notifications we told growl
|
||||
* about.
|
||||
* @param inTitle - The Title of our Notification as Growl will show it
|
||||
* @param inDescription - The Description of our Notification as Growl will
|
||||
* display it
|
||||
*
|
||||
* @throws Exception When a notification is not known
|
||||
*/
|
||||
public void notifyGrowlOf(String inNotificationName, String inTitle,
|
||||
String inDescription) throws Exception {
|
||||
notifyGrowlOf(inNotificationName, null,
|
||||
inTitle, inDescription, null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method that defers to notifyGrowlOf(String inNotificationName,
|
||||
* NSData inIconData, String inTitle, String inDescription,
|
||||
* NSDictionary inExtraInfo, boolean inSticky)
|
||||
* with null passed for icon and extraInfo arguments
|
||||
*
|
||||
* @param inNotificationName - The name of one of the notifications we told growl
|
||||
* about.
|
||||
* @param inTitle - The Title of our Notification as Growl will show it
|
||||
* @param inDescription - The Description of our Notification as Growl will
|
||||
* display it
|
||||
* @param inSticky - Whether our notification should be sticky
|
||||
*
|
||||
* @throws Exception When a notification is not known
|
||||
*
|
||||
*/
|
||||
public void notifyGrowlOf(String inNotificationName, String inTitle,
|
||||
String inDescription, boolean inSticky) throws Exception {
|
||||
notifyGrowlOf(inNotificationName, null,
|
||||
inTitle, inDescription, null, inSticky);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defers to notifyGrowlOf(String inNotificationName, NSData inIconData,
|
||||
* String inTitle, String inDescription, NSDictionary inExtraInfo) with null
|
||||
* passed for icon and extraInfo arguments
|
||||
*
|
||||
* @param inNotificationName - The name of one of the notifications we told growl
|
||||
* about.
|
||||
* @param inImage - The notification image.
|
||||
* @param inTitle - The Title of our Notification as Growl will show it
|
||||
* @param inDescription - The Description of our Notification as Growl will
|
||||
* display it
|
||||
* @param inExtraInfo - Look above for info
|
||||
*
|
||||
* @throws Exception When a notification is not known
|
||||
*
|
||||
*/
|
||||
public void notifyGrowlOf(String inNotificationName, NSImage inImage,
|
||||
String inTitle, String inDescription,
|
||||
NSDictionary inExtraInfo) throws Exception {
|
||||
|
||||
notifyGrowlOf(inNotificationName, inImage.TIFFRepresentation(),
|
||||
inTitle, inDescription, inExtraInfo, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenienve method that defers to notifyGrowlOf(String inNotificationName,
|
||||
* NSData inIconData, String inTitle, String inDescription,
|
||||
* NSDictionary inExtraInfo) with null passed for extraInfo
|
||||
*
|
||||
* @param inNotificationName - The name of one of the notifications we told growl
|
||||
* about.
|
||||
* @param inImagePath - Path to the image for this notification
|
||||
* @param inTitle - The Title of our Notification as Growl will show it
|
||||
* @param inDescription - The Description of our Notification as Growl will
|
||||
* display it
|
||||
*
|
||||
* @throws Exception When a notification is not known
|
||||
*/
|
||||
public void notifyGrowlOf(String inNotificationName, String inImagePath,
|
||||
String inTitle, String inDescription) throws Exception {
|
||||
|
||||
notifyGrowlOf(inNotificationName,
|
||||
new NSImage(inImagePath, false).TIFFRepresentation(),
|
||||
inTitle, inDescription, null, false);
|
||||
}
|
||||
|
||||
//************ Accessors **************//
|
||||
|
||||
/**
|
||||
* Accessor for The currently set "Application" Name
|
||||
*
|
||||
* @return String - Application Name
|
||||
*/
|
||||
public String applicationName() {
|
||||
return appName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the Array of allowed Notifications returned an NSArray
|
||||
*
|
||||
* @return the array of allowed notifications.
|
||||
*/
|
||||
public NSArray allowedNotifications() {
|
||||
return allNotes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the Array of default Notifications returned as an NSArray
|
||||
*
|
||||
* @return the array of default notifications.
|
||||
*/
|
||||
public NSArray defaultNotifications() {
|
||||
return defNotes;
|
||||
}
|
||||
|
||||
//************ Mutators **************//
|
||||
|
||||
/**
|
||||
* Sets The name of the Application talking to growl
|
||||
*
|
||||
* @param inAppName - The Application Name
|
||||
*/
|
||||
public void setApplicationName(String inAppName) {
|
||||
appName = inAppName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the list of allowed Notifications
|
||||
*
|
||||
* @param inAllNotes - The array of allowed Notifications
|
||||
*/
|
||||
public void setAllowedNotifications(NSArray inAllNotes) {
|
||||
allNotes = inAllNotes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the list of allowed Notifications
|
||||
*
|
||||
* @param inAllNotes - The array of allowed Notifications
|
||||
*
|
||||
*/
|
||||
public void setAllowedNotifications(String[] inAllNotes) {
|
||||
allNotes = new NSArray(inAllNotes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the list of Default Notfiications
|
||||
*
|
||||
* @param inDefNotes - The default Notifications
|
||||
*
|
||||
* @throws Exception when an element of the array is not in the
|
||||
* allowedNotifications
|
||||
*/
|
||||
public void setDefaultNotifications(NSArray inDefNotes) throws Exception {
|
||||
int stop = inDefNotes.count();
|
||||
int i;
|
||||
|
||||
for(i = 0; i < stop; i++) {
|
||||
if (!allNotes.containsObject(inDefNotes.objectAtIndex(i))) {
|
||||
throw new Exception("Array Element not in Allowed Notifications");
|
||||
}
|
||||
}
|
||||
|
||||
defNotes = inDefNotes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the list of Default Notfiications
|
||||
*
|
||||
* @param inDefNotes - The default Notifications
|
||||
*
|
||||
* @throws Exception when an element of the array is not in the
|
||||
* allowedNotifications
|
||||
*
|
||||
*/
|
||||
public void setDefaultNotifications(String [] inDefNotes) throws Exception {
|
||||
int stop = inDefNotes.length;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < stop; i++) {
|
||||
if (! allNotes.containsObject(inDefNotes[i])) {
|
||||
throw new Exception("Array Element not in Allowed Notifications");
|
||||
}
|
||||
}
|
||||
|
||||
defNotes = new NSArray(inDefNotes);
|
||||
}
|
||||
}
|
||||
@ -19,124 +19,80 @@
|
||||
*/
|
||||
package com.jivesoftware.spark.plugin.growl;
|
||||
|
||||
import com.apple.cocoa.application.NSImage;
|
||||
import com.apple.cocoa.foundation.NSData;
|
||||
import info.growl.GrowlException;
|
||||
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
import org.jivesoftware.smackx.packet.VCard;
|
||||
import org.jivesoftware.spark.SparkManager;
|
||||
import org.jivesoftware.spark.ui.ChatFrame;
|
||||
import org.jivesoftware.spark.ui.ChatRoom;
|
||||
import org.jivesoftware.spark.ui.GlobalMessageListener;
|
||||
import org.jivesoftware.spark.util.log.Log;
|
||||
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* @author Andrew Wright
|
||||
* {@link GrowlMessageListener} implements the {@link GlobalMessageListener} and
|
||||
* creates Growl Notifications on Message received
|
||||
*
|
||||
* @author Wolf.Posdorfer
|
||||
*/
|
||||
public class GrowlMessageListener implements GlobalMessageListener {
|
||||
|
||||
private Growl growl;
|
||||
private GrowlTalker _growltalker;
|
||||
|
||||
public GrowlMessageListener() {
|
||||
String[] notes = {"Message Received"};
|
||||
growl = new Growl("Spark", notes, notes);
|
||||
growl.register();
|
||||
try {
|
||||
|
||||
_growltalker = new GrowlTalker();
|
||||
} catch (GrowlException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void messageReceived(final ChatRoom chatRoom, final Message message) {
|
||||
final ChatFrame chatFrame = SparkManager.getChatManager().getChatContainer().getChatFrame();
|
||||
|
||||
if (!chatFrame.isVisible() || !chatFrame.isInFocus()) {
|
||||
showGrowlNotification(message);
|
||||
}
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
|
||||
}
|
||||
@Override
|
||||
public void run() {
|
||||
final ChatFrame chatFrame = SparkManager.getChatManager().getChatContainer()
|
||||
.getChatFrame();
|
||||
|
||||
private void showGrowlNotification(final Message message) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
if (!chatFrame.isInFocus()) {
|
||||
showGrowlNotification(message);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
String name = SparkManager.getUserManager().getUserNicknameFromJID(message.getFrom());
|
||||
|
||||
// Since it looks the method can return null do this in case
|
||||
if (name == null) {
|
||||
name = StringUtils.parseName(message.getFrom());
|
||||
}
|
||||
|
||||
VCard vCard = null;
|
||||
|
||||
try {
|
||||
vCard = SparkManager.getVCardManager().getVCard(
|
||||
StringUtils.parseBareAddress(message.getFrom()));
|
||||
}
|
||||
catch (Exception e) {
|
||||
// vcard can time out so ignore
|
||||
}
|
||||
|
||||
NSImage image = null;
|
||||
if (vCard != null) {
|
||||
byte[] bytes = vCard.getAvatar();
|
||||
if (bytes != null) {
|
||||
try {
|
||||
NSData data = new NSData(bytes);
|
||||
image = new NSImage(data);
|
||||
}
|
||||
catch (Exception e) {
|
||||
// just incase there is an error i didn't intend
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (image == null) {
|
||||
image = getImage("/images/message-32x32.png");
|
||||
}
|
||||
|
||||
growl.notifyGrowlOf("Message Received", image, name, message.getBody(), null);
|
||||
|
||||
}
|
||||
catch (Exception e) {
|
||||
Log.error(e.getMessage(), e);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void messageSent(ChatRoom room, Message message) {
|
||||
// Ignore
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link com.apple.cocoa.application.NSImage} from a string that points to an image in the class
|
||||
*
|
||||
* @param image classpath path of an image
|
||||
* @return an cocoa image object
|
||||
* Show a global Growl Notification
|
||||
*
|
||||
* @param message
|
||||
* , {@link Message} containing Body and Sender
|
||||
*/
|
||||
private NSImage getImage(String image) {
|
||||
InputStream in = this.getClass().getResourceAsStream(image);
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
private void showGrowlNotification(Message message) {
|
||||
try {
|
||||
String name = SparkManager.getUserManager().getUserNicknameFromJID(message.getFrom());
|
||||
String jid = message.getFrom();
|
||||
|
||||
byte[] buff = new byte[10 * 1024];
|
||||
int len;
|
||||
try {
|
||||
while ((len = in.read(buff)) != -1) {
|
||||
out.write(buff, 0, len);
|
||||
}
|
||||
in.close();
|
||||
out.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
Log.error(e.getMessage(), e);
|
||||
}
|
||||
if (name == null) {
|
||||
name = StringUtils.parseName(message.getFrom());
|
||||
}
|
||||
|
||||
_growltalker.sendNotificationWithCallback(name, message.getBody(), jid);
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.error(e.getMessage(), e);
|
||||
}
|
||||
|
||||
NSData data = new NSData(out.toByteArray());
|
||||
return new NSImage(data);
|
||||
}
|
||||
|
||||
public void messageSent(ChatRoom room, Message message) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -19,37 +19,101 @@
|
||||
*/
|
||||
package com.jivesoftware.spark.plugin.growl;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.jivesoftware.Spark;
|
||||
import org.jivesoftware.spark.SparkManager;
|
||||
import org.jivesoftware.spark.plugin.Plugin;
|
||||
|
||||
|
||||
/**
|
||||
* Provides support for Growl Notifications on Mac OS X. Growl can be acquired at
|
||||
* http://growl.info
|
||||
*
|
||||
*
|
||||
* @author Andrew Wright
|
||||
* Provides support for Growl Notifications on Mac OS X. Growl can be acquired
|
||||
* at http://growl.info
|
||||
*
|
||||
*
|
||||
* @author Wolf.Posdorfer
|
||||
*/
|
||||
public class GrowlPlugin implements Plugin {
|
||||
|
||||
private GrowlMessageListener growlListener;
|
||||
|
||||
|
||||
public void initialize() {
|
||||
growlListener = new GrowlMessageListener();
|
||||
SparkManager.getChatManager().addGlobalMessageListener(growlListener);
|
||||
boolean b = placeLibs();
|
||||
try {
|
||||
Thread.sleep(1500);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
|
||||
if (!b) {
|
||||
placeLibs();
|
||||
try {
|
||||
Thread.sleep(1500);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
|
||||
GrowlPreference preference = new GrowlPreference();
|
||||
// SparkManager.getPreferenceManager().addPreference(preference);
|
||||
growlListener = new GrowlMessageListener();
|
||||
SparkManager.getChatManager().addGlobalMessageListener(growlListener);
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
SparkManager.getChatManager().removeGlobalMessageListener(growlListener);
|
||||
SparkManager.getChatManager().removeGlobalMessageListener(growlListener);
|
||||
}
|
||||
|
||||
public boolean canShutDown() {
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void uninstall() {
|
||||
SparkManager.getChatManager().removeGlobalMessageListener(growlListener);
|
||||
SparkManager.getChatManager().removeGlobalMessageListener(growlListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Places the libgrowl.jnilib into /Library/Java/Extensions
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private boolean placeLibs() {
|
||||
|
||||
boolean result = false;
|
||||
|
||||
File f = new File("/Library/Java/Extensions/libgrowl.jnilib");
|
||||
|
||||
if (f.exists()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
String home = Spark.getUserHome() + "/Spark/plugins/growl/lib/";
|
||||
File library = new File(home + "libgrowl.jnilib");
|
||||
|
||||
System.out.println(f.exists() + " " + library.exists());
|
||||
|
||||
try {
|
||||
InputStream in = new FileInputStream(library);
|
||||
OutputStream out = new FileOutputStream(f);
|
||||
|
||||
// Transfer bytes from in to out
|
||||
byte[] buf = new byte[1024];
|
||||
int len;
|
||||
while ((len = in.read(buf)) > 0) {
|
||||
out.write(buf, 0, len);
|
||||
}
|
||||
in.close();
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
result = f.exists();
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,118 @@
|
||||
/**
|
||||
* $RCSfile: ,v $
|
||||
* $Revision: $
|
||||
* $Date: $
|
||||
*
|
||||
* Copyright (C) 2004-2010 Jive Software. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jivesoftware.spark.plugin.growl;
|
||||
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import org.jivesoftware.resource.SparkRes;
|
||||
import org.jivesoftware.spark.preference.Preference;
|
||||
|
||||
/**
|
||||
*
|
||||
* Simple Class for GrowlPreference Panel <br>
|
||||
* currently not in use
|
||||
*
|
||||
* @author wolf.posdorfer
|
||||
*
|
||||
*/
|
||||
public class GrowlPreference implements Preference {
|
||||
|
||||
JPanel _panel;
|
||||
private static final long serialVersionUID = 7485099198887907166L;
|
||||
|
||||
public GrowlPreference() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commit() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getData() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getErrorMessage() {
|
||||
return "error with growlplugin";
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getGUI() {
|
||||
_panel = new JPanel();
|
||||
JButton button = new JButton("Test");
|
||||
JButton button2 = new JButton("test2");
|
||||
|
||||
_panel.add(button);
|
||||
_panel.add(button2);
|
||||
|
||||
return _panel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Icon getIcon() {
|
||||
return SparkRes.getImageIcon(SparkRes.DUMMY_CONTACT_IMAGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getListName() {
|
||||
return "growl";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNamespace() {
|
||||
|
||||
return "growler";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
|
||||
return "GROWL";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTooltip() {
|
||||
|
||||
return "tooltip";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDataValid() {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,99 @@
|
||||
/**
|
||||
* $RCSfile: ,v $
|
||||
* $Revision: $
|
||||
* $Date: $
|
||||
*
|
||||
* Copyright (C) 2004-2011 Jive Software. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jivesoftware.spark.plugin.growl;
|
||||
|
||||
import info.growl.Growl;
|
||||
import info.growl.GrowlCallbackListener;
|
||||
import info.growl.GrowlException;
|
||||
import info.growl.GrowlUtils;
|
||||
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
import org.jivesoftware.spark.SparkManager;
|
||||
import org.jivesoftware.spark.ui.ChatRoom;
|
||||
import org.jivesoftware.spark.util.log.Log;
|
||||
|
||||
/**
|
||||
* GrowlTalker Class to send Messages to the GrowlInstance
|
||||
*
|
||||
* @author Wolf.Posdorfer
|
||||
*
|
||||
*/
|
||||
public class GrowlTalker implements GrowlCallbackListener {
|
||||
|
||||
private Growl _growl;
|
||||
private final String SPARK = "Spark";
|
||||
|
||||
public GrowlTalker() throws GrowlException {
|
||||
|
||||
_growl = GrowlUtils.getGrowlInstance(SPARK);
|
||||
|
||||
_growl.addNotification(SPARK, true);
|
||||
_growl.addCallbackListener(this);
|
||||
|
||||
_growl.register();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notificationWasClicked(String arg0) {
|
||||
String jid = StringUtils.parseBareAddress(arg0);
|
||||
ChatRoom room = SparkManager.getChatManager().getChatRoom(jid);
|
||||
|
||||
SparkManager.getChatManager().getChatContainer().activateChatRoom(room);
|
||||
SparkManager.getChatManager().getChatContainer().requestFocusInWindow();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a simple Notification
|
||||
*
|
||||
* @param name
|
||||
* @param title
|
||||
* @param body
|
||||
*/
|
||||
public void sendNotification(String title, String body) {
|
||||
try {
|
||||
_growl.sendNotification(SPARK, title, body);
|
||||
} catch (GrowlException e) {
|
||||
Log.error("growl error", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a notification with a CallBackContext
|
||||
*
|
||||
* @param title
|
||||
* the title to display
|
||||
* @param body
|
||||
* the body to display
|
||||
* @param callbackContext
|
||||
* a callback context
|
||||
*/
|
||||
public void sendNotificationWithCallback(String title, String body, String callbackContext) {
|
||||
try {
|
||||
_growl.sendNotification(SPARK, title, body, callbackContext);
|
||||
} catch (GrowlException e) {
|
||||
System.out.println("growl error" + e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,88 @@
|
||||
/**
|
||||
* $RCSfile: ,v $
|
||||
* $Revision: $
|
||||
* $Date: $
|
||||
*
|
||||
* Copyright (C) 2004-2010 Jive Software. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jivesoftware.spark.plugin.growl;
|
||||
|
||||
|
||||
import info.growl.Growl;
|
||||
import info.growl.GrowlCallbackListener;
|
||||
import info.growl.GrowlException;
|
||||
import info.growl.GrowlUtils;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.Action;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JFrame;
|
||||
|
||||
/**
|
||||
* Simple Test Class to test Growl behaviour
|
||||
*
|
||||
* @author wolf.posdorfer
|
||||
*
|
||||
*/
|
||||
public class GrowlTest {
|
||||
|
||||
public static void main(String[] args) throws GrowlException {
|
||||
|
||||
new GrowlTest();
|
||||
}
|
||||
|
||||
final String appName = "Eclipse";
|
||||
|
||||
public GrowlTest() throws GrowlException {
|
||||
|
||||
JFrame f = new JFrame("test");
|
||||
f.setVisible(true);
|
||||
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
|
||||
Growl growl = GrowlUtils.getGrowlInstance(appName);
|
||||
growl.addNotification(appName, true);
|
||||
|
||||
GrowlCallbackListener listener = new GrowlCallbackListener() {
|
||||
public void notificationWasClicked(final String clickContext) {
|
||||
System.out.println(clickContext + " was clicked");
|
||||
}
|
||||
};
|
||||
|
||||
growl.addCallbackListener(listener);
|
||||
growl.register();
|
||||
|
||||
Action action = new AbstractAction("CLICK") {
|
||||
private static final long serialVersionUID = -7415179834807796108L;
|
||||
|
||||
public void actionPerformed(ActionEvent ae) {
|
||||
try {
|
||||
Growl gu = GrowlUtils.getGrowlInstance(appName);
|
||||
gu.sendNotification(appName, "title", "body", "callbackcontext");
|
||||
} catch (GrowlException ge) {
|
||||
ge.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
JButton button = new JButton(action);
|
||||
f.setSize(200, 200);
|
||||
|
||||
f.add(button);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
BIN
src/plugins/growl/src/growler-src.zip
Normal file
BIN
src/plugins/growl/src/growler-src.zip
Normal file
Binary file not shown.
100
src/plugins/growl/src/info/growl/DummyGrowl.java
Normal file
100
src/plugins/growl/src/info/growl/DummyGrowl.java
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Michael Stringer
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Growl nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package info.growl;
|
||||
|
||||
import java.awt.image.RenderedImage;
|
||||
|
||||
/**
|
||||
* Dummy implementation of the Growl API for situations where the native code
|
||||
* cannot be loaded (non-Mac systems).
|
||||
*
|
||||
* @author Michael Stringer
|
||||
* @version 0.1
|
||||
*/
|
||||
class DummyGrowl implements Growl {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void addNotification(String name, boolean enabledByDefault) {
|
||||
// does nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void register() throws GrowlException {
|
||||
// does nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void sendNotification(String name, String title, String body)
|
||||
throws GrowlException {
|
||||
// does nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void sendNotification(String name, String title, String body,
|
||||
RenderedImage icon) throws GrowlException {
|
||||
// does nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void setIcon(RenderedImage icon) throws GrowlException {
|
||||
// does nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void sendNotification(String name, String title, String body,
|
||||
String callbackContext) throws GrowlException {
|
||||
// does nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void sendNotification(String name, String title, String body,
|
||||
String callbackContext, RenderedImage icon) throws GrowlException {
|
||||
// does nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void addCallbackListener(GrowlCallbackListener listener) {
|
||||
// does nothing
|
||||
}
|
||||
}
|
||||
160
src/plugins/growl/src/info/growl/Growl.java
Normal file
160
src/plugins/growl/src/info/growl/Growl.java
Normal file
@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Michael Stringer
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Growl nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package info.growl;
|
||||
|
||||
import java.awt.image.RenderedImage;
|
||||
|
||||
/**
|
||||
* Interface for sending notifications to Growl.
|
||||
*
|
||||
* @author Michael Stringer
|
||||
* @version 0.1
|
||||
*/
|
||||
public interface Growl {
|
||||
/**
|
||||
* Registers this Growl object with the Growl service.
|
||||
*
|
||||
* @throws GrowlException
|
||||
* If an error occurs during the registration.
|
||||
*/
|
||||
public void register() throws GrowlException;
|
||||
|
||||
/**
|
||||
* Sets the icon to display for notifications from this <code>Growl</code>.
|
||||
*
|
||||
* This <b>must</b> be called before calling {@link #register()}. If the
|
||||
* icon is changed after {@link #register()} has been called then another
|
||||
* call to {@link #register()} must be made.
|
||||
*
|
||||
* @param icon
|
||||
* The icon to display.
|
||||
* @throws GrowlException
|
||||
* If an error occurs while setting the icon.
|
||||
*/
|
||||
public void setIcon(RenderedImage icon) throws GrowlException;
|
||||
|
||||
/**
|
||||
* Adds a notification type for this <code>Growl</code>. This <b>must</b>
|
||||
* be called before calling {@link #register()}. If the another
|
||||
* notification type is added after {@link #register()} has been called then
|
||||
* another call to {@link #register()} must be made.
|
||||
*
|
||||
* @param name
|
||||
* The name of the notification type. This is what appears in
|
||||
* the Growl settings.
|
||||
* @param enabledByDefault
|
||||
* <code>true</code> if this notification type should be
|
||||
* enabled by default. This can be overridden by the user in
|
||||
* the Growl settings.
|
||||
*/
|
||||
public void addNotification(String name, boolean enabledByDefault);
|
||||
|
||||
/**
|
||||
* Adds a click callback listener.
|
||||
*
|
||||
* @param listener
|
||||
* The callback listener to add.
|
||||
*/
|
||||
public void addCallbackListener(GrowlCallbackListener listener);
|
||||
|
||||
/**
|
||||
* Sends a notification to Growl for displaying. This <b>must</b> be called
|
||||
* after calling {@link #register()}.
|
||||
*
|
||||
* @param name
|
||||
* Name of the notification type that has been registered.
|
||||
* @param title
|
||||
* The title of the notification.
|
||||
* @param body
|
||||
* The body of the notification.
|
||||
* @throws GrowlException
|
||||
* If the notification could not be sent.
|
||||
*/
|
||||
public void sendNotification(String name, String title, String body)
|
||||
throws GrowlException;
|
||||
|
||||
/**
|
||||
* Sends a notification to Growl for displaying. This <b>must</b> be called
|
||||
* after calling {@link #register()}.
|
||||
*
|
||||
* @param name
|
||||
* Name of the notification type that has been registered.
|
||||
* @param title
|
||||
* The title of the notification.
|
||||
* @param body
|
||||
* The body of the notification.
|
||||
* @param icon
|
||||
* The icon to display with the notification.
|
||||
* @throws GrowlException
|
||||
* If the notification could not be sent.
|
||||
*/
|
||||
public void sendNotification(String name, String title, String body,
|
||||
RenderedImage icon) throws GrowlException;
|
||||
|
||||
/**
|
||||
* Sends a notification to Growl for displaying. This <b>must</b> be called
|
||||
* after calling {@link #register()}.
|
||||
*
|
||||
* @param name
|
||||
* Name of the notification type that has been registered.
|
||||
* @param title
|
||||
* The title of the notification.
|
||||
* @param body
|
||||
* The body of the notification.
|
||||
* @param callbackContext
|
||||
* A unique ID that will be sent to any registered
|
||||
* {@link GrowlCallbackListener}s. If this is
|
||||
* <code>null</code> then clicks will be ignored.
|
||||
* @throws GrowlException
|
||||
* If the notification could not be sent.
|
||||
*/
|
||||
public void sendNotification(String name, String title, String body,
|
||||
String callbackContext) throws GrowlException;
|
||||
|
||||
/**
|
||||
* Sends a notification to Growl for displaying. This <b>must</b> be called
|
||||
* after calling {@link #register()}.
|
||||
*
|
||||
* @param name
|
||||
* Name of the notification type that has been registered.
|
||||
* @param title
|
||||
* The title of the notification.
|
||||
* @param body
|
||||
* The body of the notification.
|
||||
* @param callbackContext
|
||||
* A unique ID that will be sent to any registered
|
||||
* {@link GrowlCallbackListener}s. If this is
|
||||
* <code>null</code> then clicks will be ignored.
|
||||
* @param icon
|
||||
* The icon to display with the notification.
|
||||
* @throws GrowlException
|
||||
* If the notification could not be sent.
|
||||
*/
|
||||
public void sendNotification(String name, String title, String body,
|
||||
String callbackContext, RenderedImage icon) throws GrowlException;
|
||||
}
|
||||
46
src/plugins/growl/src/info/growl/GrowlCallbackListener.java
Normal file
46
src/plugins/growl/src/info/growl/GrowlCallbackListener.java
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Michael Stringer
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Growl nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package info.growl;
|
||||
|
||||
/**
|
||||
* Callback interface for handling users clicking on notifications.
|
||||
*
|
||||
* @author Michael Stringer
|
||||
* @version 0.1
|
||||
*/
|
||||
public interface GrowlCallbackListener {
|
||||
|
||||
/**
|
||||
* Signals that the user has clicked on a notification with an identifier of
|
||||
* <code>clickContext</code>.
|
||||
*
|
||||
* @param clickContext
|
||||
* The ID of the notification clicked.
|
||||
*/
|
||||
public void notificationWasClicked(String clickContext);
|
||||
}
|
||||
60
src/plugins/growl/src/info/growl/GrowlException.java
Normal file
60
src/plugins/growl/src/info/growl/GrowlException.java
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Michael Stringer
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Growl nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package info.growl;
|
||||
|
||||
/**
|
||||
* An exception class for handling errors while sending messages to Growl.
|
||||
*
|
||||
* @author Michael Stringer
|
||||
* @version 0.1
|
||||
*/
|
||||
public class GrowlException extends Exception {
|
||||
private static final long serialVersionUID = 2642457707267962686L;
|
||||
|
||||
/**
|
||||
* Creates a new <code>GrowlException</code>.
|
||||
*
|
||||
* @param message
|
||||
* The error message.
|
||||
*/
|
||||
public GrowlException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>GrowlException</code>.
|
||||
*
|
||||
* @param message
|
||||
* The error message.
|
||||
* @param cause
|
||||
* The underlying cause.
|
||||
*/
|
||||
public GrowlException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
211
src/plugins/growl/src/info/growl/GrowlNative.java
Normal file
211
src/plugins/growl/src/info/growl/GrowlNative.java
Normal file
@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Michael Stringer
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Growl nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package info.growl;
|
||||
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
/**
|
||||
* Growl notification implementation. This uses JNI to send messages to Growl.
|
||||
*
|
||||
* @author Michael Stringer
|
||||
* @version 0.1
|
||||
*/
|
||||
class GrowlNative implements Growl {
|
||||
private String appName;
|
||||
private List<NotificationType> notifications;
|
||||
private List<GrowlCallbackListener> callbackListeners;
|
||||
private byte[] imageData;
|
||||
|
||||
private native void sendNotification(String appName, String name,
|
||||
String title, String message, String callbackContext, byte[] icon);
|
||||
|
||||
private native void registerApp(String appName, byte[] image,
|
||||
List<NotificationType> notifications);
|
||||
|
||||
/**
|
||||
* Creates a new <code>GrowlNative</code> instance for the specified
|
||||
* application name.
|
||||
*
|
||||
* @param appName
|
||||
* The name of the application sending notifications.
|
||||
*/
|
||||
GrowlNative(String appName) {
|
||||
notifications = new ArrayList<NotificationType>();
|
||||
callbackListeners = new ArrayList<GrowlCallbackListener>();
|
||||
this.appName = appName;
|
||||
}
|
||||
|
||||
void fireCallbacks(String callbackContext) {
|
||||
for (GrowlCallbackListener listener : callbackListeners) {
|
||||
listener.notificationWasClicked(callbackContext);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void register() throws GrowlException {
|
||||
registerApp(appName, imageData, notifications);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void addNotification(String name, boolean enabledByDefault) {
|
||||
notifications.add(new NotificationType(name, enabledByDefault));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void addCallbackListener(GrowlCallbackListener listener) {
|
||||
callbackListeners.add(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void setIcon(RenderedImage icon) throws GrowlException {
|
||||
try {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ImageIO.write(icon, "png", baos);
|
||||
|
||||
imageData = baos.toByteArray();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void sendNotification(String name, String title, String body)
|
||||
throws GrowlException {
|
||||
if (!notifications.contains(new NotificationType(name, false))) {
|
||||
System.out.println("contains: " + notifications);
|
||||
throw new GrowlException("Unregistered notification name [" + name
|
||||
+ "]");
|
||||
}
|
||||
sendNotification(appName, name, title, body, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void sendNotification(String name, String title, String body,
|
||||
RenderedImage icon) throws GrowlException {
|
||||
if (!notifications.contains(new NotificationType(name, false))) {
|
||||
System.out.println("contains: " + notifications);
|
||||
throw new GrowlException("Unregistered notification name [" + name
|
||||
+ "]");
|
||||
}
|
||||
|
||||
try {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ImageIO.write(icon, "png", baos);
|
||||
|
||||
byte[] image = baos.toByteArray();
|
||||
|
||||
sendNotification(appName, name, title, body, null, image);
|
||||
} catch (IOException ioe) {
|
||||
throw new GrowlException("Failed to convert Image", ioe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void sendNotification(String name, String title, String body,
|
||||
String callbackContext) throws GrowlException {
|
||||
if (!notifications.contains(new NotificationType(name, false))) {
|
||||
System.out.println("contains: " + notifications);
|
||||
throw new GrowlException("Unregistered notification name [" + name
|
||||
+ "]");
|
||||
}
|
||||
|
||||
sendNotification(appName, name, title, body, callbackContext, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void sendNotification(String name, String title, String body,
|
||||
String callbackContext, RenderedImage icon) throws GrowlException {
|
||||
if (!notifications.contains(new NotificationType(name, false))) {
|
||||
System.out.println("contains: " + notifications);
|
||||
throw new GrowlException("Unregistered notification name [" + name
|
||||
+ "]");
|
||||
}
|
||||
|
||||
try {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ImageIO.write(icon, "png", baos);
|
||||
|
||||
byte[] image = baos.toByteArray();
|
||||
|
||||
sendNotification(appName, name, title, body, callbackContext, image);
|
||||
} catch (IOException ioe) {
|
||||
throw new GrowlException("Failed to convert Image", ioe);
|
||||
}
|
||||
}
|
||||
|
||||
private class NotificationType {
|
||||
private String name;
|
||||
private boolean enabledByDefault;
|
||||
|
||||
public NotificationType(String name, boolean enabledByDefault) {
|
||||
this.name = name;
|
||||
this.enabledByDefault = enabledByDefault;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public boolean isEnabledByDefault() {
|
||||
return enabledByDefault;
|
||||
}
|
||||
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof NotificationType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NotificationType otherType = (NotificationType) other;
|
||||
|
||||
return name.equals(otherType.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
113
src/plugins/growl/src/info/growl/GrowlUtils.java
Normal file
113
src/plugins/growl/src/info/growl/GrowlUtils.java
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Michael Stringer
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Growl nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package info.growl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Utility class for sending notifications using Growl.
|
||||
*
|
||||
* @author Michael Stringer
|
||||
* @version 0.1
|
||||
*/
|
||||
public final class GrowlUtils {
|
||||
private static final boolean GROWL_LOADED;
|
||||
private static Map<String, Growl> instances = new HashMap<String, Growl>();
|
||||
|
||||
|
||||
// public GrowlUtils(String pathtoload)
|
||||
// {
|
||||
// try {
|
||||
// System.load(pathtoload);
|
||||
// }catch (UnsatisfiedLinkError ule) {
|
||||
// System.out.println("Failed to load Growl library from "+pathtoload);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public Growl getGrowl(String appName)
|
||||
// {
|
||||
//
|
||||
// Growl stuff = new GrowlNative(appName);
|
||||
// return stuff;
|
||||
// }
|
||||
|
||||
static {
|
||||
boolean loaded = false;
|
||||
try {
|
||||
System.loadLibrary("growl");
|
||||
loaded = true;
|
||||
} catch (UnsatisfiedLinkError ule) {
|
||||
System.out.println("Failed to load Growl library");
|
||||
}
|
||||
|
||||
GROWL_LOADED = loaded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method - should not be instantiated.
|
||||
*/
|
||||
private GrowlUtils() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a <code>Growl</code> instance to use for the specified application
|
||||
* name. Multiple calls to this method will return the same instance.
|
||||
*
|
||||
* @param appName
|
||||
* The name of the application.
|
||||
* @return The <code>Growl</code> instance to use.
|
||||
*/
|
||||
public static Growl getGrowlInstance(String appName) {
|
||||
Growl instance = instances.get(appName);
|
||||
|
||||
if (instance == null) {
|
||||
if (GROWL_LOADED) {
|
||||
instance = new GrowlNative(appName);
|
||||
} else {
|
||||
instance = new DummyGrowl();
|
||||
}
|
||||
|
||||
instances.put(appName, instance);
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether messages can be sent to Growl. If this returns
|
||||
* <code>false</code> then {@link #getGrowlInstance(String)} will return a
|
||||
* dummy object.
|
||||
*
|
||||
* @return <code>true</code> if messages can be sent to Growl.
|
||||
*/
|
||||
public static boolean isGrowlLoaded() {
|
||||
return GROWL_LOADED;
|
||||
}
|
||||
}
|
||||
186
src/plugins/growl/src/info/growl/test/TestGrowl.java
Normal file
186
src/plugins/growl/src/info/growl/test/TestGrowl.java
Normal file
@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Michael Stringer
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Growl nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package info.growl.test;
|
||||
|
||||
import info.growl.Growl;
|
||||
import info.growl.GrowlCallbackListener;
|
||||
import info.growl.GrowlException;
|
||||
import info.growl.GrowlUtils;
|
||||
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.Action;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
/**
|
||||
* Simple test class for Growl.
|
||||
*
|
||||
* @author Michael Stringer
|
||||
* @version 0.1
|
||||
*/
|
||||
public class TestGrowl extends JFrame {
|
||||
private static final String APP_NAME = "Test Java App";
|
||||
private static final String NOTIF_3_CALLBACK = "Notif3";
|
||||
|
||||
public TestGrowl() {
|
||||
super("Growl for Java");
|
||||
setSize(320, 290);
|
||||
|
||||
buildComponents();
|
||||
setVisible(true);
|
||||
setDefaultCloseOperation(EXIT_ON_CLOSE);
|
||||
}
|
||||
|
||||
private void buildComponents() {
|
||||
getContentPane().setLayout(new GridLayout(6, 1));
|
||||
|
||||
Action action = new AbstractAction("Register") {
|
||||
public void actionPerformed(ActionEvent ae) {
|
||||
try {
|
||||
Growl growl = GrowlUtils.getGrowlInstance(APP_NAME);
|
||||
|
||||
growl.addNotification("Test Notification 1", true);
|
||||
growl.addNotification("Test Notification 2", false);
|
||||
growl.addNotification("Test Notification 3", true);
|
||||
|
||||
GrowlCallbackListener listener = new GrowlCallbackListener() {
|
||||
public void notificationWasClicked(
|
||||
final String clickContext) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
if (NOTIF_3_CALLBACK.equals(clickContext)) {
|
||||
JOptionPane
|
||||
.showMessageDialog(
|
||||
TestGrowl.this,
|
||||
"User clicked on 'Test Notification 3'");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
growl.addCallbackListener(listener);
|
||||
growl.register();
|
||||
} catch (GrowlException ge) {
|
||||
ge.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
getContentPane().add(new JButton(action));
|
||||
|
||||
action = new AbstractAction("Send 'Test Notification 1'") {
|
||||
public void actionPerformed(ActionEvent ae) {
|
||||
try {
|
||||
Growl growl = GrowlUtils.getGrowlInstance(APP_NAME);
|
||||
|
||||
growl.sendNotification("Test Notification 1",
|
||||
"Test Notif 1", "This is a test");
|
||||
} catch (GrowlException ge) {
|
||||
ge.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
getContentPane().add(new JButton(action));
|
||||
|
||||
action = new AbstractAction("Send 'Test Notification 2'") {
|
||||
public void actionPerformed(ActionEvent ae) {
|
||||
try {
|
||||
Growl growl = GrowlUtils.getGrowlInstance(APP_NAME);
|
||||
BufferedImage image = ImageIO.read(TestGrowl.class
|
||||
.getResource("/images/duke.gif"));
|
||||
growl.sendNotification("Test Notification 2",
|
||||
"Test Notif 2", "This is another test", image);
|
||||
} catch (GrowlException ge) {
|
||||
ge.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
getContentPane().add(new JButton(action));
|
||||
|
||||
action = new AbstractAction("Test Callback 'Notification 3'") {
|
||||
public void actionPerformed(ActionEvent ae) {
|
||||
try {
|
||||
Growl growl = GrowlUtils.getGrowlInstance(APP_NAME);
|
||||
|
||||
growl.sendNotification("Test Notification 3",
|
||||
"Callback Test", "Click me - I dares you!", NOTIF_3_CALLBACK);
|
||||
} catch (GrowlException ge) {
|
||||
ge.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
getContentPane().add(new JButton(action));
|
||||
|
||||
action = new AbstractAction("Reg & Test App 2") {
|
||||
public void actionPerformed(ActionEvent ae) {
|
||||
try {
|
||||
Growl growl = GrowlUtils.getGrowlInstance("Other App");
|
||||
|
||||
growl.addNotification("A Notification", true);
|
||||
|
||||
BufferedImage image = ImageIO.read(TestGrowl.class
|
||||
.getResource("/images/duke.gif"));
|
||||
growl.setIcon(image);
|
||||
|
||||
growl.register();
|
||||
growl.sendNotification("A Notification", "Testin",
|
||||
"Blah de blah blah");
|
||||
} catch (GrowlException ge) {
|
||||
ge.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
getContentPane().add(new JButton(action));
|
||||
|
||||
action = new AbstractAction("Exit") {
|
||||
public void actionPerformed(ActionEvent ae) {
|
||||
System.exit(0);
|
||||
}
|
||||
};
|
||||
getContentPane().add(new JButton(action));
|
||||
}
|
||||
|
||||
public static final void main(String[] args) {
|
||||
new TestGrowl();
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
<plugin>
|
||||
<name>Growl Plugin</name>
|
||||
<version>1.0</version>
|
||||
<author>Andrew Wright</author>
|
||||
<version>2.0</version>
|
||||
<author>Wolf Posdorfer</author>
|
||||
<homePage>http://www.jivesoftware.com</homePage>
|
||||
<email>andrew@jivesoftware.com</email>
|
||||
<description>Provides Growl notifications on Mac OS X.(http://growl.info)</description>
|
||||
|
||||
Reference in New Issue
Block a user