resolve symlinks before opening file
[instantlauncher.git] / src / main / java / eu / svjatoslav / instantlauncher / menu / MultiLevelMenu.java
1 package eu.svjatoslav.instantlauncher.menu;
2
3 import java.awt.BorderLayout;
4 import java.awt.Color;
5 import java.awt.Dimension;
6 import java.io.File;
7 import java.io.IOException;
8 import java.util.ArrayList;
9
10 import javax.swing.Box;
11 import javax.swing.BoxLayout;
12 import javax.swing.JPanel;
13
14 import eu.svjatoslav.commons.gui.dialog.ExceptionDialog;
15 import eu.svjatoslav.instantlauncher.FileAssociationManager;
16 import eu.svjatoslav.instantlauncher.InstantLauncher;
17 import eu.svjatoslav.instantlauncher.Utils;
18
19 public class MultiLevelMenu implements MenuListener {
20
21         private final InstantLauncher instantLauncher;
22
23         private static final int VERTICAL_MENUS_COUNT = 7;
24
25         public static final Dimension CONTENT_PANEL_SIZE = new Dimension(1024, 900);
26
27         ArrayList<Menu> menus = new ArrayList<Menu>();
28
29         ArrayList<JPanel> panels = new ArrayList<JPanel>();
30         JPanel contentPane;
31
32         public MultiLevelMenu(final InstantLauncher instantLauncher) {
33                 this.instantLauncher = instantLauncher;
34         }
35
36         /**
37          * Adds new vertical menu.
38          * 
39          * @return <code>true</code> if operation succeeded, or <code>false</code>
40          *         if there was not enough space left for a new menu.
41          */
42         public boolean addMenu(final File directory) {
43                 final int newMenuHorizontalIndex = menus.size();
44
45                 if (newMenuHorizontalIndex >= VERTICAL_MENUS_COUNT) {
46                         return false;
47                 }
48
49                 final Menu menu = new Menu(directory);
50                 menu.addMenuListener(this);
51
52                 final JPanel placeholderPanel = panels.get(newMenuHorizontalIndex);
53                 final JPanel menuPanel = menu.getMenuPanel();
54                 placeholderPanel.add(menuPanel, BorderLayout.CENTER);
55
56                 menus.add(menu);
57                 return true;
58         }
59
60         public JPanel buildContentPanel() {
61
62                 contentPane = new JPanel();
63                 contentPane.setBackground(Color.BLACK);
64                 contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.X_AXIS));
65                 Utils.setComponentSize(contentPane, CONTENT_PANEL_SIZE);
66
67                 // initialize panels
68                 for (int i = 0; i < VERTICAL_MENUS_COUNT; i++) {
69                         contentPane.add(Box.createHorizontalStrut(10));
70
71                         final JPanel panel = new JPanel(new BorderLayout());
72                         panel.setBackground(Color.BLACK);
73
74                         Utils.setComponentSize(panel, Menu.SIZE_MENU_PANEL);
75
76                         panels.add(panel);
77                         contentPane.add(panel);
78                 }
79
80                 final File directory = instantLauncher.configuration.getRootDirectory();
81                 addMenu(directory);
82
83                 return contentPane;
84         }
85
86         public int getMenuIndex(final Menu menu) {
87                 int i = 0;
88                 for (final Menu m : menus) {
89                         if (m == menu) {
90                                 return i;
91                         }
92                         i++;
93                 }
94                 return -1;
95         }
96
97         @Override
98         public void menuItemHighlighted(final Menu menu, final File chosenFile) {
99
100                 if (chosenFile.isDirectory()) {
101                         final int menuIndex = getMenuIndex(menu);
102
103                         if (menuIndex >= 0) {
104                                 removeMenus(menuIndex + 1);
105                                 if (addMenu(chosenFile)) {
106                                         contentPane.validate();
107                                         contentPane.repaint();
108                                 }
109                         }
110                 }
111
112         }
113
114         @Override
115         public void menuItemSelected(final Menu menu, final File chosenFile) {
116                 if (chosenFile.isFile()) {
117                         if (chosenFile.canExecute()) {
118                                 executeCommand(chosenFile.getAbsolutePath());
119                         } else {
120                                 boolean fileOpened;
121                                 try {
122                                         fileOpened = FileAssociationManager.openFile(chosenFile.getCanonicalFile());
123                                         if (fileOpened) {
124                                                 InstantLauncher.exitProgram();
125                                         }
126                                 } catch (IOException e) {
127                                         e.printStackTrace();
128                                 }
129                         }
130                 }
131
132                 if (chosenFile.isDirectory()) {
133                         try {
134                                 executeCommand("nautilus", "-w", chosenFile.getCanonicalFile().getAbsolutePath());
135                         } catch (IOException e) {
136                                 e.printStackTrace();
137                         }
138                 }
139         }
140
141         private void executeCommand(String... c) {
142                 try {
143                         Runtime.getRuntime().exec(c);
144                         InstantLauncher.exitProgram();
145
146                 } catch (final IOException e) {
147                         new ExceptionDialog(e);
148                 }
149         }
150
151         @Override
152         public void menuItemSelectedAlternative(final Menu menu, final File chosenFile) {
153                 if (chosenFile.isFile()) {
154                         chosenFile.setExecutable(!chosenFile.canExecute());
155                 } else {
156                         try {
157                                 executeCommand("gnome-terminal", "--working-directory="
158                                                 + chosenFile.getCanonicalFile().getAbsolutePath());
159                         } catch (IOException e) {
160                                 e.printStackTrace();
161                         }
162                 }
163         }
164
165         public void removeMenus(final int fromIndex) {
166
167                 for (int i = fromIndex; i < menus.size(); i++) {
168                         final JPanel jPanel = panels.get(i);
169                         jPanel.removeAll();
170                 }
171
172                 while (menus.size() > fromIndex) {
173                         menus.remove(fromIndex);
174                 }
175         }
176
177         @Override
178         public void menuItemSelectedAlternative2(Menu menu, File chosenFile) {
179                 if (chosenFile.isFile()) {
180                         try {
181                                 executeCommand("emacs", chosenFile.getCanonicalFile().getAbsolutePath());
182                         } catch (IOException e) {
183                                 e.printStackTrace();
184                         }
185                 }
186         }
187
188 }