/*
* Kontalk Java client
* Copyright (C) 2016 Kontalk Devteam <devteam@kontalk.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kontalk.view;
import java.awt.AWTException;
import java.awt.Image;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Observable;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.alee.laf.menu.WebMenuItem;
import com.alee.laf.menu.WebPopupMenu;
import com.alee.laf.rootpane.WebDialog;
import org.kontalk.model.Model;
import org.kontalk.model.chat.ChatList;
import org.kontalk.persistence.Config;
import org.kontalk.util.Tr;
/**
*
* @author Alexander Bikadorov {@literal <bikaejkb@mail.tu-berlin.de>}
*/
final class TrayManager implements ObserverTrait {
private static final Logger LOGGER = Logger.getLogger(TrayManager.class.getName());
private static final Image NORMAL_TRAY = Utils.getImage("kontalk.png");
private static final Image NOTIFICATION_TRAY = Utils.getImage("kontalk_notification.png");
private final View mView;
private final Model mModel;
private final MainFrame mMainFrame;
private TrayIcon mTrayIcon = null;
TrayManager(View view, Model model, MainFrame mainFrame) {
mView = view;
mModel = model;
mMainFrame = mainFrame;
this.setTray();
}
void setTray() {
if (!Config.getInstance().getBoolean(Config.MAIN_TRAY)) {
this.removeTray();
return;
}
if (!SystemTray.isSupported()) {
LOGGER.info("tray icon not supported");
return;
}
if (mTrayIcon == null)
mTrayIcon = this.createTrayIcon();
SystemTray tray = SystemTray.getSystemTray();
if (tray.getTrayIcons().length > 0)
return;
try {
tray.add(mTrayIcon);
} catch (AWTException ex) {
LOGGER.log(Level.WARNING, "can't add tray icon", ex);
}
}
void removeTray() {
if (mTrayIcon != null) {
SystemTray tray = SystemTray.getSystemTray();
tray.remove(mTrayIcon);
}
}
@Override
public void updateOnEDT(Observable o, Object arg) {
if (arg != ChatList.ViewChange.UNREAD)
return;
if (mTrayIcon == null)
return;
mTrayIcon.setImage(getTrayImage());
}
private Image getTrayImage() {
return mModel.chats().isUnread() ?
NOTIFICATION_TRAY :
NORMAL_TRAY ;
}
private TrayIcon createTrayIcon() {
// popup menu outside of frame, officially not supported
final WebPopupMenu popup = new WebPopupMenu();
WebMenuItem quitItem = new WebMenuItem(Tr.tr("Quit"));
quitItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
mView.callShutDown();
}
});
popup.add(quitItem);
// workaround: menu does not disappear when focus is lost
final WebDialog hiddenDialog = new WebDialog();
hiddenDialog.setUndecorated(true);
// create an action listener to listen for default action executed on the tray icon
MouseListener listener = new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
// menu must be shown on mouse release
//check(e);
}
@Override
public void mouseReleased(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1)
mMainFrame.toggleState();
else
check(e);
}
private void check(MouseEvent e) {
// if (!e.isPopupTrigger())
// return;
hiddenDialog.setVisible(true);
// TODO ugly code
popup.setLocation(e.getX() - 20, e.getY() - 40);
popup.setInvoker(hiddenDialog);
popup.setCornerWidth(0);
popup.setVisible(true);
}
};
TrayIcon trayIcon = new TrayIcon(this.getTrayImage(), "Kontalk" /*, popup*/);
trayIcon.setImageAutoSize(true);
trayIcon.addMouseListener(listener);
return trayIcon;
}
}