### Eclipse Workspace Patch 1.0
#P Spark
Index: src/java/org/jivesoftware/sparkimpl/plugin/systray/SysTrayPlugin.java
===================================================================
--- src/java/org/jivesoftware/sparkimpl/plugin/systray/SysTrayPlugin.java	(revision 0)
+++ src/java/org/jivesoftware/sparkimpl/plugin/systray/SysTrayPlugin.java	(revision 0)
@@ -0,0 +1,268 @@
+package org.jivesoftware.sparkimpl.plugin.systray;
+
+import java.awt.SystemTray;
+import java.awt.TrayIcon;
+import java.awt.event.ActionEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.ImageIcon;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.JPopupMenu;
+
+import org.jivesoftware.Spark;
+import org.jivesoftware.resource.Default;
+import org.jivesoftware.resource.Res;
+import org.jivesoftware.resource.SparkRes;
+import org.jivesoftware.smack.packet.Presence;
+import org.jivesoftware.spark.SparkManager;
+import org.jivesoftware.spark.plugin.Plugin;
+import org.jivesoftware.spark.ui.status.CustomStatusItem;
+import org.jivesoftware.spark.ui.status.StatusBar;
+import org.jivesoftware.spark.ui.status.StatusItem;
+
+public class SysTrayPlugin implements Plugin
+{
+	private JPopupMenu popupMenu = new JPopupMenu();
+	
+	private final JMenuItem openMenu 		= new JMenuItem(Res.getString("menuitem.open"));
+	private final JMenuItem minimizeMenu 	= new JMenuItem(Res.getString("menuitem.hide"));
+	private final JMenuItem exitMenu 		= new JMenuItem(Res.getString("menuitem.exit"));
+	private final JMenu 	statusMenu		= new JMenu(Res.getString("menuitem.status"));
+	private final JMenuItem logoutMenu 		= new JMenuItem(Res.getString("menuitem.logout.no.status"));
+	
+	private ImageIcon availableIcon;
+	private TrayIcon trayIcon;
+
+	public boolean canShutDown() 
+	{
+		return true;
+	}
+
+	public void initialize() 
+	{		
+		SystemTray tray = SystemTray.getSystemTray();
+		
+		if (SystemTray.isSupported()) {
+						
+			
+			availableIcon = Default.getImageIcon(Default.TRAY_IMAGE);
+	        if (availableIcon == null) {
+	            availableIcon = SparkRes.getImageIcon(SparkRes.TRAY_IMAGE);
+	        }
+	          
+	        popupMenu.add(openMenu);
+	        openMenu.addActionListener(new AbstractAction() {
+	
+				private static final long serialVersionUID = 1L;
+	
+				public void actionPerformed(ActionEvent event) {
+					SparkManager.getMainWindow().setVisible(true);
+					SparkManager.getMainWindow().toFront();
+				}
+	        	
+	        });
+	        popupMenu.add(minimizeMenu);
+	        minimizeMenu.addActionListener(new AbstractAction() {
+	        	private static final long serialVersionUID = 1L;
+	        	public void actionPerformed(ActionEvent event) {
+	        		SparkManager.getMainWindow().setVisible(false);
+	        	}
+	        });
+	        popupMenu.addSeparator();
+	        addStatusMessages();
+	        popupMenu.add(statusMenu);
+	        statusMenu.addActionListener(new AbstractAction() {
+	        	private static final long serialVersionUID = 1L;
+	        	public void actionPerformed(ActionEvent event) {
+	        		
+	        	}
+	        });
+	        
+	        if (Spark.isWindows())
+	        {
+	        	popupMenu.add(logoutMenu);
+	        	logoutMenu.addActionListener(new AbstractAction() {
+	    			private static final long serialVersionUID = 1L;
+	
+	    			public void actionPerformed(ActionEvent e) {
+	    				 SparkManager.getMainWindow().logout(false);
+	                }	
+	        	});
+	        }
+	        // Exit Menu
+	        exitMenu.addActionListener(new AbstractAction() {
+				private static final long serialVersionUID = 1L;
+	
+				public void actionPerformed(ActionEvent e) {
+	            	SparkManager.getMainWindow().shutdown();
+	            }
+	        });
+	        popupMenu.add(exitMenu);
+	        
+	        
+	        // init Presence Listener
+	        // Small feature preview
+	        /*
+			SparkManager.getSessionManager().addPresenceListener(new PresenceListener() {
+				public void presenceChanged(Presence presence) {
+					Icon icon = PresenceManager.getIconFromPresence(presence);
+					if (icon instanceof ImageIcon)
+					{
+						// Add Change Icon
+						trayIcon.setImage( ((ImageIcon) icon).getImage()  );
+						
+						// Add 
+						trayIcon.displayMessage("Status", presence.getMode().toString(), TrayIcon.MessageType.INFO);
+					}
+					
+				}	
+			});
+			*/
+	        //
+	                
+		    try {        
+		    	trayIcon = new TrayIcon(availableIcon.getImage(),"Spark",null);		
+			    trayIcon.setImageAutoSize(true);
+			    
+				trayIcon.addMouseListener(new MouseListener() {
+		
+						public void mouseClicked(MouseEvent event) {
+							if (event.getButton() == MouseEvent.BUTTON1 && event.getClickCount() == 1)
+							{
+
+								if (SparkManager.getMainWindow().isVisible())
+								{
+									SparkManager.getMainWindow().setVisible(false);
+								}
+								else
+								{
+									SparkManager.getMainWindow().setVisible(true);
+									SparkManager.getMainWindow().toFront();
+								}
+							}
+							else if (event.getButton() == MouseEvent.BUTTON1)
+							{
+								SparkManager.getMainWindow().requestFocus();
+							}
+							else if (event.getButton() == MouseEvent.BUTTON3) {
+				            	popupMenu.setLocation(event.getX(), event.getY());
+				            	popupMenu.setInvoker(popupMenu);
+				            	popupMenu.setVisible(true);
+							}
+						}
+		
+						public void mouseEntered(MouseEvent event) {
+		
+						}
+		
+						public void mouseExited(MouseEvent event) {
+		
+						}
+		
+						public void mousePressed(MouseEvent event) {
+		
+						}
+		
+						public void mouseReleased(MouseEvent event) {
+
+						}
+				    	
+				    }
+			    );
+
+		    	tray.add(trayIcon);
+		    } catch (Exception e) { 
+		    	// Not Supported
+		    }
+		}
+	}
+	
+	public void addStatusMessages() {
+		StatusBar statusBar = SparkManager.getWorkspace().getStatusBar();
+		for (Object o : statusBar.getStatusList()) {
+			  final StatusItem statusItem = (StatusItem) o;
+			
+			  final AbstractAction action = new AbstractAction() {
+				  private static final long serialVersionUID = 1L;
+
+				  public void actionPerformed(ActionEvent e) {
+
+					  StatusBar statusBar = SparkManager.getWorkspace().getStatusBar();
+					
+					  SparkManager.getSessionManager().changePresence(statusItem.getPresence());
+					  statusBar.setStatus(statusItem.getText());
+				  }
+			  };
+			  action.putValue(Action.NAME, statusItem.getText());
+			  action.putValue(Action.SMALL_ICON, statusItem.getIcon());
+
+			  boolean hasChildren = false;
+			  for (Object aCustom : SparkManager.getWorkspace().getStatusBar().getCustomStatusList()) {
+	                final CustomStatusItem cItem = (CustomStatusItem) aCustom;
+	                String type = cItem.getType();
+	                if (type.equals(statusItem.getText())) {
+	                    hasChildren = true;
+	                }
+			  }
+			  
+			  if (!hasChildren) {
+				  JMenuItem status = new JMenuItem(action);
+				  statusMenu.add(status);
+			  }
+			  else {
+				  final JMenu status = new JMenu(action);
+				  statusMenu.add(status);
+				  
+				  status.addMouseListener(new MouseAdapter() {
+	                    public void mouseClicked(MouseEvent mouseEvent) {	
+	                    	action.actionPerformed(null);
+	                    	popupMenu.setVisible(false);
+	                    }
+				  });
+				  
+				  for (Object aCustom : SparkManager.getWorkspace().getStatusBar().getCustomStatusList()) {
+					  final CustomStatusItem customItem = (CustomStatusItem) aCustom;
+					  String type = customItem.getType();
+					  if (type.equals(statusItem.getText())) {
+						  AbstractAction customAction = new AbstractAction() {
+							  private static final long serialVersionUID = 1L;
+	
+							  public void actionPerformed(ActionEvent e) {
+								  StatusBar statusBar = SparkManager.getWorkspace().getStatusBar();
+								  
+								  Presence oldPresence = statusItem.getPresence(); 
+								  Presence presence = StatusBar.copyPresence(oldPresence);
+                                  presence.setStatus(customItem.getStatus());
+                                  presence.setPriority(customItem.getPriority());
+                                  SparkManager.getSessionManager().changePresence(presence);
+
+								  statusBar.setStatus(statusItem.getName()  + " - " +  customItem.getStatus());
+							  }
+						  };
+						  customAction.putValue(Action.NAME, customItem.getStatus());
+						  customAction.putValue(Action.SMALL_ICON, statusItem.getIcon());
+						  JMenuItem menuItem = new JMenuItem(customAction);
+						  status.add(menuItem);
+					  }
+				  }
+				 
+			  }
+		}
+	}
+
+	public void shutdown() {
+
+		
+	}
+
+	public void uninstall()	{
+
+		
+	}
+
+}
Index: src/java/org/jivesoftware/spark/ui/status/StatusBar.java
===================================================================
--- src/java/org/jivesoftware/spark/ui/status/StatusBar.java	(revision 10963)
+++ src/java/org/jivesoftware/spark/ui/status/StatusBar.java	(working copy)
@@ -347,6 +347,15 @@
     public Collection getStatusList() {
         return statusList;
     }
