/**
* Created : Mar 30, 2012
*
* @author pquiring
*/
import java.io.*;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javaforce.*;
import javaforce.jbus.*;
import javaforce.linux.*;
import javaforce.utils.*;
import jffile.*;
public class Dock extends javax.swing.JWindow implements ActionListener, MouseListener, MouseMotionListener, LayoutManager, X11Listener, monitordir.Listener, FileClipboard {
/**
* Creates new form Dock
*/
public Dock() {
try {
initComponents();
IconCache.setPrefix("jfdesktop-");
arrowImage = IconCache.loadIcon("jfdesktop-arrow");
loadNetworkIcons();
dock = this;
x11id = Linux.x11_get_id(this);
JFLog.log("Dock.window=0x" + Long.toString(x11id, 16));
try {
Linux.x11_set_dock(x11id);
} catch (Throwable t) {
JFLog.log(t);
}
addTo = buttons;
loadConfig();
addAppsButton();
addArrows();
getDimensions();
loadButtons();
DisplayMode screen_mode = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDisplayMode();
try {
Linux.x11_set_strut(x11id, (config.autoHide ? 1 : panelHeight-borderSize), 0, 0, screen_mode.getWidth(), screen_mode.getHeight());
} catch (Throwable t) {
JFLog.log(t);
}
JF.sleep(100);
getScreenSize();
soundinit();
initUpgrades();
loadGlobalConfig();
addClock();
setClock();
addTrash();
addKeyboard();
addQuadControls();
addHalfControls();
setLayout(this);
buttons.setLayout(this);
setSize(sx, 1);
setLocation(0, sy-1);
calcDockHeight();
updateConfig();
if (config.autoHide) showDock();
DesktopCache.buildCache();
setupClockTimer();
addMouseListener(this);
addMouseListener(TrashPopup);
addMouseListener(PowerPopup);
addMouseListener(ConfigPopup);
addMouseListener(SoundPopup);
addMouseListener(ClockPopup);
addMouseListener(TaskbarPopup);
//connect to JBus
JFLog.log("jbusClient:package=org.jflinux.jfdesktop." + System.getenv("JID"));
jbusClient = new JBusClient("org.jflinux.jfdesktop." + System.getenv("JID"), new JBusMethods());
jbusClient.start();
if (new File("/usr/sbin/hciconfig").exists()) {
checkBluetooth();
}
if (new File("/usr/bin/jfwelcome").exists()) {
if (config.welcome) {
showWelcome();
}
}
startTrashListener();
mkdirs();
keyboardWindow = new KeyboardWindow();
Linux.x11_set_listener(this);
new Thread() {
public void run() {
try {
//monitor system tray
Linux.x11_tray_main(x11id, sx, trayPos, buttonHeight + 4);
} catch (Throwable t) {
JFLog.log(t);
}
}
}.start();
new Thread() {
public void run() {
try {
//monitor when top-level windows change
Linux.x11_window_list_main();
} catch (Throwable t) {
JFLog.log(t);
}
}
}.start();
JF.sleep(250); //wait for threads to start
if (new File("/usr/bin/acpi").exists()) {
checkBattery();
}
try {
Linux.x11_set_dock(x11id);
} catch (Throwable t) {
JFLog.log(t);
}
new Thread() {
public void run() {
loadMappings(); //can take a while
}
}.start();
initDockDND();
getWAPList();
JFLog.log("Dock init complete");
} catch (Throwable t) {
JFLog.log(t);
}
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
TrashPopup = new javax.swing.JPopupMenu();
EmptyTrash = new javax.swing.JMenuItem();
PowerPopup = new javax.swing.JPopupMenu();
Logoff = new javax.swing.JMenuItem();
Reboot = new javax.swing.JMenuItem();
Shutdown = new javax.swing.JMenuItem();
Sleep = new javax.swing.JMenuItem();
ConfigPopup = new javax.swing.JPopupMenu();
ControlCenter = new javax.swing.JMenuItem();
DesktopSettings = new javax.swing.JMenuItem();
Upgrades = new javax.swing.JMenuItem();
Run = new javax.swing.JMenuItem();
Help = new javax.swing.JMenuItem();
SoundPopup = new javax.swing.JPopupMenu();
Settings = new javax.swing.JMenuItem();
ClockPopup = new javax.swing.JPopupMenu();
AdjustTime = new javax.swing.JMenuItem();
BatteryPopup = new java.awt.PopupMenu();
BatterySettings = new java.awt.MenuItem();
TaskbarPopup = new javax.swing.JPopupMenu();
MinimizeAll = new javax.swing.JMenuItem();
jSeparator1 = new javax.swing.JPopupMenu.Separator();
TaskMgr = new javax.swing.JMenuItem();
jSeparator2 = new javax.swing.JPopupMenu.Separator();
DockSettings = new javax.swing.JMenuItem();
buttons = new javax.swing.JPanel();
EmptyTrash.setText("Empty");
EmptyTrash.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
EmptyTrashActionPerformed(evt);
}
});
TrashPopup.add(EmptyTrash);
Logoff.setText("Logff");
Logoff.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
LogoffActionPerformed(evt);
}
});
PowerPopup.add(Logoff);
Reboot.setText("Reboot");
Reboot.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
RebootActionPerformed(evt);
}
});
PowerPopup.add(Reboot);
Shutdown.setText("Shutdown");
Shutdown.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
ShutdownActionPerformed(evt);
}
});
PowerPopup.add(Shutdown);
Sleep.setText("Sleep");
Sleep.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
SleepActionPerformed(evt);
}
});
PowerPopup.add(Sleep);
ControlCenter.setText("Control Center");
ControlCenter.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
ControlCenterActionPerformed(evt);
}
});
ConfigPopup.add(ControlCenter);
DesktopSettings.setText("Desktop Settings");
DesktopSettings.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
DesktopSettingsActionPerformed(evt);
}
});
ConfigPopup.add(DesktopSettings);
Upgrades.setText("Upgrades");
Upgrades.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
UpgradesActionPerformed(evt);
}
});
ConfigPopup.add(Upgrades);
Run.setText("Run");
Run.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
RunActionPerformed(evt);
}
});
ConfigPopup.add(Run);
Help.setText("Help");
Help.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
HelpActionPerformed(evt);
}
});
ConfigPopup.add(Help);
Settings.setText("Settings");
Settings.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
SettingsActionPerformed(evt);
}
});
SoundPopup.add(Settings);
AdjustTime.setText("Adjust Date & Time");
AdjustTime.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
AdjustTimeActionPerformed(evt);
}
});
ClockPopup.add(AdjustTime);
BatteryPopup.setName("");
BatterySettings.setLabel("Settings");
BatterySettings.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
BatterySettingsActionPerformed(evt);
}
});
BatteryPopup.add(BatterySettings);
MinimizeAll.setText("Show the desktop");
MinimizeAll.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
MinimizeAllActionPerformed(evt);
}
});
TaskbarPopup.add(MinimizeAll);
TaskbarPopup.add(jSeparator1);
TaskMgr.setText("Start Task Manager");
TaskMgr.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
TaskMgrActionPerformed(evt);
}
});
TaskbarPopup.add(TaskMgr);
TaskbarPopup.add(jSeparator2);
DockSettings.setText("Settings");
DockSettings.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
DockSettingsActionPerformed(evt);
}
});
TaskbarPopup.add(DockSettings);
setAlwaysOnTop(true);
setMinimumSize(new java.awt.Dimension(1, 1));
setName("dock"); // NOI18N
buttons.setMinimumSize(new java.awt.Dimension(1, 1));
buttons.setPreferredSize(new java.awt.Dimension(1, 1));
javax.swing.GroupLayout buttonsLayout = new javax.swing.GroupLayout(buttons);
buttons.setLayout(buttonsLayout);
buttonsLayout.setHorizontalGroup(
buttonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 545, Short.MAX_VALUE)
);
buttonsLayout.setVerticalGroup(
buttonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 1, Short.MAX_VALUE)
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(buttons, javax.swing.GroupLayout.DEFAULT_SIZE, 545, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(buttons, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
pack();
}// </editor-fold>//GEN-END:initComponents
private void EmptyTrashActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_EmptyTrashActionPerformed
emptyTrash();
}//GEN-LAST:event_EmptyTrashActionPerformed
private void LogoffActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_LogoffActionPerformed
if (!JF.showConfirm("Confirm", "Are you sure you want to logoff?")) return;
closeAllApps();
System.exit(0);
}//GEN-LAST:event_LogoffActionPerformed
private void RebootActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_RebootActionPerformed
if (!JF.showConfirm("Confirm", "Are you sure you want to reboot?")) return;
jbusClient.call("org.jflinux.jfsystemmgr", "reboot", "");
closeAllApps();
System.exit(0);
}//GEN-LAST:event_RebootActionPerformed
private void ShutdownActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ShutdownActionPerformed
if (!JF.showConfirm("Confirm", "Are you sure you want to shutdown?")) return;
jbusClient.call("org.jflinux.jfsystemmgr", "shutdown", "");
closeAllApps();
System.exit(0);
}//GEN-LAST:event_ShutdownActionPerformed
private void ControlCenterActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ControlCenterActionPerformed
try {
Runtime.getRuntime().exec("jconfig");
} catch (Exception e) {
JFLog.log(e);
}
}//GEN-LAST:event_ControlCenterActionPerformed
private void DesktopSettingsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_DesktopSettingsActionPerformed
showConfig();
}//GEN-LAST:event_DesktopSettingsActionPerformed
private void SleepActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SleepActionPerformed
//disconnect all VPN
jbusClient.call("org.jflinux", "closeAllVPN", "");
JF.sleep(500);
jbusClient.call("org.jflinux.jfsystemmgr", "sleep" , "");
//reset clock after 10 seconds (hopefully after we resume from sleep)
new java.util.Timer().schedule(new TimerTask() {
public void run() {
setClock();
}
}, 10 * 1000);
}//GEN-LAST:event_SleepActionPerformed
private void SettingsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SettingsActionPerformed
try {
Runtime.getRuntime().exec(new String[] {"jconfig", "sound"});
} catch (Exception e) {
JFLog.log(e);
}
}//GEN-LAST:event_SettingsActionPerformed
private void AdjustTimeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_AdjustTimeActionPerformed
try {
Runtime.getRuntime().exec(new String[] {"jconfig", "datetime"});
} catch (Exception e) {
JFLog.log(e);
}
}//GEN-LAST:event_AdjustTimeActionPerformed
private void HelpActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_HelpActionPerformed
try {
Runtime.getRuntime().exec(new String[] {"jhelp", "jfdesktop"});
} catch (Exception e) {
JFLog.log(e);
}
}//GEN-LAST:event_HelpActionPerformed
private void RunActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_RunActionPerformed
doRun();
}//GEN-LAST:event_RunActionPerformed
private void UpgradesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_UpgradesActionPerformed
try { Runtime.getRuntime().exec("jupgrade"); } catch (Exception e) {JFLog.log(e);}
}//GEN-LAST:event_UpgradesActionPerformed
private void BatterySettingsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_BatterySettingsActionPerformed
new BatteryDialog(null, true).setVisible(true);
}//GEN-LAST:event_BatterySettingsActionPerformed
private void DockSettingsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_DockSettingsActionPerformed
showConfig();
}//GEN-LAST:event_DockSettingsActionPerformed
private void MinimizeAllActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MinimizeAllActionPerformed
Linux.x11_minimize_all();
}//GEN-LAST:event_MinimizeAllActionPerformed
private void TaskMgrActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_TaskMgrActionPerformed
try {
Runtime.getRuntime().exec("jtaskmgr");
} catch (Exception e) {
JFLog.log(e);
}
}//GEN-LAST:event_TaskMgrActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JMenuItem AdjustTime;
private java.awt.PopupMenu BatteryPopup;
private java.awt.MenuItem BatterySettings;
private javax.swing.JPopupMenu ClockPopup;
private javax.swing.JPopupMenu ConfigPopup;
private javax.swing.JMenuItem ControlCenter;
private javax.swing.JMenuItem DesktopSettings;
private javax.swing.JMenuItem DockSettings;
private javax.swing.JMenuItem EmptyTrash;
private javax.swing.JMenuItem Help;
private javax.swing.JMenuItem Logoff;
private javax.swing.JMenuItem MinimizeAll;
private javax.swing.JPopupMenu PowerPopup;
private javax.swing.JMenuItem Reboot;
private javax.swing.JMenuItem Run;
private javax.swing.JMenuItem Settings;
private javax.swing.JMenuItem Shutdown;
private javax.swing.JMenuItem Sleep;
private javax.swing.JPopupMenu SoundPopup;
private javax.swing.JMenuItem TaskMgr;
private javax.swing.JPopupMenu TaskbarPopup;
private javax.swing.JPopupMenu TrashPopup;
private javax.swing.JMenuItem Upgrades;
private javax.swing.JPanel buttons;
private javax.swing.JPopupMenu.Separator jSeparator1;
private javax.swing.JPopupMenu.Separator jSeparator2;
// End of variables declaration//GEN-END:variables
public static class App {
public String file;
}
public static class Card {
public int idx;
public String activeProfile;
}
public static class Sink {
public int idx;
public String activePort;
public int volume; //%
}
public static class Source {
public int idx;
public String activePort;
public int volume; //%
}
public static class Config {
public Config() {
dock = new App[0];
}
public boolean showClock;
public boolean showKeyboard;
public boolean autoHide;
public boolean welcome;
public boolean compact;
public boolean showIcons; //on Desktop
public boolean arrangeIconsAuto; //on Desktop
public boolean mountAudio;
public int desktopMode;
public String desktopFile;
public App dock[]; //for Dock
public Color bc, fc; //back fore color (desktop)
//sound config
public Card card[];
public Sink sink[];
public Source source[];
public int dockSize; //48, 32, 24
//video config (TODO) - for now in .xrandr.xml
}
public static class GlobalConfig {
public boolean disableSleep;
}
public static class BlueToothDevice {
String desc, mac;
}
public Config config = new Config();
private String configFile = ".jfdesktop.xml";
private GlobalConfig globalConfig = new GlobalConfig();
private String globalConfigFolder = "/etc/jconfig.d/";
private String globalConfigFile = "global.xml";
private int appIdx = 0; //where to insert next button
private int viewIdx = 0; //first app to show if not all fit on dock
private int overflowCnt = 0;
private boolean needArrows = false;
public static int sx, sy; //screen size
private JFImage clockImage;
private Font clockFont;
private String clockLine1 = "MONTH DAY", clockLine2 = "HH:MM";
private JButton left, right, apps, trash, keyboard;
private JButton soundQuad, networkQuad, powerQuad, settingsQuad;
private JButton soundHalf, networkHalf, powerHalf, settingsHalf;
private JFImage batteryImage, trashFullImage, trashEmptyImage;
private JPanel quad;
private SystemTray tray;
private TrayIcon trayIcon;
private boolean haveMouse = true;
private boolean isDockHidden = true;
private int panelHeight, buttonWidth, buttonHeight, halfWidth;
private int panelHiddenHeight = 1;
private CalendarWindow calWindow;
private SoundWindow soundWindow;
public KeyboardWindow keyboardWindow;
private boolean keyboardShown = false;
public static JBusClient jbusClient;
private boolean isTrashFull;
public static BlueToothDialog btDialog;
private java.util.Timer clockTimer;
private java.util.Timer flashTimer;
private java.util.Timer autoHideTimer;
private JPopupMenu NetworkPopup = new JPopupMenu();
public static Dock dock;
private long x11id;
public static ArrayList<BlueToothDevice> btDevices = new ArrayList<BlueToothDevice>();
private int buttonsCount = 0; //# of app buttons shown in dock (pinned & !pinned)
private String fileSelection = "";
private static final int borderSize = 4;
private int trayPos = 0;
private final int trayPad = 2;
private JButton newButton;
private int newButtonIdx;
public void trayIconAdded(int count) {
JFLog.log("Dock:tray icon added");
}
public void trayIconRemoved(int count) {
JFLog.log("Dock:tray icon removed");
}
private boolean updatePending = false;
public void windowsChanged() {
if (updatePending) return;
updatePending = true;
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
updateWindowList();
}
});
}
private static class Window {
public long xid;
public String title;
public Window(long xid, String title) {
this.xid = xid;
this.title = title;
}
public void show() {
Linux.x11_map_window(xid);
Linux.x11_raise_window(xid);
}
}
private static class Group {
public ArrayList<Window> windows = new ArrayList<Window>();
public void updateTitle(long xid, String title) {
for(int a=0;a<windows.size();a++) {
Window window = windows.get(a);
if (window.xid == xid) {
window.title = title;
return;
}
}
addWindow(xid, title);
}
public void addWindow(long xid, String title) {
windows.add(new Window(xid, title));
}
public void clearWindows() {
windows.clear();
}
public void removeWindow(int idx) {
windows.remove(idx);
}
public void removeWindow(long xid) {
for(int a=0;a<windows.size();a++) {
Window window = windows.get(a);
if (window.xid == xid) {
windows.remove(a);
return;
}
}
}
public boolean isEmpty() {
return windows.isEmpty();
}
public Window getWindow(int idx) {
return windows.get(idx);
}
public int size() {
return windows.size();
}
}
//updates the active windows list
private synchronized void updateWindowList() {
//add buttons
updatePending = false;
try {
Linux.Window winList[] = Linux.x11_get_window_list();
Component buts[] = buttons.getComponents();
for(int w=0;w<winList.length;w++) {
Linux.Window x11window = winList[w];
// JFLog.log("window:xid=" + Integer.toString(JF.atoi(x11window.xid.toString()), 16) + ",pid=" + x11window.pid + ",title=" + x11window.title + ",res_class=" + x11window.res_class + ",res_name=" + x11window.res_name);
x11window.file = null;
if (x11window.pid != -1) x11window.file = DesktopCache.getDesktopFromPID(x11window.pid);
if (x11window.file == null && x11window.title.length() > 0) x11window.file = DesktopCache.getDesktopFromText(x11window.title);
if (x11window.file == null && x11window.res_class.length() > 0) x11window.file = DesktopCache.getDesktopFromText(x11window.res_class);
if (x11window.file == null) {
//unable to match window (TODO : create a generic button? : would need to copy icon)
JFLog.log("Dock:Unable to match window to application:" + x11window.title);
continue;
}
boolean ok = false;
for(int b=0;b<buts.length;b++) {
if (!(buts[b] instanceof JButton)) continue;
JButton button = (JButton)buts[b];
String file = (String)button.getClientProperty("file");
if (file.startsWith("#")) continue;
Group group = (Group)button.getClientProperty("group");
if (file.equals(x11window.file)) {
group.updateTitle(x11window.xid, x11window.title);
ok = true;
break;
}
}
if (ok) continue;
//add new button
JButton button = addButton(x11window.file, false, -1);
Group group = (Group)button.getClientProperty("group");
group.addWindow(x11window.xid, x11window.title);
buts = buttons.getComponents();
}
//remove buttons
for(int b=0;b<buts.length;b++) {
if (!(buts[b] instanceof JButton)) continue;
JButton button = (JButton)buts[b];
String file = (String)button.getClientProperty("file");
if (file.startsWith("#")) continue;
Group group = (Group)button.getClientProperty("group");
boolean group_ok = false;
for(int g=0;g<group.size();) {
Window window = group.getWindow(g);
boolean window_ok = false;
for(int w=0;w<winList.length;w++) {
Linux.Window x11window = winList[w];
if (x11window.xid == window.xid) {group_ok = true; window_ok = true; break;}
}
if (!window_ok) {
group.removeWindow(g);
} else {
g++;
}
}
if (group_ok) {
createAppPopupMenu(button);
continue;
}
//remove button (if not pinned)
Boolean pinned = (Boolean)button.getClientProperty("pinned");
if (!pinned) {
removeButton(button);
//NOTE:do NOT update buts list
} else {
createAppPopupMenu(button); //remove any windows
}
}
} catch (Exception e) {
JFLog.log(e);
}
}
private void togglePinned(JButton button) {
String file = (String)button.getClientProperty("file");
Boolean pinned = (Boolean)button.getClientProperty("pinned");
Group group = (Group)button.getClientProperty("group");
if (pinned) {
if (group.isEmpty()) {
removeButton(button);
} else {
button.putClientProperty("pinned", new Boolean(false));
}
} else {
button.putClientProperty("pinned", new Boolean(true));
addApp(file);
saveConfig();
}
createAppPopupMenu(button);
}
public void loadConfig() {
config.card = new Card[0];
config.sink = new Sink[0];
config.source = new Source[0];
config.dock = new App[0];
config.showClock = true;
config.showKeyboard = true;
config.dockSize = 48;
try {
XML xml = new XML();
FileInputStream fis = new FileInputStream(JF.getUserPath() + "/" + configFile);
byte data[] = JF.readAll(fis);
String str = new String(data);
str = str.replaceAll("app>", "dock>"); //convert pre 6.5 config
xml.read(new ByteArrayInputStream(str.getBytes()));
//remove old "desktop" config
for(int a=0;a<xml.root.getChildCount();) {
if (xml.root.getChildAt(a).getName().equals("desktop")) {
xml.root.remove(a);
} else {
a++;
}
}
xml.writeClass(config);
} catch (FileNotFoundException e1) {
defaultConfig();
} catch (Exception e2) {
JFLog.log(e2);
defaultConfig();
}
validateConfig();
bx = config.dockSize;
by = config.dockSize;
}
public void validateConfig() {
if (config.dockSize != 48 && config.dockSize != 32 && config.dockSize != 24) {
config.dockSize = 48;
}
}
public void getDimensions() {
Dimension d = apps.getPreferredSize();
buttonWidth = d.width;
buttonHeight = d.height;
panelHeight = d.height + borderSize * 2;
d = left.getPreferredSize();
halfWidth = d.width;
}
public void loadGlobalConfig() {
try {
XML xml = new XML();
FileInputStream fis = new FileInputStream(globalConfigFolder + "/" + globalConfigFile);
xml.read(fis);
xml.writeClass(globalConfig);
} catch (FileNotFoundException fnfe) {
defaultGlobalConfig();
return;
} catch (Exception e) {
defaultGlobalConfig();
JFLog.log(e);
}
if (globalConfig.disableSleep) {
PowerPopup.remove(Sleep);
PowerPopup.remove(Reboot);
PowerPopup.remove(Shutdown);
}
}
private void defaultGlobalConfig() {
globalConfig.disableSleep = false;
}
public synchronized void saveConfig() {
try {
XML xml = new XML();
FileOutputStream fos = new FileOutputStream(JF.getUserPath() + "/" + configFile);
xml.readClass("jfdesktop", config);
xml.write(fos);
fos.close();
} catch (Exception e) {
JFLog.log(e);
}
}
public void defaultConfig() {
config = new Config();
config.showClock = true;
config.showKeyboard = true;
config.autoHide = true;
config.welcome = true;
config.showIcons = true;
config.mountAudio = true;
config.dock = new App[0];
config.desktopFile = "/usr/share/icons/hicolor/48x48/apps/jfdesktop-wallpaper.png";
config.desktopMode = 3;
config.bc = Color.BLUE;
config.fc = Color.WHITE;
config.dockSize = 48;
//add jfile
addAppIfExists("jfile");
//add jinstall
if (new File("/etc/.live").exists()) {
addAppIfExists("jinstall");
}
//add Chrome (if installed)
addAppIfExists("chromium-browser");
addAppIfExists("chrome");
addAppIfExists("google-chrome");
//add Firefox (if installed)
addAppIfExists("firefox");
//add libre Office
addAppIfExists("libreoffice-startcenter");
addAppIfExists("libreoffice-writer");
addAppIfExists("libreoffice-calc");
//add japps
addAppIfExists("japps");
saveConfig();
}
private void getScreenSize() {
DisplayMode mode = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDisplayMode();
sx = mode.getWidth();
sy = mode.getHeight();
JFLog.log("ScreenSize:" + sx + "," + sy);
}
private void _setPosition() {
if (config.autoHide) {
setSize(sx, dockHeight);
setLocation(0, sy - dockHeight);
} else {
setSize(sx, panelHeight - borderSize);
setLocation(0, sy - (panelHeight - borderSize));
}
}
private void setPosition() {
if (java.awt.EventQueue.isDispatchThread()) {
_setPosition();
} else {
try {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
_setPosition();
}
});
} catch (Exception e) {
JFLog.log(e);
}
}
}
private void removeButton(JButton b) {
try {
String file = (String)b.getClientProperty("file");
buttons.remove(b);
appIdx--;
if (!file.startsWith("#")) {
buttonsCount--;
}
updateButtons();
for(int a=0;a<config.dock.length;a++) {
if (config.dock[a].file.equals(file)) {
removeApp(a);
break;
}
}
} catch (Exception e) {
JFLog.log(e);
}
}
private void copyButtonToDesktop(JButton b) {
String src = (String)b.getClientProperty("file");
int idx = src.lastIndexOf("/");
String dest = JF.getUserPath() + "/Desktop" + src.substring(idx);
boolean exists;
int i = 1;
do {
exists = new File(dest).exists();
if (exists) {
dest = dest.substring(0, dest.length() -8) + "(" + i++ + ").desktop";
}
} while (exists);
JF.copyAll(src, dest);
}
private void removeApp(int idx) {
App newList[] = new App[config.dock.length - 1];
System.arraycopy(config.dock, 0, newList, 0, idx);
System.arraycopy(config.dock, idx+1, newList, idx, config.dock.length - idx - 1);
config.dock = newList;
saveConfig();
}
private int bx = 48, by = 48; //button size
private JComponent addTo;
private JFImage buttonImage, arrowImage;
private boolean addArrow = false;
private boolean halfSized = false;
public JButton addButton(String icon, String name, String file, int idx, boolean pinned) {
buttonImage = IconCache.loadIcon(icon);
int _bx = bx;
int _by = by;
if (halfSized) {
_bx /= 2;
}
if (addArrow) {
buttonImage = IconCache.scaleIcon(buttonImage, _bx, _bx);
JFImage tmpImage = new JFImage(_bx, _by);
tmpImage.fill(0, 0, _bx, _by, 0, true);
tmpImage.getGraphics().drawImage(buttonImage.getImage(), 0,(_by-_bx)/2 + 4, null);
tmpImage.getGraphics().drawImage(arrowImage.getImage(),
0,0, _bx,_by/6, //dest
0,0, 24,8, //src
null);
buttonImage = tmpImage;
} else {
buttonImage = IconCache.scaleIcon(buttonImage, _bx, _by);
}
JButton button = new JButton(buttonImage);
button.setMargin(new Insets(0,0,0,0));
button.setActionCommand(file);
button.setContentAreaFilled(false);
button.addActionListener(this);
// button.setToolTipText(name); //mouse over the tooltip causes dock to hide
button.addMouseListener(this);
button.putClientProperty("file", file);
button.putClientProperty("icon", icon);
button.putClientProperty("arrow", new Boolean(addArrow));
button.putClientProperty("halfSized", new Boolean(halfSized));
button.putClientProperty("pinned", new Boolean(pinned));
button.putClientProperty("group", new Group());
if (!file.startsWith("#")) {
createAppPopupMenu(button);
button.addMouseMotionListener(this);
buttonsCount++;
}
addTo.add(button, idx);
updateButtons();
return button;
}
public JButton addButton(String file, boolean pinned, int idx) {
String name = null, icon = null;
try {
FileInputStream fis = new FileInputStream(file);
byte data[] = JF.readAll(fis);
fis.close();
String str = new String(data);
String lns[] = str.split("\n");
boolean desktopEntry = false;
for(int a=0;a<lns.length;a++) {
if (lns[a].startsWith("[Desktop Entry]")) {
desktopEntry = true;
continue;
}
if (lns[a].startsWith("[")) desktopEntry = false;
if (!desktopEntry) continue;
if (lns[a].startsWith("Name=")) {
name = lns[a].substring(5);
}
if (lns[a].startsWith("Icon=")) {
icon = lns[a].substring(5);
}
}
if ((name == null) || (icon == null)) {
JF.showError("Error", "Unable to add app:" + file);
return null;
}
if (idx == -1) idx = appIdx++; else appIdx++;
return addButton(icon, name, file, idx, pinned);
} catch (Exception e) {
JFLog.log(e);
return null;
}
}
public void updateButtonIcon(JButton b) {
String icon = (String)b.getClientProperty("icon");
if (icon == null) return;
Boolean arrow = (Boolean)b.getClientProperty("arrow");
Boolean half = (Boolean)b.getClientProperty("halfSized");
int _bx = bx;
int _by = by;
if (half) {
_bx /= 2;
}
buttonImage = IconCache.loadIcon(icon);
if (arrow) {
buttonImage = IconCache.scaleIcon(buttonImage, _bx, _bx);
JFImage tmpImage = new JFImage(_bx, _by);
tmpImage.fill(0, 0, _bx, _by, 0, true);
tmpImage.getGraphics().drawImage(buttonImage.getImage(), 0,(_by-_bx)/2 + 4, null);
tmpImage.getGraphics().drawImage(arrowImage.getImage(),
0,0, _bx,_by/6, //dest
0,0, 24,8, //src
null);
buttonImage = tmpImage;
} else {
buttonImage = IconCache.scaleIcon(buttonImage, _bx, _by);
}
b.setIcon(buttonImage);
}
public void updateButtonsIcons() {
//resize all button icons
Component c[] = (Component[])buttons.getComponents();
for(int a=0;a<c.length;a++) {
if (!(c[a] instanceof JButton)) continue;
JButton b = (JButton)c[a];
updateButtonIcon(b);
}
}
public void loadButtons() {
//load buttons for config.app[]
for(int a=0;a<config.dock.length;) {
if (addButton(config.dock[a].file, true, -1) == null) {
removeApp(a);
} else {
a++;
}
}
}
public boolean haveApp(String file) {
Component buts[] = buttons.getComponents();
for(int a=0;a<buts.length;a++) {
if (!(buts[a] instanceof JButton)) continue;
JButton b = (JButton)buts[a];
String bfile = (String)b.getClientProperty("file");
if (bfile.equals(file)) return true;
}
return false;
}
public void updateConfig() {
validateConfig();
bx = config.dockSize;
by = config.dockSize;
updateButtonIcon(apps);
updateButtonIcon(left);
updateButtonIcon(right);
getDimensions();
DisplayMode screen_mode = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDisplayMode();
JFLog.log("updateConfig:screen=" + screen_mode.getWidth() + "x" + screen_mode.getHeight());
try {
Linux.x11_set_strut(x11id, (config.autoHide ? 1 : panelHeight-borderSize), 0, 0, screen_mode.getWidth(), screen_mode.getHeight());
} catch (Throwable t) {
JFLog.log(t);
}
getScreenSize();
if (Desktop.desktop != null) {
Desktop.desktop.browser.setWallPaper(config.desktopFile, config.desktopMode);
Desktop.desktop.setPosition();
}
if (!config.autoHide) {
if (isDockHidden) {
showDock();
} else {
setPosition();
}
} else {
if (isDockHidden) {
setPosition();
} else {
hideDock();
}
}
if (config.showClock) {
buttons.add(clockImage);
} else {
buttons.remove(clockImage);
}
if (config.compact) {
buttons.add(quad);
buttons.remove(powerHalf);
buttons.remove(settingsHalf);
buttons.remove(networkHalf);
buttons.remove(soundHalf);
} else {
buttons.remove(quad);
buttons.add(powerHalf);
buttons.add(settingsHalf);
buttons.add(networkHalf);
buttons.add(soundHalf);
}
if (config.showKeyboard) {
buttons.add(keyboard);
} else {
buttons.remove(keyboard);
}
bx = config.dockSize;
by = config.dockSize;
updateButtonsIcons();
updateButtons();
}
public void addAppsButton() {
apps = addButton("jfdesktop-apps", "Add", "#apps", appIdx++, true);
}
public void addClock() {
clockImage = new JFImage() {
public void paint(Graphics g) {
FontMetrics fm = clockImage.getFontMetrics(clockImage.getFont());
Dimension size = clockImage.getPreferredSize();
int height = fm.getHeight();
g.setColor(Color.white);
g.drawRect(0,0, size.width,size.height);
g.setColor(Color.black);
g.setFont(clockFont);
if (config.dockSize >= 32) {
int width = fm.stringWidth(clockLine1);
g.drawBytes(clockLine1.getBytes(), 0, clockLine1.length(),
(size.width - width) / 2, ((size.height/2 - height) / 2) + height);
width = fm.stringWidth(clockLine2);
g.drawBytes(clockLine2.getBytes(), 0, clockLine2.length(),
(size.width - width) / 2, (size.height/2) + ((size.height/2 - height) / 2) + (height/2)); //BUG : last /2 shouldn't be needed but is
} else {
//can only do one line
int width = fm.stringWidth(clockLine2);
g.drawBytes(clockLine2.getBytes(), 0, clockLine2.length(),
(size.width - width) / 2, ((size.height - height)/2) + height);
}
}
public Dimension getPreferredSize() {
Dimension size = new Dimension();
FontMetrics fm = clockImage.getFontMetrics(clockImage.getFont());
size.width = fm.stringWidth("88:88:88 AM");
size.height = buttonHeight;
return size;
}
};
clockFont = new Font(null, Font.BOLD, 12);
clockImage.setComponentPopupMenu(ClockPopup);
clockImage.addMouseListener(this);
clockImage.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent me) {
try {
if (calWindow == null) showCalendar(); else hideCalendar();
} catch (Exception e) {JFLog.log(e);}
}
});
if (config.showClock) buttons.add(clockImage);
}
public int getLastIdx() {
return buttons.getComponentCount()-1;
}
public void folderChangeEvent(String event, String file) {
if (event.equals("CREATED")) {
trashFull();
} else if (event.equals("DELETED")) {
if (!isTrashFull()) {
trashEmpty();
}
}
}
private int monitor;
private void startTrashListener() {
File file = new File(System.getenv("HOME") + "/.local/share/Trash");
file.mkdirs();
JFLog.log("Starting Trash monitor");
monitor = monitordir.add(file.getAbsolutePath());
monitordir.setListener(monitor, this);
}
private boolean isTrashFull() {
File file = new File(JF.getUserPath() + "/.local/share/Trash");
if (!file.exists()) return false;
File files[] = file.listFiles();
if (files == null) return false;
return files.length > 0;
}
public void trashFull() {
if (isTrashFull) return;
isTrashFull = true;
trash.setIcon(trashFullImage);
validate();
repaint();
}
public void trashEmpty() {
isTrashFull = false;
trash.setIcon(trashEmptyImage);
validate();
repaint();
}
private void addTrash() {
trashEmptyImage = IconCache.scaleIcon(IconCache.loadIcon("jfdesktop-trash-empty"), bx, by);
trashFullImage = IconCache.scaleIcon(IconCache.loadIcon("jfdesktop-trash-full"), bx, by);
trash = addButton((isTrashFull() ? "jfdesktop-trash-full" : "jfdesktop-trash-empty"), "Trash", "#trash", getLastIdx(), true);
trash.setComponentPopupMenu(TrashPopup);
initTrashDND();
}
private void addKeyboard() {
addArrow = true;
halfSized = true;
keyboard = addButton("jfdesktop-keyboard", "Keyboard", "#keyboard", getLastIdx(), true);
bx = config.dockSize;
addArrow = false;
halfSized = false;
}
private void addQuadControls() {
quad = new JPanel();
quad.setLayout(new GridLayout(2,2));
addTo = quad;
halfSized = true;
powerQuad = addButton("jfdesktop-power", "Power", "#power", 0, true);
powerQuad.setComponentPopupMenu(PowerPopup);
settingsQuad = addButton("jfdesktop-config", "Settings", "#config", 0, true);
settingsQuad.setComponentPopupMenu(ConfigPopup);
networkQuad = addButton("jfdesktop-network", "Network", "#network", 0, true);
soundQuad = addButton("jfdesktop-sound", "Sound", "#sound", 0, true);
soundQuad.setComponentPopupMenu(SoundPopup);
addTo = buttons;
halfSized = false;
if (config.compact) buttons.add(quad, getLastIdx());
}
private void addHalfControls() {
if (config.compact) addTo = new JPanel();
addArrow = true;
halfSized = true;
powerHalf = addButton("jfdesktop-power", "Power", "#power", 0, true);
powerHalf.setComponentPopupMenu(PowerPopup);
settingsHalf = addButton("jfdesktop-config", "Settings", "#config", 0, true);
settingsHalf.setComponentPopupMenu(ConfigPopup);
networkHalf = addButton("jfdesktop-network", "Network", "#network", 0, true);
soundHalf = addButton("jfdesktop-sound", "Sound", "#sound", 0, true);
soundHalf.setComponentPopupMenu(SoundPopup);
addTo = buttons;
addArrow = false;
halfSized = false;
}
public void addArrows() {
halfSized = true;
left = addButton("jfdesktop-left", "Left", "#left", getLastIdx(), true);
buttons.remove(left);
right = addButton("jfdesktop-right", "Right", "#right", getLastIdx(), true);
buttons.remove(right);
halfSized = false;
}
private void addApp(String desktop) {
App app = new App();
app.file = desktop;
App newList[] = new App[config.dock.length + 1];
System.arraycopy(config.dock, 0, newList, 0, config.dock.length);
newList[config.dock.length] = app;
config.dock = newList;
}
private void addAppIfExists(String filename) {
File fullPath = new File("/usr/share/applications/" + filename + ".desktop");
if (fullPath.exists()) addApp(fullPath.getAbsolutePath());
}
private int calcMenuHeight(JPopupMenu menu) {
return menu.getComponentCount() * 18 + 9;
}
private AddAppWindow appsDialog;
public void addAppDialogClosed() {
appsDialog = null;
}
public void actionPerformed(ActionEvent ae) {
try {
if (dragged) {
dragged = false;
return;
}
String action = ae.getActionCommand();
if (calWindow != null) {
hideCalendar();
}
if ((soundWindow != null) && (!action.equals("#sound"))) {
hideSound();
}
if (action.equals("#battery")) {
updateBattery();
return;
}
if (action.equals("#new")) {
//BUG : user should never be able to click this
removeNewButton();
updateButtons();
return;
}
if (action.equals("#apps")) {
if (appsDialog != null) {
appsDialog.toFront();
} else {
appsDialog = new AddAppWindow();
appsDialog.setVisible(true);
}
return;
}
if (action.equals("#bt-connect")) {
btDialog = new BlueToothDialog();
btDialog.setVisible(true);
return;
}
if (action.equals("#vpn-configure")) {
try {
Runtime.getRuntime().exec(new String[] {"jconfig", "vpn"});
} catch (Exception e) {
JFLog.log(e);
}
return;
}
if (action.startsWith("#bt#")) {
blueToothDisconnect(action.substring(4));
return;
}
if (action.equals("#sound")) {
try {
if (soundWindow == null) showSound(); else hideSound();
} catch (Exception e) {JFLog.log(e);}
return;
}
if (action.equals("#network")) {
if (networkTimer != null) {
cancelNetworkConnection();
} else {
getVPNList(); //triggers showNetworkPopup()
}
return;
}
if (action.equals("#config")) {
showSettingsPopup();
return;
}
if (action.equals("#left")) {
if (viewIdx > 0) {
viewIdx--;
overflowCnt++;
updateButtons();
}
return;
}
if (action.equals("#right")) {
if (overflowCnt > 0) {
viewIdx++;
overflowCnt--;
updateButtons();
}
return;
}
if (action.equals("#trash")) {
try {
Runtime.getRuntime().exec(new String[] {"jfile", JF.getUserPath() + "/.local/share/Trash"});
} catch (Exception e) {}
return;
}
if (action.equals("#keyboard")) {
if (!keyboardShown)
showKeyboard();
else
hideKeyboard();
return;
}
if (action.equals("#power")) {
PowerPopup.show(config.compact ? powerQuad : powerHalf, 0, -calcMenuHeight(PowerPopup));
return;
}
if (action.startsWith("#vpn#")) {
connectVPN(action.substring(5));
return;
}
if (action.startsWith("#wap#")) {
int idx = Integer.valueOf(action.substring(5));
WAP wap = wapItems.get(idx);
connectWAP(wap.dev, wap.ssid, wap.encType);
return;
}
if (action.equals("#wap-disconnect")) {
jbusClient.call("org.jflinux.jnetworkmgr", "disconnectWAP" ,"");
return;
}
Object obj = ae.getSource();
if (obj instanceof JButton) {
//check if window is already active for this app and show it
JButton button = (JButton)obj;
Group group = (Group)button.getClientProperty("group");
String open = (String)button.getClientProperty("open"); //open'ing a new window?
if (!group.isEmpty() && open == null) {
group.getWindow(0).show();
return;
} else {
flashButton((JButton)obj);
}
}
File file = new File(action);
if (file.isDirectory()) {
//open with jfile
Runtime.getRuntime().exec(new String[] {"jfile", action});
return;
}
if (action.endsWith(".lnk")) {
//open with Wine (if installed)
Runtime.getRuntime().exec(new String[] {"wine", action});
return;
}
if (!action.endsWith(".desktop")) {
//regular file, open with jopen
Runtime.getRuntime().exec(new String[] {"jopen", action});
return;
}
//.desktop file, get Exec= line and execute it
Linux.executeDesktop(action, null);
} catch (Exception e) {
JFLog.log(e);
}
}
public void flashButton(JButton button) {
if (flashTimer != null) return;
flashTimer = new java.util.Timer();
flashTimer.schedule(new TimerTask() {
private JButton button;
private int cnt = 7, fullcnt = 6;
private int clr;
private int org = 0;
private boolean brighter = false;
public void run() {
if (org == 0) {
org = getBackground().getRGB();
clr = org;
button.setContentAreaFilled(true);
}
if (brighter) clr += 0x110011; else clr -= 0x110011;
cnt--;
if (cnt == 0) {
cnt = 7;
brighter = !brighter;
fullcnt--;
if (fullcnt == 0) {
flashTimer.cancel();
flashTimer = null;
clr = org;
button.setContentAreaFilled(false);
}
}
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
button.setBackground(new Color(clr));
button.repaint();
}
});
}
public TimerTask init(JButton button) {
this.button = button;
return this;
}
}.init(button), 100, 100);
}
private String vpnList = "";
private String wapList = "";
private void showSettingsPopup() {
ConfigPopup.show(config.compact ? settingsQuad : settingsHalf, 0, -calcMenuHeight(ConfigPopup));
}
private void getWAPList() {
jbusClient.call("org.jflinux.jnetworkmgr", "getWAPList", JBusClient.quote(jbusClient.pack));
}
private void getVPNList() {
jbusClient.call("org.jflinux.jnetworkmgr", "getVPNList", JBusClient.quote(jbusClient.pack));
}
private static class WAP {
public String dev, ssid, encType;
}
ArrayList<WAP> wapItems = new ArrayList<WAP>();
private void showNetworkPopup() {
NetworkPopup.removeAll();
if (checkWireless()) {
JMenu subWireless = new JMenu("Wireless");
NetworkPopup.add(subWireless);
//list wireless access points
String lns[] = wapList.split("[|]");
boolean wapActive = false;
int idx = 0;
String dev = null;
int cnt = 0;
int w = 0;
wapItems.clear();
while (idx < lns.length) {
if (cnt == 0) {
dev = lns[idx++];
cnt = JF.atoi(lns[idx++]);
}
if (cnt == 0) continue;
String ssid = lns[idx++];
String encType = lns[idx++];
WAP wap = new WAP();
if (ssid.endsWith(" *")) {
wapActive = true;
}
wap.dev = dev;
wap.ssid = ssid;
wap.encType = encType;
wapItems.add(wap);
JMenuItem w1 = new JMenuItem(ssid);
w1.setActionCommand("#wap#" + (w++));
w1.addActionListener(this);
addMouseListener(w1);
subWireless.add(w1);
cnt--;
}
if (wapActive) {
JMenuItem w1 = new JMenuItem("Disconnect...");
w1.setActionCommand("#wap-disconnect");
w1.addActionListener(this);
addMouseListener(w1);
subWireless.add(w1);
}
addMouseListener(subWireless);
}
if (checkBluetooth()) {
JMenu subBluetooth = new JMenu("Bluetooth");
NetworkPopup.add(subBluetooth);
for(int a=0;a<btDevices.size();a++) {
String desc = btDevices.get(a).desc;
JMenuItem b1 = new JMenuItem(desc);
b1.setActionCommand("#bt#" + desc);
b1.addActionListener(this);
addMouseListener(b1);
subBluetooth.add(b1);
}
JMenuItem b1 = new JMenuItem("Connect...");
b1.setActionCommand("#bt-connect");
b1.addActionListener(this);
addMouseListener(b1);
subBluetooth.add(b1);
addMouseListener(subBluetooth);
}
//list vpn
JMenu subVPN = new JMenu("VPN");
NetworkPopup.add(subVPN);
String vpns[] = vpnList.split("[|]");
for(int a=0;a<vpns.length;a++) {
if (vpns[a].length() == 0) continue;
String name = vpns[a];
JMenuItem vpn1 = new JMenuItem(name);
vpn1.setActionCommand("#vpn#" + vpns[a]);
vpn1.addActionListener(this);
addMouseListener(vpn1);
subVPN.add(vpn1);
}
JMenuItem vpn1 = new JMenuItem("Configure...");
vpn1.setActionCommand("#vpn-configure");
vpn1.addActionListener(this);
addMouseListener(vpn1);
subVPN.add(vpn1);
addMouseListener(NetworkPopup);
addMouseListener(subVPN);
NetworkPopup.show(config.compact ? networkQuad : networkHalf, 0, -calcMenuHeight(NetworkPopup));
}
private void emptyTrash() {
JFLog.log("empty trash");
File file = new File(System.getenv("HOME") + "/.local/share/Trash");
//glob files
ArrayList<String> cmd = new ArrayList<String>();
cmd.add("jrm");
File files[] = file.listFiles();
if (files == null) return;
for(int a=0;a<files.length;a++) {
cmd.add(files[a].getAbsolutePath());
}
try {
Runtime.getRuntime().exec(cmd.toArray(new String[0]));
} catch (Exception e) {
JFLog.log(e);
}
}
private static String months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec"};
private void setClock() {
Calendar now = Calendar.getInstance();
clockLine1 = String.format("%s %s", months[now.get(Calendar.MONTH)], now.get(Calendar.DAY_OF_MONTH));
int hour = now.get(Calendar.HOUR);
if (hour == 0) hour = 12;
clockLine2 = String.format("%d:%02d", hour, now.get(Calendar.MINUTE));
clockImage.repaint();
}
public void updateClock() {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
setClock();
}
});
}
public void setupClockTimer() {
if (clockTimer != null) clockTimer.cancel();
Calendar now = Calendar.getInstance();
clockTimer = new java.util.Timer();
clockTimer.scheduleAtFixedRate(new TimerTask() {public void run() {updateClock();}}
,60000 - now.get(Calendar.SECOND) * 1000, 60000);
}
private void calcDockHeight() {
int pos = dockSliderPos;
dockHeight = (panelHeight-borderSize) * pos / 100;
if (dockHeight == 0) dockHeight = 1;
}
private class DockSliderTask extends TimerTask {
public void run() {
try {
synchronized(sliderLock) {
if (dockSliderShow) {
if (dockSliderPos == 100) {
dockSliderTimer.cancel();
dockSliderTimer = null;
} else {
dockSliderPos += 25;
calcDockHeight();
setPosition();
}
} else {
if (dockSliderPos == 0) {
dockSliderTimer.cancel();
dockSliderTimer = null;
} else {
dockSliderPos -= 25;
calcDockHeight();
setPosition();
}
}
if (keyboardShown) {
keyboardWindow.setPosition(keyboardHeight, dockHeight);
}
}
} catch (Exception e) {
JFLog.log(e);
}
}
}
private void removeNewButton() {
buttons.remove(newButton);
newButton = null;
appIdx--;
buttonsCount--;
}
private java.util.Timer dockSliderTimer = null;
private final Object sliderLock = new Object();
private int dockSliderPos = 0; //percentage of dock visible
private int dockHeight = 0; //actual size
private boolean dockSliderShow = true;
private void hideDock() {
if (newButton != null) {
removeNewButton();
}
if (!config.autoHide) return;
if (isDockHidden) return;
isDockHidden = true;
if (newButton != null) {
removeNewButton();
}
if (soundWindow != null) {
hideSound();
}
if (calWindow != null) {
hideCalendar();
}
if (PowerPopup.isVisible()) PowerPopup.setVisible(false);
if (ConfigPopup.isVisible()) ConfigPopup.setVisible(false);
if (NetworkPopup.isVisible()) NetworkPopup.setVisible(false);
synchronized(sliderLock) {
getScreenSize();
dockSliderShow = false;
if (dockSliderTimer == null) {
dockSliderTimer = new java.util.Timer();
dockSliderTimer.schedule(new DockSliderTask(), 50, 50);
}
}
}
private void showDock() {
if (!isDockHidden) return;
isDockHidden = false;
synchronized(sliderLock) {
dockSliderShow = true;
if (dockSliderTimer == null) {
dockSliderTimer = new java.util.Timer();
dockSliderTimer.schedule(new DockSliderTask(), 50, 50);
}
}
if (!haveMouse) {
autoHideTimer = new java.util.Timer();
autoHideTimer.schedule(new TimerTask() {
public void run() {
if (!haveMouse && !isDockHidden && drag == null) hideDock();
}
}, 5*1000);
}
}
private class KeyboardSliderTask extends TimerTask {
public void run() {
synchronized(sliderLock) {
if (keyboardSliderShow) {
if (keyboardHeight == 200) {
keyboardSliderTimer.cancel();
keyboardSliderTimer = null;
} else {
keyboardHeight += 25;
keyboardWindow.setPosition(keyboardHeight, dockHeight);
}
} else {
if (keyboardHeight == 0) {
keyboardSliderTimer.cancel();
keyboardSliderTimer = null;
keyboardWindow.setVisible(false);
keyboardShown = false;
} else {
keyboardHeight -= 25;
keyboardWindow.setPosition(keyboardHeight, dockHeight);
}
}
}
}
}
private java.util.Timer keyboardSliderTimer = null;
private int keyboardHeight = 0; //actual size of keyboard height (1-200)
private boolean keyboardSliderShow = true;
private void showKeyboard() {
if (keyboardShown) return;
synchronized(sliderLock) {
keyboardWindow.setPosition(1, dockHeight);
keyboardWindow.setVisible(true);
keyboardShown = true;
keyboardSliderShow = true;
if (keyboardSliderTimer == null) {
keyboardSliderTimer = new java.util.Timer();
keyboardSliderTimer.schedule(new KeyboardSliderTask(), 50, 50);
}
}
}
public void hideKeyboard() {
if (!keyboardShown) return;
synchronized(sliderLock) {
keyboardSliderShow = false;
if (keyboardSliderTimer == null) {
keyboardSliderTimer = new java.util.Timer();
keyboardSliderTimer.schedule(new KeyboardSliderTask(), 50, 50);
}
}
}
private void showCalendar() {
if (soundWindow != null) hideSound();
calWindow = new CalendarWindow(clockImage.getLocationOnScreen(), clockImage.getWidth());
calWindow.setVisible(true);
calWindow.addMouseListener(this);
}
private void hideCalendar() {
calWindow.setVisible(false);
calWindow.dispose();
calWindow = null;
}
private void showSound() {
if (calWindow != null) hideCalendar();
Point pos;
int width;
if (config.compact) {
pos = soundQuad.getLocationOnScreen();
width = soundQuad.getWidth();
} else {
pos = soundHalf.getLocationOnScreen();
width = soundHalf.getWidth();
}
//sometimes pos.y is wrong so calc it instead
pos.y = sy - buttonHeight + 1;
soundWindow = new SoundWindow(pos, width);
soundWindow.setVisible(true);
soundWindow.addMouseListener(this);
soundWindow.reload(config);
}
private void hideSound() {
soundWindow.setVisible(false);
soundWindow.dispose();
soundWindow = null;
}
public void mouseClicked(MouseEvent me) {
if (me.getSource() == buttons) {
if (x11id == 0) return;
try {
x11_set_dock();
} catch (Throwable t) {
JFLog.log(t);
}
}
}
public void mousePressed(MouseEvent me) {
// JFLog.log("press:" + me);
draggable = me.getButton() == MouseEvent.BUTTON1;
if (me.getSource() == this && me.getButton() == MouseEvent.BUTTON3) {
TaskbarPopup.show(this, me.getX(), me.getY());
}
}
private volatile boolean showDockTimerActive = false;
public void mouseEntered(MouseEvent me) {
haveMouse = true;
if (autoHideTimer != null) {
autoHideTimer.cancel();
autoHideTimer = null;
}
if ((isDockHidden) && (!showDockTimerActive)) {
showDockTimerActive = true;
new java.util.Timer().schedule(new TimerTask() {
public void run() {
showDockTimerActive = false;
if (haveMouse && isDockHidden) showDock();
}
}, 250);
}
}
private volatile boolean hideDockTimerActive = false;
public void mouseExited(MouseEvent me) {
haveMouse = false;
if ((!isDockHidden) && (!hideDockTimerActive)) {
hideDockTimerActive = true;
new java.util.Timer().schedule(new TimerTask() {
public void run() {
hideDockTimerActive = false;
if (!haveMouse && !isDockHidden && drag == null) hideDock();
}
}, 250);
}
}
public void mouseReleased(MouseEvent me) {
// JFLog.log("release:" + me);
try {
draggable = false;
if (drag == null) return;
drag.setBackground(drag_org_color);
drag = null;
getContentPane().setCursor(Cursor.getDefaultCursor());
updateAppList();
} catch (Exception e) {
JFLog.log(e);
}
}
private JButton drag;
private int dragx, dragy;
private int drag_width;
private Color drag_org_color;
private int drag_component_idx;
public boolean dragged, draggable;
public void mouseDragged(MouseEvent me) {
if (!draggable) return;
dragged = true; //avoid click after dragging (not working)
try {
//move Button
if (drag == null) {
//start drag
JButton button = (JButton)me.getSource();
String file = (String)button.getClientProperty("file");
if ((file == null) || (file.startsWith("#"))) return;
drag = button;
dragx = me.getXOnScreen();
dragy = me.getYOnScreen();
drag_width = button.getWidth();
getContentPane().setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
drag_org_color = button.getBackground();
button.setBackground(Color.green);
drag_component_idx = -1;
int cnt = buttons.getComponentCount();
for(int a=0;a<cnt;a++) {
if (buttons.getComponent(a) == drag) {
drag_component_idx = a;
break;
}
}
} else {
//move drag
if (drag_component_idx == -1) return; //error
int newX = me.getXOnScreen();
if (needArrows) {
newX += halfWidth;
}
int newIdx = newX / buttonWidth;
if (newIdx < 1) newIdx = 1;
if (newIdx >= appIdx) newIdx = appIdx-1;
if (newIdx == drag_component_idx) return;
drag_component_idx = newIdx;
buttons.setComponentZOrder(drag, newIdx);
updateButtons();
}
} catch (Exception e) {
JFLog.log(e);
}
}
public void mouseMoved(MouseEvent me) {
}
private static void doRun() {
try {
RunDialog runDialog = new RunDialog(null, true);
runDialog.setVisible(true);
} catch (Exception e) {
JFLog.log(e);
}
}
private void addMouseListener(JComponent jc) {
jc.addMouseListener(this);
int cnt = jc.getComponentCount();
for(int a=0;a<cnt;a++) {
jc.getComponent(a).addMouseListener(this);
}
}
private void closeAllApps() {
saveConfig();
//close open VPN connections
jbusClient.call("org.jflinux", "closeAllVPN", "");
//close all apps belonging to this user
//BUG : killall may kill other sessions of same user???
try {
Runtime.getRuntime().exec(new String[] {"killall", "-u", System.getenv("USER")});
} catch (Exception e) {JFLog.log(e);}
}
public void showConfig() {
ConfigDialog dialog = new ConfigDialog(null, true, config);
dialog.setVisible(true);
if (dialog.accepted) {
dialog.updateConfig(config);
updateConfig();
saveConfig();
}
}
private void checkBattery() {
ShellProcess sp = new ShellProcess();
String output = sp.run(new String[] {"acpi"}, false);
if (output.indexOf("Battery") == -1) return;
batteryImage = IconCache.loadIcon("jfdesktop-battery");
try {
tray = SystemTray.getSystemTray();
trayIcon = new TrayIcon(batteryImage.getImage(), "Battery", BatteryPopup);
tray.add(trayIcon);
} catch (Exception e) {
JFLog.log(e);
return;
}
new java.util.Timer().schedule(new TimerTask() {public void run() {updateBattery();}}, 0, 60000);
}
private boolean checkBluetooth() {
ShellProcess sp = new ShellProcess();
String output = sp.run(new String[] {"hciconfig"}, false);
if (output.indexOf("hci") == -1) return false;
return true;
}
private boolean checkWireless() {
ShellProcess sp = new ShellProcess();
String output = sp.run(new String[] {"iwconfig"}, false);
if (output.indexOf("ESSID") == -1) return false;
return true;
}
private JFImage plugImage;
private void updateBattery() {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
ShellProcess sp = new ShellProcess();
String output = sp.run(new String[] {"acpi"}, false);
String lns[] = output.split("\n");
String f[] = lns[0].split(","); //only show battery #1
//Battery 1: discharging, 44%, 00:18:48 remaining
int percent = JF.atoi(f[1].trim().replaceAll("%", ""));
Graphics g = batteryImage.getGraphics();
g.setColor(Color.white);
g.fillRect(4,2,15,20);
int h = percent * 20 / 100;
int y = 2 + (20-h);
if (percent < 15) {
g.setColor(Color.yellow);
} else if (percent < 5) {
g.setColor(Color.red);
} else {
g.setColor(Color.green);
}
g.fillRect(4,y,15,h);
if (lns[0].indexOf("Discharging") == -1) {
if (plugImage == null) {
plugImage = IconCache.loadIcon("jfdesktop-plug");
}
g.drawImage(plugImage.getImage(), 0, 0, null);
}
trayIcon.setImage(batteryImage.getImage());
}
});
}
//LayoutManager
public void addLayoutComponent(String string, Component cmpnt) {
}
public void removeLayoutComponent(Component cmpnt) {
}
public Dimension preferredLayoutSize(Container p) {
if (isDockHidden) {
return new Dimension(sx, panelHiddenHeight);
}
return new Dimension(sx, panelHeight + borderSize*2);
}
public Dimension minimumLayoutSize(Container p) {
if (isDockHidden) {
return new Dimension(sx, panelHiddenHeight);
}
return new Dimension(sx, panelHeight + borderSize*2);
}
public void layoutContainer(Container p) {
try {
if (p == getContentPane()) {
synchronized(p.getParent().getTreeLock()) {
buttons.setBounds(0,0,sx,panelHeight);
}
return;
}
synchronized(p.getParent().getTreeLock()) {
Dimension d;
//do we need arrows?
int tWidth = 0, bWidth = 0; //tools width, buttons width
bWidth += appIdx * buttonWidth;
if (config.showClock) {
d = clockImage.getPreferredSize();
tWidth += d.width;
}
if (config.showKeyboard) {
d = keyboard.getPreferredSize();
tWidth += d.width;
}
if (config.compact) {
//quad controls
tWidth += buttonWidth;
} else {
//half controls
tWidth += halfWidth * 4;
}
tWidth += buttonWidth; //trash
int trayWidth = Linux.x11_tray_width();
// JFLog.log("dock widths:" + bWidth + "," + trayWidth + "," + tWidth);
int cnt = 0;
if (bWidth + trayWidth + tWidth > sx) {
//need arrow buttons
if (!needArrows) {
needArrows = true;
buttons.add(left,getLastIdx());
buttons.add(right,getLastIdx());
}
int arrowsWidth = halfWidth * 2; //left + right arrows
int appsWidth = buttonWidth;
cnt = (sx - appsWidth - tWidth - arrowsWidth - trayWidth) / buttonWidth;
bWidth = cnt * buttonWidth;
overflowCnt = buttonsCount - cnt - viewIdx;
} else {
//no arrows - show all buttons
if (needArrows) {
needArrows = false;
buttons.remove(left);
buttons.remove(right);
}
cnt = buttonsCount;
viewIdx = 0;
overflowCnt = 0;
}
int cx = 0;
apps.setBounds(cx, borderSize, buttonWidth, buttonHeight);
cx += buttonWidth;
if (needArrows) {
left.setBounds(cx, borderSize, halfWidth, buttonHeight);
cx += halfWidth;
for(int a=1;a<=viewIdx;a++) {
p.getComponent(a).setVisible(false);
}
}
int idx = 1 + viewIdx;
while (cnt > 0) {
Component c = p.getComponent(idx++);
c.setVisible(true);
c.setBounds(cx, borderSize, buttonWidth, buttonHeight);
cx += buttonWidth;
cnt--;
}
while (idx < appIdx) {
p.getComponent(idx++).setVisible(false);
}
if (needArrows) {
right.setBounds(cx, borderSize, halfWidth, buttonHeight);
cx += halfWidth;
}
cx = sx - tWidth;
trayPos = cx;
Linux.x11_tray_reposition(sx, trayPos, buttonHeight + trayPad);
if (config.compact) {
quad.setBounds(cx, borderSize, buttonWidth, buttonHeight);
cx += buttonWidth;
} else {
powerHalf.setBounds(cx, borderSize, halfWidth, buttonHeight);
cx += halfWidth;
settingsHalf.setBounds(cx, borderSize, halfWidth, buttonHeight);
cx += halfWidth;
networkHalf.setBounds(cx, borderSize, halfWidth, buttonHeight);
cx += halfWidth;
soundHalf.setBounds(cx, borderSize, halfWidth, buttonHeight);
cx += halfWidth;
}
if (config.showKeyboard) {
keyboard.setBounds(cx, borderSize, halfWidth, buttonHeight);
cx += halfWidth;
}
trash.setBounds(cx, borderSize, buttonWidth, buttonHeight);
cx += buttonWidth;
if (config.showClock) {
d = clockImage.getPreferredSize();
clockImage.setBounds(cx, borderSize, d.width, buttonHeight);
}
}
} catch (Exception e) {
JFLog.log(e);
}
}
private void disconnectVPN(String name) {
jbusClient.call("org.jflinux.jnetworkmgr", "disconnectVPN", JBusClient.quote(name));
}
private void connectVPN(String name) {
if (name.endsWith(" *")) {
disconnectVPN(name.substring(0, name.length() - 2));
} else {
startNetworkTimer("cancelVPN");
jbusClient.call("org.jflinux.jnetworkmgr", "connectVPN", JBusClient.quote(jbusClient.pack) + "," + JBusClient.quote(name));
}
}
private void disconnectWAP(String ssid) {
jbusClient.call("org.jflinux.jnetworkmgr", "disconnectWAP" , JBusClient.quote(ssid));
}
private void connectWAP(String dev, String ssid, String encType) {
if (ssid.endsWith(" *")) {
disconnectWAP(ssid.substring(0, ssid.length() - 2));
} else {
String key = "";
if (encType.equals("WEP")) {
key = JF.getString("Enter WEP encryption key (26 or 10 hex digits)", "");
} else if (encType.equals("WPA")) {
key = JF.getString("Enter WPA pass phrase", "");
}
startNetworkTimer("cancelWAP");
jbusClient.call("org.jflinux.jnetworkmgr", "connectWAP",
JBusClient.quote(jbusClient.pack) + "," + JBusClient.quote(dev) + "," + JBusClient.quote(ssid) + "," + JBusClient.quote(encType) + "," + JBusClient.quote(key));
}
}
private void blueToothDisconnect(String dev) {
for(int a=0;a<btDevices.size();a++) {
if (btDevices.get(a).desc.equals(dev)) {
ShellProcess sp = new ShellProcess();
String output = sp.run(new String[] {"hcitool", "dc", btDevices.get(a).mac}, false);
// if (output.startsWith("Not connected")) {}
btDevices.remove(a);
}
}
}
private java.util.Timer networkTimer;
private int networkIconIdx;
private JFImage networkIconsQuad[];
private JFImage networkIconsHalf[];
private Icon networkOrgIcon;
private final Object networkLock = new Object();
private int networkTimerCount;
private String cancelNetworkMethod;
private void loadNetworkIcons() {
halfSized = true;
networkIconsQuad = new JFImage[3];
networkIconsHalf = new JFImage[3];
for(int a=0;a<3;a++) {
JFImage img = IconCache.loadIcon("jfdesktop-network-" + (a+1));
networkIconsQuad[a] = IconCache.scaleIcon(img, 21, 21);
JFImage tmpImage = new JFImage(bx, by);
tmpImage.fill(0, 0, bx, by, 0, true);
tmpImage.getGraphics().drawImage(IconCache.scaleIcon(img, 24, 24).getImage(), 0,(by-bx)/2 + 4, null);
tmpImage.getGraphics().drawImage(arrowImage.getImage(), 0,0, null);
networkIconsHalf[a] = tmpImage;
}
halfSized = false;
}
private void startNetworkTimer(String cancelMethod) {
if (networkTimer != null) return;
cancelNetworkMethod = cancelMethod;
networkIconIdx = 0;
networkTimerCount = 0;
networkTimer = new java.util.Timer();
networkTimer.schedule(new TimerTask() {
public void run() {
synchronized(networkLock) {
if (networkTimer == null) return;
networkTimerCount++;
if (networkTimerCount == 60) {
//after 30 seconds
JFLog.log("30 seconds timeout network connection");
networkTimer.cancel();
networkTimer = null;
resetNetworkIcon();
cancelNetworkConnection();
return;
}
try {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
if (config.compact) {
if (networkOrgIcon == null) networkOrgIcon = networkQuad.getIcon();
networkIconIdx++;
if (networkIconIdx == networkIconsQuad.length) networkIconIdx = 0;
networkQuad.setIcon(networkIconsQuad[networkIconIdx]);
} else {
if (networkOrgIcon == null) networkOrgIcon = networkHalf.getIcon();
networkIconIdx++;
if (networkIconIdx == networkIconsHalf.length) networkIconIdx = 0;
networkHalf.setIcon(networkIconsHalf[networkIconIdx]);
}
}
});
} catch (Exception e) {}
}
}
}, 0, 500);
}
private void stopNetworkTimer() {
synchronized(networkLock) {
cancelNetworkMethod = null;
networkTimer.cancel();
networkTimer = null;
}
resetNetworkIcon();
}
private void resetNetworkIcon() {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
if (config.compact) {
networkQuad.setIcon(networkOrgIcon);
} else {
networkHalf.setIcon(networkOrgIcon);
}
networkOrgIcon = null;
}
});
}
private void cancelNetworkConnection() {
if (cancelNetworkMethod == null) return;
stopNetworkTimer();
jbusClient.call("org.jflinux.jnetworkmgr", cancelNetworkMethod, "");
cancelNetworkMethod = null;
showNetworkFailed();
}
private void showNetworkFailed() {
JF.showError("Error", "Connection failed!");
}
private void showWelcome() {
try {
Runtime.getRuntime().exec("jwelcome");
} catch (Exception e) {
JFLog.log(e);
}
}
private void mkdirs() {
new File(JF.getUserPath() + "/Desktop").mkdir();
new File(JF.getUserPath() + "/Documents").mkdir();
new File(JF.getUserPath() + "/Music").mkdir();
new File(JF.getUserPath() + "/Pictures").mkdir();
new File(JF.getUserPath() + "/Videos").mkdir();
new File(JF.getUserPath() + "/Downloads").mkdir();
}
public void soundinit() {
new Thread() {
public void run() {
SoundWindow.init(config);
saveConfig();
}
}.start();
}
public void initUpgrades() {
try {
File file = new File("/etc/upgrades.cnts");
if (!file.exists()) return;
FileInputStream fis = new FileInputStream(file);
String str = new String(JF.readAll(fis));
fis.close();
if (str.length() == 0) return;
int idx = str.indexOf(" ");
if (idx == -1) return;
int cnts = JF.atoi(str.substring(0, idx));
setUpgradesAvailable(cnts);
} catch (Exception e) {
JFLog.log(e);
}
}
public void setUpgradesAvailable(int cnt) {
for(int a=0;a<ConfigPopup.getComponentCount();a++) {
JMenuItem mi = (JMenuItem)ConfigPopup.getComponent(a);
if (mi.getText().startsWith("Upgrades")) {
mi.setText("Upgrades (" + cnt + ")");
break;
}
}
}
public void x11_set_dock() {
try {
Linux.x11_set_dock(x11id);
} catch (Throwable t) {
JFLog.log(t);
}
}
public int getPanelHeight() {
return panelHeight;
}
private void initTrashDND() {
trash.setTransferHandler(new TransferHandler() {
public boolean canImport(TransferHandler.TransferSupport info) {
// we only import Files
if (!info.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
return false;
}
// TransferHandler.DropLocation dl = (TransferHandler.DropLocation) info.getDropLocation();
// Point pt = dl.getDropPoint();
return true;
}
public boolean importData(TransferHandler.TransferSupport info) {
if (!info.isDrop()) {
return false;
}
// Check for file flavor
if (!info.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
return false;
}
// TransferHandler.DropLocation dl = info.getDropLocation();
// Point pt = dl.getDropPoint();
String folder = JF.getUserPath() + "/.local/share/Trash";
// Get the file(s) that are being dropped.
Transferable t = info.getTransferable();
java.util.List<File> data;
try {
data = (java.util.List<File>) t.getTransferData(DataFlavor.javaFileListFlavor);
} catch (Exception e) {
return false;
}
// Perform the actual import.
ArrayList<String> cmd = new ArrayList<String>();
boolean move = false;
boolean copy = false;
for(int a=0;a<data.size();a++) {
switch (info.getDropAction()) {
case COPY:
case MOVE:
if (copy) return false; //Can that happen?
move = true;
cmd.add(((File)data.get(a)).getAbsolutePath());
break;
case LINK:
return false; //BUG : not supported : ???
}
}
if (cmd.isEmpty()) return false;
cmd.add(0, "-v");
cmd.add(0, "-n");
if (copy) {
cmd.add(0, "cp");
} else if (move) {
cmd.add(0, "mv");
} else {
return false;
}
cmd.add(folder);
JFileBrowser.runCmd(null, cmd.toArray(new String[0]));
return true;
}
public int getSourceActions(JComponent c) {
return COPY_OR_MOVE;
}
protected Transferable createTransferable(JComponent c) {
//can not transfer out of trash from this icon
return null;
}
protected void exportDone(JComponent source, Transferable data, int action) {
}
});
}
private int getDragIdx(Point pt) {
int x = pt.x;
if (needArrows) {
x += halfWidth;
}
x /= buttonWidth;
if (x < 1) return 1;
if (x >= appIdx) return appIdx-1;
return x;
}
private void initDockDND() {
this.setTransferHandler(new TransferHandler() {
public boolean canImport(TransferHandler.TransferSupport info) {
// we only import Files
if (!info.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
return false;
}
TransferHandler.DropLocation dl = (TransferHandler.DropLocation) info.getDropLocation();
Point pt = dl.getDropPoint();
if (newButton == null) {
newButtonIdx = getDragIdx(pt);
newButton = addButton("jfdesktop-new", "New", "#new", newButtonIdx, false);
appIdx++;
buttonsCount++;
} else {
int newIdx = getDragIdx(pt);
if (newIdx == newButtonIdx) return true; //no change
newButtonIdx = newIdx;
buttons.setComponentZOrder(newButton, newButtonIdx);
}
mouseEntered(null); //prevent dock for hiding
updateButtons();
return true;
}
public boolean importData(TransferHandler.TransferSupport info) {
if (!info.isDrop()) {
return false;
}
// Check for file flavor
if (!info.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
return false;
}
TransferHandler.DropLocation dl = info.getDropLocation();
Point pt = dl.getDropPoint();
int idx = getDragIdx(pt);
// Get the file(s) that are being dropped.
Transferable t = info.getTransferable();
java.util.List<File> data;
try {
data = (java.util.List<File>) t.getTransferData(DataFlavor.javaFileListFlavor);
} catch (Exception e) {
return false;
}
if (newButton != null) {
removeNewButton();
}
// Perform the actual import.
String file;
for(int a=0;a<data.size();a++) {
switch (info.getDropAction()) {
case COPY:
case MOVE:
file = ((File)data.get(a)).getAbsolutePath();
if (!file.endsWith(".desktop")) continue;
if (!haveApp(file)) {
addButton(file, true, idx);
addApp(file);
}
break;
case LINK:
//BUG : not supported : ???
continue;
}
}
saveConfig();
updateButtons();
return true;
}
public int getSourceActions(JComponent c) {
return COPY_OR_MOVE;
}
protected Transferable createTransferable(JComponent c) {
//can not transfer out of trash from this icon
return null;
}
protected void exportDone(JComponent source, Transferable data, int action) {
}
});
}
private void loadMappings() {
Mappings.loadMaps();
Mappings.Maps maps = Mappings.getMaps();
if (maps == null || maps.map == null) return;
JBusMethods methods = new JBusMethods();
for(int a=0;a<maps.map.length;a++) {
methods.mount(null, maps.map[a].uri, maps.map[a].mount, maps.map[a].passwd, maps.map[a].wineDrive);
}
}
private void openButton(JButton button) {
button.putClientProperty("open", "true"); //ensure a NEW window is opened (not just select already active window)
button.doClick();
button.putClientProperty("open", null);
}
private void createAppPopupMenu(JButton button) {
JPopupMenu popup = new JPopupMenu();
JMenuItem item;
Boolean pinned = (Boolean)button.getClientProperty("pinned");
Group group = (Group)button.getClientProperty("group");
item = new JMenuItem(group.isEmpty() ? "Open" : "Open new window");
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JMenuItem mi = (JMenuItem)e.getSource();
JPopupMenu pm = (JPopupMenu)mi.getParent();
openButton((JButton)pm.getInvoker());
}
});
popup.add(item);
for(int a=0;a<group.size();a++) {
final Window window = group.getWindow(a);
item = new JMenuItem(window.title);
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
window.show();
}
});
popup.add(item);
}
item = new JMenuItem("Copy to Desktop");
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JMenuItem mi = (JMenuItem)e.getSource();
JPopupMenu pm = (JPopupMenu)mi.getParent();
copyButtonToDesktop((JButton)pm.getInvoker());
}
});
popup.add(item);
item = new JMenuItem(pinned ? "Unpin" : "Pin");
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JMenuItem mi = (JMenuItem)e.getSource();
JPopupMenu pm = (JPopupMenu)mi.getParent();
togglePinned((JButton)pm.getInvoker());
}
});
popup.add(item);
addMouseListener(popup);
button.setComponentPopupMenu(popup);
}
private void updateAppList() {
ArrayList<App> list = new ArrayList<App>();
Component buts[] = buttons.getComponents();
for(int a=0;a<buts.length;a++) {
if (!(buts[a] instanceof JButton)) continue;
JButton button = (JButton)buts[a];
String file = (String)button.getClientProperty("file");
if (file.startsWith("#")) continue;
Boolean pinned = (Boolean)button.getClientProperty("pinned");
if (!pinned) continue;
App app = new App();
app.file = (String)button.getClientProperty("file");
list.add(app);
}
config.dock = list.toArray(new App[0]);
saveConfig();
}
private void updateButtons() {
buttons.revalidate();
buttons.repaint();
}
public class JBusMethods {
public void run() {
doRun();
}
public void show() {
showDock();
}
public void getWelcome(String pack) {
jbusClient.call(pack, "setWelcome", JBusClient.quote("" + config.welcome));
}
public void setWelcome(String state) {
config.welcome = state.equals("true");
saveConfig();
}
public void upgradesAvailable(int upgrades) {
setUpgradesAvailable(upgrades);
}
public void volume(String lvl) {
if ((lvl == null) || (lvl.length() == 0)) return;
if (isDockHidden) showDock();
if (soundWindow == null) showSound();
if (lvl.equals("mute")) {
soundWindow.mute();
} else if (lvl.charAt(0) == '+') {
soundWindow.adjustVolume(JF.atoi(lvl.substring(1)));
} else if (lvl.charAt(0) == '-') {
soundWindow.adjustVolume(-JF.atoi(lvl.substring(1)));
}
}
public void vpnFailed(String id) {
stopNetworkTimer();
showNetworkFailed();
}
public void vpnSuccess(String id) {
stopNetworkTimer();
}
public void wapFailed() {
stopNetworkTimer();
showNetworkFailed();
}
public void wapSuccess() {
stopNetworkTimer();
}
public void btFailed() {
if (btDialog == null) return;
btDialog.failed();
}
public void btSuccess() {
if (btDialog == null) return;
btDialog.success();
}
public void setBTdevices(String list) {
if (btDialog == null) return;
btDialog.devices(list);
}
public void soundSinkVolumeChanged(int idx, int volume) {
if (idx == PulseAudio.sinks.get(0).idx) SoundWindow.setVolume(volume);
for(int a=0;a<config.sink.length;a++) {
if (config.sink[a].idx == idx) {
config.sink[a].volume = volume;
saveConfig();
return;
}
}
}
public void soundSourceVolumeChanged(int idx, int volume) {
for(int a=0;a<config.source.length;a++) {
if (config.source[a].idx == idx) {
config.source[a].volume = volume;
saveConfig();
return;
}
}
}
public void soundSinkPortChanged(int idx, String port) {
for(int a=0;a<config.sink.length;a++) {
if (config.sink[a].idx == idx) {
config.sink[a].activePort = port;
saveConfig();
return;
}
}
}
public void soundSourcePortChanged(int idx, String port) {
for(int a=0;a<config.source.length;a++) {
if (config.source[a].idx == idx) {
config.source[a].activePort = port;
saveConfig();
return;
}
}
}
public void soundProfileChanged(int idx, String profile) {
for(int a=0;a<config.card.length;a++) {
if (config.card[a].idx == idx) {
config.card[a].activeProfile = profile;
saveConfig();
return;
}
}
}
public void timeAdjusted() {
setupClockTimer();
}
public void videoChanged(String reason) {
//TODO : popup window asking to load jconfig:display
if (reason.equals("jconfig")) {
updateConfig();
} else {
//else udev event : need to call x11_rr_auto first
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
Linux.x11_rr_auto();
updateConfig();
}
});
}
}
public void powerChanged() {
updateBattery();
}
public void mount(String callback, String uri, String mount, String pass, String link) {
JFLog.log("mount:" + uri + "," + mount);
final String _callback = callback;
final String _uri = uri;
new Thread() {
public void run() {
try {
Process p = Runtime.getRuntime().exec(new String[] {"gnome-disk-image-mounter", _uri});
p.waitFor();
int result = p.exitValue();
if (_callback != null) jbusClient.call(_callback, result == 0 ? "mountSuccess" : "mountFail", JBusClient.quote(_uri));
} catch (Exception e) {
JFLog.log(e);
}
}
}.start();
}
public void setWAPList(String list) {
wapList = list;
}
public void setVPNList(String list) {
vpnList = list;
showNetworkPopup();
}
//jfile : file ops (should use clipboard)
public void setFileSelection(String selection) {
JFLog.log("setSelection:" + selection);
fileSelection = selection;
}
public void getFileSelection(String pack) {
if (fileSelection == null) return;
JFLog.log("getSelection:" + pack);
jbusClient.call(pack, "getFileSelection", JBusClient.quote(fileSelection));
}
public void clearFileSelection() {
JFLog.log("clearSelection");
fileSelection = null;
}
}
public void get() {
if (fileSelection == null) return;
Desktop.desktop.browser.paste(JBusClient.decodeString(fileSelection));
}
public void set(String fileset) {
fileSelection = fileset;
}
public void clear() {
fileSelection = "";
}
}