|
|
|
@ -38,10 +38,12 @@ import java.awt.TrayIcon;
|
|
|
|
|
import java.awt.event.ActionEvent;
|
|
|
|
|
import java.awt.event.ActionListener;
|
|
|
|
|
import java.io.File;
|
|
|
|
|
import java.io.IOException;
|
|
|
|
|
import java.lang.reflect.Method;
|
|
|
|
|
|
|
|
|
|
import javax.imageio.ImageIO;
|
|
|
|
|
|
|
|
|
|
import net.yacy.cora.util.ConcurrentLog;
|
|
|
|
|
import net.yacy.gui.framework.Browser;
|
|
|
|
|
import net.yacy.kelondro.util.OS;
|
|
|
|
|
import net.yacy.search.Switchboard;
|
|
|
|
@ -61,8 +63,8 @@ public final class Tray {
|
|
|
|
|
private boolean isShown = false;
|
|
|
|
|
private boolean appIsReady = false;
|
|
|
|
|
private boolean menuEnabled = true;
|
|
|
|
|
private Image trayIcon = null;
|
|
|
|
|
private BufferedImage[] progressIcons = null;
|
|
|
|
|
private final String iconPath;
|
|
|
|
|
|
|
|
|
|
private MenuItem menuItemHeadline = null;
|
|
|
|
|
private MenuItem menuItemSearch = null;
|
|
|
|
@ -70,44 +72,36 @@ public final class Tray {
|
|
|
|
|
private MenuItem menuItemTerminate = null;
|
|
|
|
|
|
|
|
|
|
public Tray(final Switchboard sb_par) {
|
|
|
|
|
sb = sb_par;
|
|
|
|
|
menuEnabled = sb.getConfigBool(SwitchboardConstants.TRAY_MENU_ENABLED, true);
|
|
|
|
|
trayLabel = sb.getConfig(SwitchboardConstants.TRAY_ICON_LABEL, "YaCy");
|
|
|
|
|
try {
|
|
|
|
|
final boolean trayIconEnabled = sb.getConfigBool(SwitchboardConstants.TRAY_ICON_ENABLED, false);
|
|
|
|
|
final boolean trayIconForced = sb.getConfigBool(SwitchboardConstants.TRAY_ICON_FORCED, false);
|
|
|
|
|
if (trayIconEnabled && (OS.isWindows || OS.isMacArchitecture || trayIconForced)) {
|
|
|
|
|
this.sb = sb_par;
|
|
|
|
|
this.menuEnabled = sb.getConfigBool(SwitchboardConstants.TRAY_MENU_ENABLED, true);
|
|
|
|
|
this.trayLabel = sb.getConfig(SwitchboardConstants.TRAY_ICON_LABEL, "YaCy");
|
|
|
|
|
this.iconPath = sb.getAppPath().toString() + "/addon/YaCy_TrayIcon.png".replace("/", File.separator);
|
|
|
|
|
if (useTray()) {
|
|
|
|
|
try {
|
|
|
|
|
System.setProperty("java.awt.headless", "false"); // we have to switch off headless mode, else all will fail
|
|
|
|
|
if (SystemTray.isSupported()) {
|
|
|
|
|
final String iconPath = sb.getAppPath().toString() + "/addon/YaCy_TrayIcon.png".replace("/", File.separator);
|
|
|
|
|
final String progressPath = sb.getAppPath().toString() + "/addon/progressbar.png".replace("/", File.separator);
|
|
|
|
|
final String progressBootingPath = sb.getAppPath().toString() + "/addon/progress_booting.png".replace("/", File.separator);
|
|
|
|
|
ActionListener al = new ActionListener() {
|
|
|
|
|
@Override
|
|
|
|
|
public void actionPerformed(final ActionEvent e) {
|
|
|
|
|
doubleClickAction();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
this.trayIcon = ImageIO.read(new File(iconPath)); // 128x128
|
|
|
|
|
Image progress_raw = ImageIO.read(new File(progressPath)); // 149x56
|
|
|
|
|
Image progressBooting = ImageIO.read(new File(progressBootingPath)); // 128x28
|
|
|
|
|
BufferedImage progress = new BufferedImage(280, 56, BufferedImage.TYPE_INT_ARGB);
|
|
|
|
|
Graphics2D progressg = progress.createGraphics();
|
|
|
|
|
progressg.drawImage(progress_raw, 0, 0, null);
|
|
|
|
|
progressg.dispose();
|
|
|
|
|
final Image trayIcon = ImageIO.read(new File(iconPath)); // 128x128
|
|
|
|
|
final Image progressBooting = ImageIO.read(new File(sb.getAppPath().toString() + "/addon/progress_booting.png".replace("/", File.separator))); // 128x28
|
|
|
|
|
final BufferedImage progress = getProgressImage();
|
|
|
|
|
this.progressIcons = new BufferedImage[4];
|
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
|
|
|
this.progressIcons[i] = new BufferedImage(128, 128, BufferedImage.TYPE_INT_ARGB);
|
|
|
|
|
Graphics2D h = this.progressIcons[i].createGraphics();
|
|
|
|
|
h.setBackground(Color.BLACK);
|
|
|
|
|
h.clearRect(0, 0, 128, 128);
|
|
|
|
|
h.drawImage(this.trayIcon, 0, 0, 128, 128 - progress.getHeight(), null);
|
|
|
|
|
h.drawImage(trayIcon, 0, 0, 128, 128 - progress.getHeight(), null);
|
|
|
|
|
h.drawImage(progress.getSubimage(i * 7, 0, 128, progress.getHeight() / 2), 0, 128 - progress.getHeight() / 2, null);
|
|
|
|
|
h.drawImage(progressBooting, 0, 128 - progress.getHeight(), null);
|
|
|
|
|
h.dispose();
|
|
|
|
|
}
|
|
|
|
|
final PopupMenu menu = (menuEnabled) ? getPopupMenu() : null;
|
|
|
|
|
ti = new TrayIcon(this.trayIcon, trayLabel, menu);
|
|
|
|
|
ti = new TrayIcon(trayIcon, trayLabel, menu);
|
|
|
|
|
if (OS.isMacArchitecture) setDockIcon(trayIcon);
|
|
|
|
|
ti.setImageAutoSize(true);
|
|
|
|
|
ti.addActionListener(al);
|
|
|
|
@ -118,12 +112,18 @@ public final class Tray {
|
|
|
|
|
} else {
|
|
|
|
|
System.setProperty("java.awt.headless", "true");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (final Exception e) {
|
|
|
|
|
System.setProperty("java.awt.headless", "true");
|
|
|
|
|
} catch (final Exception e) {
|
|
|
|
|
System.setProperty("java.awt.headless", "true");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private boolean useTray() {
|
|
|
|
|
final boolean trayIconEnabled = sb.getConfigBool(SwitchboardConstants.TRAY_ICON_ENABLED, false);
|
|
|
|
|
final boolean trayIconForced = sb.getConfigBool(SwitchboardConstants.TRAY_ICON_FORCED, false);
|
|
|
|
|
return trayIconEnabled && (OS.isWindows || OS.isMacArchitecture || trayIconForced);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private class TrayAnimation extends Thread {
|
|
|
|
|
int ic = 0;
|
|
|
|
|
@Override
|
|
|
|
@ -134,9 +134,15 @@ public final class Tray {
|
|
|
|
|
ic++; if (ic >= 4) ic = 0;
|
|
|
|
|
try {Thread.sleep(80);} catch (InterruptedException e) {break;}
|
|
|
|
|
}
|
|
|
|
|
ti.setImage(Tray.this.trayIcon);
|
|
|
|
|
ti.setToolTip(readyMessage());
|
|
|
|
|
if (OS.isMacArchitecture) setDockIcon(trayIcon);
|
|
|
|
|
try {
|
|
|
|
|
Image trayIcon = ImageIO.read(new File(Tray.this.iconPath));
|
|
|
|
|
ti.setImage(trayIcon);
|
|
|
|
|
ti.setToolTip(readyMessage());
|
|
|
|
|
setDockIcon(trayIcon);
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
ConcurrentLog.logException(e);
|
|
|
|
|
}
|
|
|
|
|
Tray.this.progressIcons = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -157,17 +163,64 @@ public final class Tray {
|
|
|
|
|
*/
|
|
|
|
|
public void setReady() {
|
|
|
|
|
appIsReady = true;
|
|
|
|
|
if (ti != null) {
|
|
|
|
|
ti.setImage(this.trayIcon);
|
|
|
|
|
ti.setToolTip(readyMessage());
|
|
|
|
|
if (useTray()) {
|
|
|
|
|
try {
|
|
|
|
|
Image trayIcon = ImageIO.read(new File(this.iconPath));
|
|
|
|
|
if (ti != null) {
|
|
|
|
|
ti.setImage(trayIcon);
|
|
|
|
|
ti.setToolTip(readyMessage());
|
|
|
|
|
}
|
|
|
|
|
setDockIcon(trayIcon);
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
ConcurrentLog.logException(e);
|
|
|
|
|
}
|
|
|
|
|
if (this.menuItemHeadline != null) this.menuItemHeadline.setLabel(readyMessage());
|
|
|
|
|
if (this.menuItemSearch != null) this.menuItemSearch.setEnabled(true);
|
|
|
|
|
if (this.menuItemAdministration != null) this.menuItemAdministration.setEnabled(true);
|
|
|
|
|
if (this.menuItemTerminate != null) this.menuItemTerminate.setEnabled(true);
|
|
|
|
|
}
|
|
|
|
|
setDockIcon(trayIcon);
|
|
|
|
|
if (this.menuItemHeadline != null) this.menuItemHeadline.setLabel(readyMessage());
|
|
|
|
|
if (this.menuItemSearch != null) this.menuItemSearch.setEnabled(true);
|
|
|
|
|
if (this.menuItemAdministration != null) this.menuItemAdministration.setEnabled(true);
|
|
|
|
|
if (this.menuItemTerminate != null) this.menuItemTerminate.setEnabled(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setShutdown() {
|
|
|
|
|
if (useTray()) {
|
|
|
|
|
try {
|
|
|
|
|
if (ti != null) {
|
|
|
|
|
Image trayIcon = ImageIO.read(new File(this.iconPath)); // 128x128
|
|
|
|
|
final Image progressShutdown = ImageIO.read(new File(sb.getAppPath().toString() + "/addon/progress_shutdown.png".replace("/", File.separator))); // 128x28
|
|
|
|
|
final BufferedImage progress = getProgressImage();
|
|
|
|
|
BufferedImage shutdownIcon;
|
|
|
|
|
shutdownIcon = new BufferedImage(128, 128, BufferedImage.TYPE_INT_ARGB);
|
|
|
|
|
Graphics2D h = shutdownIcon.createGraphics();
|
|
|
|
|
h.setBackground(Color.BLACK);
|
|
|
|
|
h.clearRect(0, 0, 128, 128);
|
|
|
|
|
h.drawImage(trayIcon, 0, 0, 128, 128 - progress.getHeight(), null);
|
|
|
|
|
h.drawImage(progress.getSubimage(0, 0, 128, progress.getHeight() / 2), 0, 128 - progress.getHeight() / 2, null);
|
|
|
|
|
h.drawImage(progressShutdown, 0, 128 - progress.getHeight(), null);
|
|
|
|
|
h.dispose();
|
|
|
|
|
ti.setImage(shutdownIcon);
|
|
|
|
|
setDockIcon(shutdownIcon);
|
|
|
|
|
ti.setToolTip(shutdownMessage());
|
|
|
|
|
}
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
ConcurrentLog.logException(e);
|
|
|
|
|
}
|
|
|
|
|
if (this.menuItemHeadline != null) this.menuItemHeadline.setLabel(shutdownMessage());
|
|
|
|
|
if (this.menuItemSearch != null) this.menuItemSearch.setEnabled(false);
|
|
|
|
|
if (this.menuItemAdministration != null) this.menuItemAdministration.setEnabled(false);
|
|
|
|
|
if (this.menuItemTerminate != null) this.menuItemTerminate.setEnabled(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private BufferedImage getProgressImage() throws IOException {
|
|
|
|
|
final String progressPath = sb.getAppPath().toString() + "/addon/progressbar.png".replace("/", File.separator);
|
|
|
|
|
Image progress_raw = ImageIO.read(new File(progressPath)); // 149x56
|
|
|
|
|
BufferedImage progress = new BufferedImage(149, 56, BufferedImage.TYPE_INT_ARGB);
|
|
|
|
|
Graphics2D progressg = progress.createGraphics();
|
|
|
|
|
progressg.drawImage(progress_raw, 0, 0, null);
|
|
|
|
|
progressg.dispose();
|
|
|
|
|
return progress;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void remove() {
|
|
|
|
|
if (isShown){
|
|
|
|
|
SystemTray.getSystemTray().remove(ti);
|
|
|
|
@ -184,11 +237,16 @@ public final class Tray {
|
|
|
|
|
else
|
|
|
|
|
return "YaCy is starting, please wait...";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private String readyMessage() {
|
|
|
|
|
if (deutsch) return "YaCy laeuft unter http://localhost:" + sb.getConfig("port", "8090");
|
|
|
|
|
return "YaCy is running at http://localhost:" + sb.getConfig("port", "8090");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String shutdownMessage() {
|
|
|
|
|
if (deutsch) return "YaCy wird beendet, bitte warten...";
|
|
|
|
|
return "YaCy will shut down, please wait...";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void doubleClickAction() {
|
|
|
|
|
if (!appIsReady) {
|
|
|
|
|