+    
+    public Collection getCustomStatusList()
+    {
+    	List custom = CustomMessages.load();;;
+    	if (custom == null)
+    		custom = new ArrayList();
+    	
+    	return custom;
+    }
 
     public Presence getPresence() {
         return currentPresence;
Index: src/resources/META-INF/plugins.xml
===================================================================
--- src/resources/META-INF/plugins.xml	(revision 10963)
+++ src/resources/META-INF/plugins.xml	(working copy)
@@ -164,5 +164,23 @@
         <email>derek@jivesoftware.com</email>
         <description>Allows users to explicitly set their language.</description>
         <class>org.jivesoftware.sparkimpl.plugin.language.LanguagePlugin</class>
+    </plugin>    
+    <plugin>
+        <name>SystemTray</name>
+        <version>1.0</version>
+        <author>Michael Will</author>
+        <homePage>http://www.igniterealtime.org</homePage>
+        <email>michael-will@gmx.net</email>
+        <description>SystemTray.</description>
+        <class>org.jivesoftware.sparkimpl.plugin.systray.SysTrayPlugin</class>
     </plugin>
+    <plugin>
+        <name>UserIdle</name>
+        <version>1.0</version>
+        <author>Michael Will</author>
+        <homePage>http://www.igniterealtime.org</homePage>
+        <email>michael-will@gmx.net</email>
+        <description>SystemTray.</description>
+        <class>org.jivesoftware.sparkimpl.plugin.idle.UserIdlePlugin</class>
+    </plugin>
 </plugins>
Index: src/java/org/jivesoftware/sparkimpl/plugin/idle/UserIdlePlugin.java
===================================================================
--- src/java/org/jivesoftware/sparkimpl/plugin/idle/UserIdlePlugin.java	(revision 0)
+++ src/java/org/jivesoftware/sparkimpl/plugin/idle/UserIdlePlugin.java	(revision 0)
@@ -0,0 +1,106 @@
+package org.jivesoftware.sparkimpl.plugin.idle;
+
+import java.awt.MouseInfo;
+import java.awt.PointerInfo;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import org.jivesoftware.Spark;
+import org.jivesoftware.resource.Res;
+import org.jivesoftware.smack.packet.Presence;
+import org.jivesoftware.spark.SparkManager;
+import org.jivesoftware.spark.plugin.Plugin;
+import org.jivesoftware.sparkimpl.settings.local.LocalPreferences;
+import org.jivesoftware.sparkimpl.settings.local.SettingsManager;
+
+public class UserIdlePlugin extends TimerTask implements Plugin {
+
+	private final int CHECKTIME = 5;
+	private double x = 0;
+	private double y = 0;
+	private boolean hasChanged = false;
+	private int counter = 0;
+	private LocalPreferences pref = SettingsManager.getLocalPreferences();
+	
+	@Override
+	public boolean canShutDown() {
+
+		return false;
+	}
+
+	@Override
+	public void initialize() {
+		 Timer timer = new Timer();
+		 // Check all 5 secounds
+		 timer.schedule  ( this, (1000 * 10), (1000 * CHECKTIME)  );
+	}
+
+	@Override
+	public void shutdown() {
+		
+	}
+
+	@Override
+	public void uninstall() {
+		
+	}
+	
+	private void setIdle()
+	{
+		Presence presence = new Presence(Presence.Type.available, Res.getString("status.away"), 1, Presence.Mode.away);			
+		SparkManager.getSessionManager().changePresence(presence);
+	}
+	
+	private void setOnline()
+	{
+		Presence presence = new Presence(Presence.Type.available, Res.getString("status.online"), 1, Presence.Mode.available);
+		SparkManager.getSessionManager().changePresence(presence);
+	}
+	
+	@Override
+	public void run() {
+		if(pref.isIdleOn()){
+			PointerInfo info = MouseInfo.getPointerInfo();
+			//DecimalFormat format = new DecimalFormat("0.00");
+			//System.out.println(format.format(info.getLocation().getY()).toString() + "-" + 7.24288464E8 + "-" + (info.getLocation().getY() == 7.24288464E8));
+			//System.out.println(format.format(info.getLocation().getX()).toString() + "-" + 7.24288464E8 + "-" + (info.getLocation().getX() == 7.24288464E8));
+			int automaticIdleTime = (pref.getIdleTime() * 60) / CHECKTIME;
+	
+			// Windows Desktop Lock
+			if (Spark.isWindows()) {
+				
+				if (info.getLocation().getX() > 50000000 || 
+					info.getLocation().getY() > 50000000) {
+					if (!hasChanged) {
+						System.out.println("Desktop Lock Ole Ole .. ");
+						hasChanged = true;
+						setIdle();
+						y = info.getLocation().getY();
+						x = info.getLocation().getX();
+					}
+				}
+			}
+		
+			// Default Idle
+			if (x == info.getLocation().getX() && 
+				y == info.getLocation().getY()) {
+				if (counter > automaticIdleTime) {
+					if (!hasChanged) {
+						setIdle();
+					}
+					hasChanged = true;
+				}
+				counter++;
+			} else {
+				if (hasChanged) {
+					setOnline();
+					hasChanged = false;
+				}
+				counter = 0;
+			}
+			
+			y = info.getLocation().getY();
+			x = info.getLocation().getX();
+		}
+	}
+}
Index: src/java/org/jivesoftware/resource/spark.properties
===================================================================
--- src/java/org/jivesoftware/resource/spark.properties	(revision 10963)
+++ src/java/org/jivesoftware/resource/spark.properties	(working copy)
@@ -16,7 +16,7 @@
 
 #MainWindow
 MAIN_IMAGE = images/spark-16x16.png
-TRAY_IMAGE = images/message.png
+TRAY_IMAGE = images/spark-16x16.png
 SPARK_IMAGE_32x32 = images/spark-32x32.png
 MAIN_IMAGE_ICO = images/icon_16.ico
 MAIN_ICNS_FILE = images/message.icns
