package thaw.plugins; import java.util.Comparator; import java.util.Collections; import java.util.Vector; import java.util.Iterator; import java.awt.event.MouseListener; import java.awt.event.MouseEvent; import java.awt.event.WindowListener; import java.awt.event.WindowEvent; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import javax.swing.JLabel; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JScrollPane; import javax.swing.JPanel; import java.awt.Toolkit; import java.awt.GridLayout; import java.awt.BorderLayout; import thaw.core.Core; import thaw.core.Config; import thaw.core.Logger; import thaw.core.I18n; import thaw.core.ThawThread; import thaw.core.ThawRunnable; import thaw.fcp.FCPTransferQuery; import thaw.gui.SysTrayIcon; import thaw.gui.TransferProgressBar; import thaw.gui.IconBox; import thaw.gui.WarningWindow; public class TrayIcon implements thaw.core.Plugin, MouseListener, WindowListener, ActionListener, thaw.core.LogListener { private Core core; private Config config; private SysTrayIcon icon; private JDialog dialog; private JButton closeDialog; public final static int DIALOG_X = 500; public final static int DIALOG_Y = 800; public TrayIcon() { } public boolean run(Core core) { this.core = core; this.config = core.getConfig(); if (!Core.checkJavaVersion(1, 6)) { new WarningWindow(core, I18n.getMessage("thaw.plugin.trayIcon.java1.6")); return false; } if (config.getValue("disableTrayIconPopups") == null) config.setValue("disableTrayIconPopups", "false"); icon = new SysTrayIcon(thaw.gui.IconBox.blueBunny); icon.setToolTip("Thaw "+thaw.core.Main.VERSION); icon.addMouseListener(this); core.getMainWindow().addWindowListener(this); icon.setVisible(true); Logger.addLogListener(this); return true; } public void stop() { if (icon == null) return; Logger.removeLogListener(this); core.getMainWindow().removeWindowListener(this); icon.removeMouseListener(this); icon.setVisible(false); if (!core.getMainWindow().isVisible()) { Logger.info(this, "Making main window visible again"); core.getMainWindow().setVisible(true); } Logger.addLogListener(this); } public static boolean popMessage(thaw.core.PluginManager pluginManager, String title, String message) { return popMessage(pluginManager, title, message, SysTrayIcon.MSG_NONE); } /** * that's an helper to make my life easier : * it tries to find a loaded instance of this plugin, it succeed, it tries to * pop the message with it. Else if returns false. * @param msgType see thaw.gui.SysTrayIcon */ public static boolean popMessage(thaw.core.PluginManager pluginManager, String title, String message, int msgType) { TrayIcon plugin = (TrayIcon)pluginManager.getPlugin("thaw.plugins.TrayIcon"); if (plugin == null) return false; return plugin.popMessage(title, message, msgType); } /** * Made to be also used by other plugins */ public boolean popMessage(String title, String message, int msgType) { if (icon == null || !icon.canWork()) return false; String cfg; if ( (cfg = config.getValue("disableTrayIconPopups")) != null ) if (Boolean.TRUE.equals(Boolean.valueOf(cfg))) return false; icon.popMessage(title, message, msgType); return true; } public void newLogLine(int level, Object src, String line) { if (level > Logger.LOG_LEVEL_ERROR || src == this || src == icon) return; int msgType = ((level == 0) ? SysTrayIcon.MSG_ERROR : SysTrayIcon.MSG_WARNING); popMessage("Thaw : "+Logger.PREFIXES[level], line, msgType); } public void logLevelChanged(int oldLevel, int newLevel) { } public String getNameForUser() { return I18n.getMessage("thaw.plugin.trayIcon.pluginName"); } public javax.swing.ImageIcon getIcon() { return thaw.gui.IconBox.blueBunny; } public void switchMainWindowVisibility() { Logger.info(this, "Changing main window visibility"); boolean v = !core.getMainWindow().isVisible(); core.getMainWindow().setVisible(v); if (v) core.getMainWindow().getMainFrame().toFront(); } private class QueryComparator implements Comparator { public QueryComparator() { } public int compare(final Object o1, final Object o2) { int result = 0; if(!(o1 instanceof FCPTransferQuery) || !(o2 instanceof FCPTransferQuery)) return 0; final FCPTransferQuery q1 = (FCPTransferQuery)o1; final FCPTransferQuery q2 = (FCPTransferQuery)o2; if((q1.getProgression() <= 0) && (q2.getProgression() <= 0)) { if(q1.isRunning() && !q2.isRunning()) return 1; if(q2.isRunning() && !q1.isRunning()) return -1; } result = -1 * (new Integer(q1.getProgression())).compareTo(new Integer(q2.getProgression())); return result; } public boolean equals(final Object obj) { return true; } public int hashCode(){ return super.hashCode(); } } private Vector progressBars = null; private JPanel getTransferPanel(FCPTransferQuery q) { JPanel p = new JPanel(new GridLayout(2, 1, 5, 5)); String txt = q.getFilename(); if (txt == null) txt = q.getFileKey(); if (txt == null) txt = "?"; javax.swing.ImageIcon icon; if (q.getQueryType() == 2) icon = IconBox.minInsertions; else icon = IconBox.minDownloads; JLabel l = new JLabel(txt); l.setIcon(icon); p.add(l); TransferProgressBar bar = new TransferProgressBar(q, true, true); bar.refresh(); progressBars.add(bar); p.add(bar); return p; } private boolean realDisplayFrame(int x, int y) { dialog = new JDialog((java.awt.Frame)null, I18n.getMessage("thaw.plugin.trayIcon.dialogTitle")); dialog.getContentPane().setLayout(new BorderLayout(5, 5)); dialog.setUndecorated(true); dialog.setResizable(true); JPanel panel = new JPanel(new BorderLayout(10, 10)); panel.add(new JLabel(" "), BorderLayout.CENTER); Vector queries = core.getQueueManager().getRunningQueue(); JPanel north; Vector newQueries = new Vector(); synchronized(queries) { for (Iterator it = queries.iterator(); it.hasNext();) { newQueries.add(it.next()); } } if (newQueries.size() == 0) { popMessage("Thaw", I18n.getMessage("thaw.plugin.trayIcon.emptyQueue"), SysTrayIcon.MSG_WARNING); dialog = null; return false; } Collections.sort(newQueries, new QueryComparator()); north = new JPanel(new GridLayout(queries.size(), 1, 10, 10)); progressBars = new Vector(); for (Iterator it = newQueries.iterator(); it.hasNext();) { north.add(getTransferPanel((FCPTransferQuery)it.next())); } JPanel northNorth = new JPanel(new BorderLayout()); northNorth.add(new JLabel(" "), BorderLayout.CENTER); closeDialog = new JButton(IconBox.minClose); closeDialog.addActionListener(this); northNorth.add(closeDialog, BorderLayout.EAST); dialog.getContentPane().add(northNorth, BorderLayout.NORTH); dialog.getContentPane().add(panel, BorderLayout.CENTER); panel.add(north, BorderLayout.NORTH); dialog.getContentPane().add(new JScrollPane(panel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); //dialog.setSize(DIALOG_X, DIALOG_Y); dialog.validate(); dialog.pack(); java.awt.Dimension size = dialog.getSize(); double height = size.getHeight(); double width = size.getWidth(); if (width > DIALOG_X) width = DIALOG_X; if (height > DIALOG_Y) height = DIALOG_Y; dialog.setSize((int)width, (int)height); java.awt.Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); int screen_x = (int)d.getWidth(); int screen_y = (int)d.getHeight(); if (x+width >= screen_x) x -= width; if (y+height >= screen_y) y -= height; dialog.setLocation(x, y); dialog.setVisible(true); dialog.toFront(); return true; } private class ProgressBarRefresher implements ThawRunnable { private Vector bars; private boolean stop; public ProgressBarRefresher(Vector bars) { this.bars = bars; stop = false; } public void run() { while(!stop) { for (Iterator it = bars.iterator(); it.hasNext();) { try { Thread.sleep(200); } catch(InterruptedException e) { /* \_o< */ } if (stop) break; TransferProgressBar bar = (TransferProgressBar)it.next(); bar.refresh(); } } } public void stop() { stop = true; } } private ProgressBarRefresher refresher = null; public void displayFrame(int x, int y) { if (realDisplayFrame(x, y) && dialog != null) { /* progressBars vector is generated at the same time than the panels */ refresher = new ProgressBarRefresher(progressBars); Thread th = new ThawThread(refresher, "Trayicon transfer list refresher", this); th.start(); } } public void hideFrame() { if (dialog != null) { dialog.setVisible(false); dialog = null; progressBars = null; refresher.stop(); refresher = null; } } public void windowActivated(WindowEvent e) { } public void windowClosed(WindowEvent e) { } public void windowClosing(WindowEvent e) { } public void windowDeactivated(WindowEvent e) { } public void windowDeiconified(WindowEvent e) { } public void windowIconified(WindowEvent e) { } public void windowOpened(WindowEvent e) { } public void mouseClicked(MouseEvent e) { if (dialog != null) { hideFrame(); return; } if (e.getButton() == MouseEvent.BUTTON1) switchMainWindowVisibility(); else if (e.getButton() == MouseEvent.BUTTON3) { if (dialog == null) { java.awt.Point p = icon.getMousePosition(); displayFrame(((int)p.getX()), ((int)p.getY())); } } } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mousePressed(MouseEvent e) { } public void mouseReleased(MouseEvent e) { } public void actionPerformed(ActionEvent e) { if (e.getSource() == closeDialog) { if (dialog != null) { hideFrame(); } } } }