| 1 | package net.oni2.aeinstaller.gui; | 
|---|
| 2 |  | 
|---|
| 3 | import java.awt.Desktop; | 
|---|
| 4 | import java.awt.event.ActionEvent; | 
|---|
| 5 | import java.awt.event.ActionListener; | 
|---|
| 6 | import java.awt.event.MouseAdapter; | 
|---|
| 7 | import java.awt.event.MouseEvent; | 
|---|
| 8 | import java.io.File; | 
|---|
| 9 | import java.io.IOException; | 
|---|
| 10 | import java.net.URL; | 
|---|
| 11 | import java.util.ArrayList; | 
|---|
| 12 | import java.util.HashMap; | 
|---|
| 13 | import java.util.HashSet; | 
|---|
| 14 | import java.util.List; | 
|---|
| 15 | import java.util.ResourceBundle; | 
|---|
| 16 | import java.util.TreeMap; | 
|---|
| 17 | import java.util.TreeSet; | 
|---|
| 18 | import java.util.Vector; | 
|---|
| 19 |  | 
|---|
| 20 | import javax.swing.AbstractAction; | 
|---|
| 21 | import javax.swing.Icon; | 
|---|
| 22 | import javax.swing.ImageIcon; | 
|---|
| 23 | import javax.swing.JButton; | 
|---|
| 24 | import javax.swing.JComboBox; | 
|---|
| 25 | import javax.swing.JComponent; | 
|---|
| 26 | import javax.swing.JFileChooser; | 
|---|
| 27 | import javax.swing.JFrame; | 
|---|
| 28 | import javax.swing.JLabel; | 
|---|
| 29 | import javax.swing.JMenu; | 
|---|
| 30 | import javax.swing.JMenuItem; | 
|---|
| 31 | import javax.swing.JOptionPane; | 
|---|
| 32 | import javax.swing.JPopupMenu; | 
|---|
| 33 | import javax.swing.JSplitPane; | 
|---|
| 34 | import javax.swing.JTable; | 
|---|
| 35 | import javax.swing.ListSelectionModel; | 
|---|
| 36 | import javax.swing.RowSorter; | 
|---|
| 37 | import javax.swing.SortOrder; | 
|---|
| 38 | import javax.swing.SwingUtilities; | 
|---|
| 39 | import javax.swing.event.ListSelectionEvent; | 
|---|
| 40 | import javax.swing.event.ListSelectionListener; | 
|---|
| 41 | import javax.swing.filechooser.FileFilter; | 
|---|
| 42 | import javax.swing.table.TableRowSorter; | 
|---|
| 43 |  | 
|---|
| 44 | import net.oni2.aeinstaller.AEInstaller2; | 
|---|
| 45 | import net.oni2.aeinstaller.backend.AppExecution; | 
|---|
| 46 | import net.oni2.aeinstaller.backend.Paths; | 
|---|
| 47 | import net.oni2.aeinstaller.backend.Settings; | 
|---|
| 48 | import net.oni2.aeinstaller.backend.Settings.Platform; | 
|---|
| 49 | import net.oni2.aeinstaller.backend.SizeFormatter; | 
|---|
| 50 | import net.oni2.aeinstaller.backend.depot.DepotCacheUpdateProgressListener; | 
|---|
| 51 | import net.oni2.aeinstaller.backend.depot.DepotManager; | 
|---|
| 52 | import net.oni2.aeinstaller.backend.mods.Mod; | 
|---|
| 53 | import net.oni2.aeinstaller.backend.mods.ModManager; | 
|---|
| 54 | import net.oni2.aeinstaller.backend.mods.Type; | 
|---|
| 55 | import net.oni2.aeinstaller.backend.mods.download.ModDownloader; | 
|---|
| 56 | import net.oni2.aeinstaller.backend.mods.download.ModDownloader.State; | 
|---|
| 57 | import net.oni2.aeinstaller.backend.mods.download.ModDownloaderListener; | 
|---|
| 58 | import net.oni2.aeinstaller.backend.oni.InstallProgressListener; | 
|---|
| 59 | import net.oni2.aeinstaller.backend.oni.Installer; | 
|---|
| 60 | import net.oni2.aeinstaller.backend.oni.OniSplit; | 
|---|
| 61 | import net.oni2.aeinstaller.gui.about.AboutDialog; | 
|---|
| 62 | import net.oni2.aeinstaller.gui.downloadwindow.Downloader; | 
|---|
| 63 | import net.oni2.aeinstaller.gui.modtable.DownloadSizeListener; | 
|---|
| 64 | import net.oni2.aeinstaller.gui.modtable.ModTableFilter; | 
|---|
| 65 | import net.oni2.aeinstaller.gui.modtable.ModTableModel; | 
|---|
| 66 | import net.oni2.aeinstaller.gui.settings.SettingsDialog; | 
|---|
| 67 |  | 
|---|
| 68 | import org.javabuilders.BuildResult; | 
|---|
| 69 | import org.javabuilders.annotations.DoInBackground; | 
|---|
| 70 | import org.javabuilders.event.BackgroundEvent; | 
|---|
| 71 | import org.javabuilders.swing.SwingJavaBuilder; | 
|---|
| 72 | import org.simplericity.macify.eawt.ApplicationEvent; | 
|---|
| 73 | import org.simplericity.macify.eawt.ApplicationListener; | 
|---|
| 74 |  | 
|---|
| 75 | /** | 
|---|
| 76 | * @author Christian Illy | 
|---|
| 77 | */ | 
|---|
| 78 | public class MainWin extends JFrame implements ApplicationListener, | 
|---|
| 79 | DownloadSizeListener { | 
|---|
| 80 | private static final long serialVersionUID = -4027395051382659650L; | 
|---|
| 81 |  | 
|---|
| 82 | private ResourceBundle bundle = ResourceBundle.getBundle(getClass() | 
|---|
| 83 | .getName()); | 
|---|
| 84 | @SuppressWarnings("unused") | 
|---|
| 85 | private BuildResult result = SwingJavaBuilder.build(this, bundle); | 
|---|
| 86 |  | 
|---|
| 87 | private JMenu mainMenu; | 
|---|
| 88 | private JMenu toolsMenu; | 
|---|
| 89 | private TreeSet<JMenuItem> toolsMenuItems = new TreeSet<JMenuItem>(); | 
|---|
| 90 |  | 
|---|
| 91 | private JSplitPane contents; | 
|---|
| 92 |  | 
|---|
| 93 | private JComboBox cmbModTypes; | 
|---|
| 94 | private JTable tblMods; | 
|---|
| 95 | private ModTableModel model; | 
|---|
| 96 | private TableRowSorter<ModTableModel> sorter; | 
|---|
| 97 | private JLabel lblDownloadSizeVal; | 
|---|
| 98 |  | 
|---|
| 99 | private JLabel lblSubmitterVal; | 
|---|
| 100 | private JLabel lblCreatorVal; | 
|---|
| 101 | private JLabel lblTypesVal; | 
|---|
| 102 | private JLabel lblPlatformVal; | 
|---|
| 103 | private JLabel lblPackageNumberVal; | 
|---|
| 104 | private HTMLLinkLabel lblDescriptionVal; | 
|---|
| 105 |  | 
|---|
| 106 | private JButton btnInstall; | 
|---|
| 107 |  | 
|---|
| 108 | private TreeSet<Mod> execUpdates = null; | 
|---|
| 109 |  | 
|---|
| 110 | private enum EInstallResult { | 
|---|
| 111 | DONE, | 
|---|
| 112 | OFFLINE, | 
|---|
| 113 | INCOMPATIBLE | 
|---|
| 114 | }; | 
|---|
| 115 |  | 
|---|
| 116 | private EInstallResult installDone = EInstallResult.DONE; | 
|---|
| 117 |  | 
|---|
| 118 | /** | 
|---|
| 119 | * Constructor of main window. | 
|---|
| 120 | */ | 
|---|
| 121 | public MainWin() { | 
|---|
| 122 | this.setTitle(SwingJavaBuilder.getConfig().getResource("appname") | 
|---|
| 123 | + " - v" | 
|---|
| 124 | + SwingJavaBuilder.getConfig().getResource("appversion")); | 
|---|
| 125 |  | 
|---|
| 126 | contents.setDividerLocation(400); | 
|---|
| 127 |  | 
|---|
| 128 | if (Settings.getPlatform() == Platform.MACOS) { | 
|---|
| 129 | mainMenu.setVisible(false); | 
|---|
| 130 | } | 
|---|
| 131 |  | 
|---|
| 132 | getRootPane().setDefaultButton(btnInstall); | 
|---|
| 133 | lblDownloadSizeVal.setText(SizeFormatter.format(0, 2)); | 
|---|
| 134 | } | 
|---|
| 135 |  | 
|---|
| 136 | private void initModTypeBox() { | 
|---|
| 137 | cmbModTypes.removeAllItems(); | 
|---|
| 138 |  | 
|---|
| 139 | TreeMap<String, Type> types = new TreeMap<String, Type>(); | 
|---|
| 140 | for (Type t : ModManager.getInstance().getTypesWithContent()) { | 
|---|
| 141 | types.put(t.getName(), t); | 
|---|
| 142 | } | 
|---|
| 143 | for (Type t : types.values()) { | 
|---|
| 144 | cmbModTypes.addItem(t); | 
|---|
| 145 | } | 
|---|
| 146 | cmbModTypes.setSelectedIndex(0); | 
|---|
| 147 | } | 
|---|
| 148 |  | 
|---|
| 149 | private void initTable() { | 
|---|
| 150 | tblMods.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); | 
|---|
| 151 | tblMods.getSelectionModel().addListSelectionListener( | 
|---|
| 152 | new ListSelectionListener() { | 
|---|
| 153 | @Override | 
|---|
| 154 | public void valueChanged(ListSelectionEvent e) { | 
|---|
| 155 | int viewRow = tblMods.getSelectedRow(); | 
|---|
| 156 | if (viewRow < 0) { | 
|---|
| 157 | modSelection(null); | 
|---|
| 158 | } else { | 
|---|
| 159 | int modelRow = tblMods | 
|---|
| 160 | .convertRowIndexToModel(viewRow); | 
|---|
| 161 | Mod mod = (Mod) model.getValueAt(modelRow, -1); | 
|---|
| 162 | modSelection(mod); | 
|---|
| 163 | } | 
|---|
| 164 | } | 
|---|
| 165 | }); | 
|---|
| 166 | tblMods.addMouseListener(new MouseAdapter() { | 
|---|
| 167 | private void common(MouseEvent e) { | 
|---|
| 168 | int r = tblMods.rowAtPoint(e.getPoint()); | 
|---|
| 169 | if (r >= 0 && r < tblMods.getRowCount()) | 
|---|
| 170 | tblMods.setRowSelectionInterval(r, r); | 
|---|
| 171 | else | 
|---|
| 172 | tblMods.clearSelection(); | 
|---|
| 173 |  | 
|---|
| 174 | int rowindex = tblMods.getSelectedRow(); | 
|---|
| 175 | if (rowindex >= 0) { | 
|---|
| 176 | if (e.isPopupTrigger() | 
|---|
| 177 | && e.getComponent() instanceof JTable) { | 
|---|
| 178 | int modelRow = tblMods.convertRowIndexToModel(rowindex); | 
|---|
| 179 | final Mod mod = (Mod) model.getValueAt(modelRow, -1); | 
|---|
| 180 |  | 
|---|
| 181 | if (mod.isLocalAvailable()) { | 
|---|
| 182 | JPopupMenu popup = new JPopupMenu(); | 
|---|
| 183 | JMenuItem openModFolder = new JMenuItem(bundle | 
|---|
| 184 | .getString("openModFolder.text")); | 
|---|
| 185 | openModFolder | 
|---|
| 186 | .addActionListener(new ActionListener() { | 
|---|
| 187 | @Override | 
|---|
| 188 | public void actionPerformed( | 
|---|
| 189 | ActionEvent arg0) { | 
|---|
| 190 | try { | 
|---|
| 191 | Desktop.getDesktop().open( | 
|---|
| 192 | mod.getLocalPath()); | 
|---|
| 193 | } catch (IOException e) { | 
|---|
| 194 | e.printStackTrace(); | 
|---|
| 195 | } | 
|---|
| 196 | } | 
|---|
| 197 | }); | 
|---|
| 198 | popup.add(openModFolder); | 
|---|
| 199 | popup.show(e.getComponent(), e.getX(), e.getY()); | 
|---|
| 200 | } | 
|---|
| 201 | } | 
|---|
| 202 | } | 
|---|
| 203 | } | 
|---|
| 204 |  | 
|---|
| 205 | @Override | 
|---|
| 206 | public void mousePressed(MouseEvent e) { | 
|---|
| 207 | common(e); | 
|---|
| 208 | } | 
|---|
| 209 |  | 
|---|
| 210 | @Override | 
|---|
| 211 | public void mouseReleased(MouseEvent e) { | 
|---|
| 212 | common(e); | 
|---|
| 213 | } | 
|---|
| 214 | }); | 
|---|
| 215 | // To get checkbox-cells with background of row | 
|---|
| 216 | ((JComponent) tblMods.getDefaultRenderer(Boolean.class)) | 
|---|
| 217 | .setOpaque(true); | 
|---|
| 218 |  | 
|---|
| 219 | model = new ModTableModel(); | 
|---|
| 220 | model.addDownloadSizeListener(this); | 
|---|
| 221 |  | 
|---|
| 222 | tblMods.setModel(model); | 
|---|
| 223 |  | 
|---|
| 224 | sorter = new TableRowSorter<ModTableModel>(model); | 
|---|
| 225 | tblMods.setRowSorter(sorter); | 
|---|
| 226 |  | 
|---|
| 227 | sorter.setRowFilter(new ModTableFilter(null)); | 
|---|
| 228 |  | 
|---|
| 229 | List<RowSorter.SortKey> sortKeys = new ArrayList<RowSorter.SortKey>(); | 
|---|
| 230 | sortKeys.add(new RowSorter.SortKey(1, SortOrder.ASCENDING)); | 
|---|
| 231 | sorter.setSortKeys(sortKeys); | 
|---|
| 232 |  | 
|---|
| 233 | for (int i = 0; i < model.getColumnCount(); i++) { | 
|---|
| 234 | model.setColumnConstraints(i, tblMods.getColumnModel().getColumn(i)); | 
|---|
| 235 | } | 
|---|
| 236 | } | 
|---|
| 237 |  | 
|---|
| 238 | private void exit() { | 
|---|
| 239 | dispose(); | 
|---|
| 240 | System.exit(0); | 
|---|
| 241 | } | 
|---|
| 242 |  | 
|---|
| 243 | private void saveLocalData() { | 
|---|
| 244 | Settings.getInstance().serializeToFile(); | 
|---|
| 245 | DepotManager.getInstance().saveToFile(Settings.getDepotCacheFilename()); | 
|---|
| 246 | } | 
|---|
| 247 |  | 
|---|
| 248 | @DoInBackground(progressMessage = "updateDepot.title", cancelable = false, indeterminateProgress = false) | 
|---|
| 249 | private void execDepotUpdate(final BackgroundEvent evt) { | 
|---|
| 250 | if (!Settings.getInstance().isOfflineMode()) { | 
|---|
| 251 | try { | 
|---|
| 252 | DepotManager.getInstance().updateInformation(false, | 
|---|
| 253 | new DepotCacheUpdateProgressListener() { | 
|---|
| 254 |  | 
|---|
| 255 | @Override | 
|---|
| 256 | public void cacheUpdateProgress(String stepName, | 
|---|
| 257 | int current, int total) { | 
|---|
| 258 | evt.setProgressEnd(total); | 
|---|
| 259 | evt.setProgressValue(current); | 
|---|
| 260 | evt.setProgressMessage(stepName); | 
|---|
| 261 | } | 
|---|
| 262 | }); | 
|---|
| 263 | } catch (Exception e) { | 
|---|
| 264 | e.printStackTrace(); | 
|---|
| 265 | } | 
|---|
| 266 | } | 
|---|
| 267 | ModManager.getInstance().init(); | 
|---|
| 268 | initTable(); | 
|---|
| 269 | initModTypeBox(); | 
|---|
| 270 |  | 
|---|
| 271 | tblMods.setVisible(true); | 
|---|
| 272 | } | 
|---|
| 273 |  | 
|---|
| 274 | @SuppressWarnings("unused") | 
|---|
| 275 | private void checkUpdates(Object evtSource) { | 
|---|
| 276 | if ((evtSource != this) | 
|---|
| 277 | || Settings.getInstance().get("notifyupdates", true)) { | 
|---|
| 278 | if (Settings.getInstance().isOfflineMode()) { | 
|---|
| 279 | if (evtSource != this) { | 
|---|
| 280 | JOptionPane.showMessageDialog(this, | 
|---|
| 281 | bundle.getString("offlineMode.text"), | 
|---|
| 282 | bundle.getString("offlineMode.title"), | 
|---|
| 283 | JOptionPane.WARNING_MESSAGE); | 
|---|
| 284 | } | 
|---|
| 285 | } else { | 
|---|
| 286 | TreeSet<Mod> mods = ModManager.getInstance().getUpdatableMods(); | 
|---|
| 287 | TreeSet<Mod> tools = ModManager.getInstance() | 
|---|
| 288 | .getUpdatableTools(); | 
|---|
| 289 | int size = 0; | 
|---|
| 290 | String strMods = ""; | 
|---|
| 291 | for (Mod m : mods) { | 
|---|
| 292 | size += m.getZipSize(); | 
|---|
| 293 | if (strMods.length() > 0) | 
|---|
| 294 | strMods += "<br>"; | 
|---|
| 295 | strMods += " - " + m.getName(); | 
|---|
| 296 | } | 
|---|
| 297 | String strTools = ""; | 
|---|
| 298 | for (Mod m : tools) { | 
|---|
| 299 | size += m.getZipSize(); | 
|---|
| 300 | if (strTools.length() > 0) | 
|---|
| 301 | strTools += "<br>"; | 
|---|
| 302 | strTools += " - " + m.getName(); | 
|---|
| 303 | } | 
|---|
| 304 | if (size > 0) { | 
|---|
| 305 | String message = "<html>"; | 
|---|
| 306 | message += String.format( | 
|---|
| 307 | bundle.getString("updatesAvailable.text"), strMods, | 
|---|
| 308 | strTools, SizeFormatter.format(size, 3)); | 
|---|
| 309 | message += "</html>"; | 
|---|
| 310 | int res = JOptionPane.showConfirmDialog(this, message, | 
|---|
| 311 | bundle.getString("updatesAvailable.title"), | 
|---|
| 312 | JOptionPane.YES_NO_OPTION, | 
|---|
| 313 | JOptionPane.QUESTION_MESSAGE); | 
|---|
| 314 | if (res == JOptionPane.YES_OPTION) { | 
|---|
| 315 | execUpdates = new TreeSet<Mod>(); | 
|---|
| 316 | execUpdates.addAll(mods); | 
|---|
| 317 | execUpdates.addAll(tools); | 
|---|
| 318 | } | 
|---|
| 319 | } | 
|---|
| 320 | } | 
|---|
| 321 | } | 
|---|
| 322 | } | 
|---|
| 323 |  | 
|---|
| 324 | @SuppressWarnings("unused") | 
|---|
| 325 | private void doUpdate() { | 
|---|
| 326 | if (execUpdates != null) { | 
|---|
| 327 | Downloader dl = new Downloader(execUpdates); | 
|---|
| 328 | try { | 
|---|
| 329 | dl.setVisible(true); | 
|---|
| 330 | if (dl.isFinished()) { | 
|---|
| 331 | TreeSet<Integer> installed = Installer.getInstalledTools(); | 
|---|
| 332 | TreeSet<Mod> tools = new TreeSet<Mod>(); | 
|---|
| 333 | for (Mod m : execUpdates) | 
|---|
| 334 | if (m.isTool() | 
|---|
| 335 | && installed.contains(m.getPackageNumber())) | 
|---|
| 336 | tools.add(m); | 
|---|
| 337 | if (tools.size() > 0) { | 
|---|
| 338 | Installer.installTools(tools); | 
|---|
| 339 | } | 
|---|
| 340 | } | 
|---|
| 341 | } finally { | 
|---|
| 342 | dl.dispose(); | 
|---|
| 343 | } | 
|---|
| 344 | } | 
|---|
| 345 | execUpdates = null; | 
|---|
| 346 | } | 
|---|
| 347 |  | 
|---|
| 348 | @SuppressWarnings("unused") | 
|---|
| 349 | private void focus() { | 
|---|
| 350 | SwingUtilities.invokeLater(new Runnable() { | 
|---|
| 351 |  | 
|---|
| 352 | @Override | 
|---|
| 353 | public void run() { | 
|---|
| 354 | toFront(); | 
|---|
| 355 | repaint(); | 
|---|
| 356 | } | 
|---|
| 357 | }); | 
|---|
| 358 |  | 
|---|
| 359 | } | 
|---|
| 360 |  | 
|---|
| 361 | private void showSettings() { | 
|---|
| 362 | new SettingsDialog().setVisible(true); | 
|---|
| 363 | } | 
|---|
| 364 |  | 
|---|
| 365 | private void showAbout() { | 
|---|
| 366 | new AboutDialog().setVisible(true); | 
|---|
| 367 | } | 
|---|
| 368 |  | 
|---|
| 369 | private JFileChooser getConfigOpenSaveDialog(boolean save) { | 
|---|
| 370 | JFileChooser fc = new JFileChooser(); | 
|---|
| 371 | fc.setCurrentDirectory(Paths.getEditionBasePath()); | 
|---|
| 372 | if (save) | 
|---|
| 373 | fc.setDialogType(JFileChooser.SAVE_DIALOG); | 
|---|
| 374 | else | 
|---|
| 375 | fc.setDialogType(JFileChooser.OPEN_DIALOG); | 
|---|
| 376 | fc.setFileSelectionMode(JFileChooser.FILES_ONLY); | 
|---|
| 377 | fc.setFileFilter(new FileFilter() { | 
|---|
| 378 | @Override | 
|---|
| 379 | public String getDescription() { | 
|---|
| 380 | return "XML files"; | 
|---|
| 381 | } | 
|---|
| 382 |  | 
|---|
| 383 | @Override | 
|---|
| 384 | public boolean accept(File arg0) { | 
|---|
| 385 | return (arg0.isDirectory()) | 
|---|
| 386 | || (arg0.getName().toLowerCase().endsWith(".xml")); | 
|---|
| 387 | } | 
|---|
| 388 | }); | 
|---|
| 389 | fc.setMultiSelectionEnabled(false); | 
|---|
| 390 | return fc; | 
|---|
| 391 | } | 
|---|
| 392 |  | 
|---|
| 393 | @SuppressWarnings("unused") | 
|---|
| 394 | private void loadConfig() { | 
|---|
| 395 | JFileChooser fc = getConfigOpenSaveDialog(false); | 
|---|
| 396 | int res = fc.showOpenDialog(this); | 
|---|
| 397 | if (res == JFileChooser.APPROVE_OPTION) { | 
|---|
| 398 | if (fc.getSelectedFile().exists()) | 
|---|
| 399 | model.reloadSelection(fc.getSelectedFile()); | 
|---|
| 400 | } | 
|---|
| 401 | } | 
|---|
| 402 |  | 
|---|
| 403 | @SuppressWarnings("unused") | 
|---|
| 404 | private void saveConfig() { | 
|---|
| 405 | JFileChooser fc = getConfigOpenSaveDialog(true); | 
|---|
| 406 | int res = fc.showSaveDialog(this); | 
|---|
| 407 | if (res == JFileChooser.APPROVE_OPTION) { | 
|---|
| 408 | File f = fc.getSelectedFile(); | 
|---|
| 409 | if (!f.getName().endsWith(".xml")) | 
|---|
| 410 | f = new File(f.getParentFile(), f.getName() + ".xml"); | 
|---|
| 411 | ModManager.getInstance().saveModSelection(f, | 
|---|
| 412 | model.getSelectedMods()); | 
|---|
| 413 | } | 
|---|
| 414 | } | 
|---|
| 415 |  | 
|---|
| 416 | @DoInBackground(progressMessage = "initializingEdition.title", cancelable = false, indeterminateProgress = false) | 
|---|
| 417 | private void reglobalize(final BackgroundEvent evt) { | 
|---|
| 418 | Installer.initializeEdition(new InstallProgressListener() { | 
|---|
| 419 | @Override | 
|---|
| 420 | public void installProgressUpdate(int done, int total, String step) { | 
|---|
| 421 | evt.setProgressEnd(total); | 
|---|
| 422 | evt.setProgressValue(done); | 
|---|
| 423 | evt.setProgressMessage(step); | 
|---|
| 424 | } | 
|---|
| 425 | }); | 
|---|
| 426 | } | 
|---|
| 427 |  | 
|---|
| 428 | @SuppressWarnings("unused") | 
|---|
| 429 | private void tools() { | 
|---|
| 430 | // TODO: Open tools manager | 
|---|
| 431 | JOptionPane.showMessageDialog(this, "tools", "todo", | 
|---|
| 432 | JOptionPane.INFORMATION_MESSAGE); | 
|---|
| 433 | } | 
|---|
| 434 |  | 
|---|
| 435 | @SuppressWarnings("unused") | 
|---|
| 436 | private void refreshToolsMenu() { | 
|---|
| 437 | for (JMenuItem i : toolsMenuItems) { | 
|---|
| 438 | toolsMenu.remove(i); | 
|---|
| 439 | } | 
|---|
| 440 | toolsMenuItems.clear(); | 
|---|
| 441 | for (Mod m : ModManager.getInstance().getInstalledTools()) { | 
|---|
| 442 | if (m.getExeFile() != null && m.getExeFile().exists()) { | 
|---|
| 443 | JMenuItem item = new JMenuItem(); | 
|---|
| 444 | final Vector<String> params = new Vector<String>(); | 
|---|
| 445 | params.add(m.getExeFile().getPath()); | 
|---|
| 446 | final File wd = m.getWorkingDir(); | 
|---|
| 447 | Icon ico = null; | 
|---|
| 448 | if (m.getIconFile() != null && m.getIconFile().exists()) { | 
|---|
| 449 | ico = new ImageIcon(m.getIconFile().getPath()); | 
|---|
| 450 | } else { | 
|---|
| 451 | URL icon = AEInstaller2.class | 
|---|
| 452 | .getResource("images/transparent.png"); | 
|---|
| 453 | ico = new ImageIcon(icon); | 
|---|
| 454 | } | 
|---|
| 455 | item.setAction(new AbstractAction(m.getName(), ico) { | 
|---|
| 456 | private static final long serialVersionUID = 1L; | 
|---|
| 457 |  | 
|---|
| 458 | @Override | 
|---|
| 459 | public void actionPerformed(ActionEvent e) { | 
|---|
| 460 | AppExecution.execute(params, wd); | 
|---|
| 461 | } | 
|---|
| 462 | }); | 
|---|
| 463 | toolsMenuItems.add(item); | 
|---|
| 464 | toolsMenu.add(item); | 
|---|
| 465 | } | 
|---|
| 466 | } | 
|---|
| 467 | } | 
|---|
| 468 |  | 
|---|
| 469 | @SuppressWarnings("unused") | 
|---|
| 470 | private void revertSelection() { | 
|---|
| 471 | model.revertSelection(); | 
|---|
| 472 | } | 
|---|
| 473 |  | 
|---|
| 474 | @DoInBackground(progressMessage = "mandatoryFiles.title", cancelable = false, indeterminateProgress = false) | 
|---|
| 475 | private void checkMandatoryFiles(final BackgroundEvent evt) { | 
|---|
| 476 | if (!Settings.getInstance().isOfflineMode()) { | 
|---|
| 477 | TreeSet<Mod> mand = new TreeSet<Mod>(); | 
|---|
| 478 | for (Mod m : ModManager.getInstance().getMandatoryTools()) { | 
|---|
| 479 | if (m.isNewerAvailable()) { | 
|---|
| 480 | mand.add(m); | 
|---|
| 481 | } | 
|---|
| 482 | } | 
|---|
| 483 | for (Mod m : ModManager.getInstance().getMandatoryMods()) { | 
|---|
| 484 | if (m.isNewerAvailable()) { | 
|---|
| 485 | mand.add(m); | 
|---|
| 486 | } | 
|---|
| 487 | } | 
|---|
| 488 | if (mand.size() > 0) { | 
|---|
| 489 | ModDownloader m = new ModDownloader(mand, | 
|---|
| 490 | new ModDownloaderListener() { | 
|---|
| 491 | @Override | 
|---|
| 492 | public void updateStatus(ModDownloader source, | 
|---|
| 493 | State state, int filesDown, int filesTotal, | 
|---|
| 494 | int bytesDown, int bytesTotal, | 
|---|
| 495 | int duration, int remaining, int speed) { | 
|---|
| 496 | evt.setProgressEnd(filesTotal); | 
|---|
| 497 | evt.setProgressValue(filesDown); | 
|---|
| 498 | } | 
|---|
| 499 | }); | 
|---|
| 500 | while (!m.isFinished()) { | 
|---|
| 501 | try { | 
|---|
| 502 | Thread.sleep(10); | 
|---|
| 503 | } catch (InterruptedException e) { | 
|---|
| 504 | e.printStackTrace(); | 
|---|
| 505 | } | 
|---|
| 506 | } | 
|---|
| 507 | } | 
|---|
| 508 | evt.setProgressMessage(bundle | 
|---|
| 509 | .getString("mandatoryToolsInstall.title")); | 
|---|
| 510 | Installer | 
|---|
| 511 | .installTools(ModManager.getInstance().getMandatoryTools()); | 
|---|
| 512 | } | 
|---|
| 513 | } | 
|---|
| 514 |  | 
|---|
| 515 | @DoInBackground(progressMessage = "installing.title", cancelable = false, indeterminateProgress = false) | 
|---|
| 516 | private void install(final BackgroundEvent evt) { | 
|---|
| 517 | TreeSet<Mod> mods = new TreeSet<Mod>(); | 
|---|
| 518 | mods.addAll(ModManager.getInstance().getMandatoryMods()); | 
|---|
| 519 | mods.addAll(model.getSelectedMods()); | 
|---|
| 520 |  | 
|---|
| 521 | boolean instReady = false; | 
|---|
| 522 | installDone = EInstallResult.DONE; | 
|---|
| 523 |  | 
|---|
| 524 | while (!instReady) { | 
|---|
| 525 | TreeSet<Mod> toDownload = new TreeSet<Mod>(); | 
|---|
| 526 | for (Mod m : mods) { | 
|---|
| 527 | if (!m.isLocalAvailable()) | 
|---|
| 528 | toDownload.add(m); | 
|---|
| 529 | } | 
|---|
| 530 | if (Settings.getInstance().isOfflineMode()) { | 
|---|
| 531 | installDone = EInstallResult.OFFLINE; | 
|---|
| 532 | break; | 
|---|
| 533 | } | 
|---|
| 534 | if (toDownload.size() > 0) { | 
|---|
| 535 | Downloader dl = new Downloader(toDownload); | 
|---|
| 536 | try { | 
|---|
| 537 | dl.setVisible(true); | 
|---|
| 538 | if (!dl.isFinished()) | 
|---|
| 539 | break; | 
|---|
| 540 | } finally { | 
|---|
| 541 | dl.dispose(); | 
|---|
| 542 | } | 
|---|
| 543 | } | 
|---|
| 544 | HashMap<Mod, HashSet<Mod>> dependencies = ModManager.getInstance() | 
|---|
| 545 | .checkDependencies(mods); | 
|---|
| 546 | if (dependencies.size() > 0) { | 
|---|
| 547 | System.out.println("Unmet dependencies: " | 
|---|
| 548 | + dependencies.toString()); | 
|---|
| 549 | for (Mod m : dependencies.keySet()) { | 
|---|
| 550 | for (Mod mDep : dependencies.get(m)) | 
|---|
| 551 | mods.add(mDep); | 
|---|
| 552 | } | 
|---|
| 553 | } else { | 
|---|
| 554 | HashMap<Mod, HashSet<Mod>> conflicts = ModManager.getInstance() | 
|---|
| 555 | .checkIncompabitilites(mods); | 
|---|
| 556 | if (conflicts.size() > 0) { | 
|---|
| 557 | installDone = EInstallResult.INCOMPATIBLE; | 
|---|
| 558 | System.err.println("Incompatible mods: " | 
|---|
| 559 | + conflicts.toString()); | 
|---|
| 560 | break; | 
|---|
| 561 | } else { | 
|---|
| 562 | instReady = true; | 
|---|
| 563 | } | 
|---|
| 564 | } | 
|---|
| 565 | } | 
|---|
| 566 |  | 
|---|
| 567 | if (instReady) { | 
|---|
| 568 | TreeSet<Mod> actuallyMods = new TreeSet<Mod>(); | 
|---|
| 569 | TreeSet<Mod> actuallyTools = new TreeSet<Mod>(); | 
|---|
| 570 |  | 
|---|
| 571 | for (Mod m : mods) { | 
|---|
| 572 | if (m.isTool()) | 
|---|
| 573 | actuallyTools.add(m); | 
|---|
| 574 | else | 
|---|
| 575 | actuallyMods.add(m); | 
|---|
| 576 | } | 
|---|
| 577 |  | 
|---|
| 578 | if (actuallyTools.size() > 0) { | 
|---|
| 579 | Installer.installTools(actuallyTools); | 
|---|
| 580 | } | 
|---|
| 581 |  | 
|---|
| 582 | Installer.install(actuallyMods, new InstallProgressListener() { | 
|---|
| 583 | @Override | 
|---|
| 584 | public void installProgressUpdate(int done, int total, | 
|---|
| 585 | String step) { | 
|---|
| 586 | evt.setProgressEnd(total); | 
|---|
| 587 | evt.setProgressValue(done); | 
|---|
| 588 | evt.setProgressMessage(step); | 
|---|
| 589 | } | 
|---|
| 590 | }); | 
|---|
| 591 | installDone = EInstallResult.DONE; | 
|---|
| 592 | } | 
|---|
| 593 | } | 
|---|
| 594 |  | 
|---|
| 595 | @SuppressWarnings("unused") | 
|---|
| 596 | private void installDone() { | 
|---|
| 597 | switch (installDone) { | 
|---|
| 598 | case DONE: | 
|---|
| 599 | JOptionPane.showMessageDialog(this, | 
|---|
| 600 | bundle.getString("installDone.text"), | 
|---|
| 601 | bundle.getString("installDone.title"), | 
|---|
| 602 | JOptionPane.INFORMATION_MESSAGE); | 
|---|
| 603 | break; | 
|---|
| 604 | case OFFLINE: | 
|---|
| 605 | JOptionPane.showMessageDialog(this, | 
|---|
| 606 | bundle.getString("offlineMode.text"), | 
|---|
| 607 | bundle.getString("offlineMode.title"), | 
|---|
| 608 | JOptionPane.WARNING_MESSAGE); | 
|---|
| 609 | break; | 
|---|
| 610 | case INCOMPATIBLE: | 
|---|
| 611 | break; | 
|---|
| 612 | } | 
|---|
| 613 | } | 
|---|
| 614 |  | 
|---|
| 615 | private void modSelection(Mod m) { | 
|---|
| 616 | lblSubmitterVal.setText(""); | 
|---|
| 617 | lblCreatorVal.setText(""); | 
|---|
| 618 | lblDescriptionVal.setText(""); | 
|---|
| 619 | lblTypesVal.setText(""); | 
|---|
| 620 | lblPlatformVal.setText(""); | 
|---|
| 621 | lblPackageNumberVal.setText(""); | 
|---|
| 622 | if (m != null) { | 
|---|
| 623 | lblSubmitterVal.setText(m.getName()); | 
|---|
| 624 | lblCreatorVal.setText(m.getCreator()); | 
|---|
| 625 | lblDescriptionVal.setText(m.getDescription()); | 
|---|
| 626 |  | 
|---|
| 627 | String types = ""; | 
|---|
| 628 | for (Type t : m.getTypes()) { | 
|---|
| 629 | if (types.length() > 0) | 
|---|
| 630 | types += ", "; | 
|---|
| 631 | types += t.getName(); | 
|---|
| 632 | } | 
|---|
| 633 | lblTypesVal.setText(types); | 
|---|
| 634 | lblPlatformVal.setText(m.getPlatform().toString()); | 
|---|
| 635 | lblPackageNumberVal.setText(m.getPackageNumberString()); | 
|---|
| 636 | } | 
|---|
| 637 | } | 
|---|
| 638 |  | 
|---|
| 639 | @SuppressWarnings("unused") | 
|---|
| 640 | private void modTypeSelection() { | 
|---|
| 641 | Type t = (Type) cmbModTypes.getSelectedItem(); | 
|---|
| 642 | if (t != null) | 
|---|
| 643 | sorter.setRowFilter(new ModTableFilter(t)); | 
|---|
| 644 | else | 
|---|
| 645 | sorter.setRowFilter(new ModTableFilter(null)); | 
|---|
| 646 | } | 
|---|
| 647 |  | 
|---|
| 648 | @Override | 
|---|
| 649 | public void downloadSizeChanged(int newSize) { | 
|---|
| 650 | lblDownloadSizeVal.setText(SizeFormatter.format(newSize, 2)); | 
|---|
| 651 | } | 
|---|
| 652 |  | 
|---|
| 653 | @SuppressWarnings("unused") | 
|---|
| 654 | private void checkInitialize() { | 
|---|
| 655 | if (!Installer.isEditionInitialized()) { | 
|---|
| 656 | if (!OniSplit.isOniSplitInstalled()) { | 
|---|
| 657 | JOptionPane.showMessageDialog(this, | 
|---|
| 658 | bundle.getString("noOniSplit.text"), | 
|---|
| 659 | bundle.getString("noOniSplit.title"), | 
|---|
| 660 | JOptionPane.ERROR_MESSAGE); | 
|---|
| 661 | exit(); | 
|---|
| 662 | } else { | 
|---|
| 663 | int res = JOptionPane | 
|---|
| 664 | .showConfirmDialog(this, | 
|---|
| 665 | bundle.getString("askInitialize.text"), | 
|---|
| 666 | bundle.getString("askInitialize.title"), | 
|---|
| 667 | JOptionPane.YES_NO_OPTION, | 
|---|
| 668 | JOptionPane.QUESTION_MESSAGE); | 
|---|
| 669 | if (res == JOptionPane.NO_OPTION) { | 
|---|
| 670 | saveLocalData(); | 
|---|
| 671 | exit(); | 
|---|
| 672 | } | 
|---|
| 673 | } | 
|---|
| 674 | } | 
|---|
| 675 | } | 
|---|
| 676 |  | 
|---|
| 677 | @DoInBackground(progressMessage = "initializingEdition.title", cancelable = false, indeterminateProgress = false) | 
|---|
| 678 | private void initialize(final BackgroundEvent evt) { | 
|---|
| 679 | if (!Installer.isEditionInitialized()) { | 
|---|
| 680 | Installer.initializeEdition(new InstallProgressListener() { | 
|---|
| 681 | @Override | 
|---|
| 682 | public void installProgressUpdate(int done, int total, | 
|---|
| 683 | String step) { | 
|---|
| 684 | evt.setProgressEnd(total); | 
|---|
| 685 | evt.setProgressValue(done); | 
|---|
| 686 | evt.setProgressMessage(step); | 
|---|
| 687 | } | 
|---|
| 688 | }); | 
|---|
| 689 | } | 
|---|
| 690 | } | 
|---|
| 691 |  | 
|---|
| 692 | private Vector<String> getBasicOniLaunchParams() { | 
|---|
| 693 | Vector<String> params = new Vector<String>(); | 
|---|
| 694 | File exe = null; | 
|---|
| 695 | switch (Settings.getPlatform()) { | 
|---|
| 696 | case WIN: | 
|---|
| 697 | exe = new File(Paths.getEditionBasePath(), "Oni.exe"); | 
|---|
| 698 | if (exe.exists()) | 
|---|
| 699 | params.add(exe.getPath()); | 
|---|
| 700 | break; | 
|---|
| 701 | case MACOS: | 
|---|
| 702 | exe = new File(Paths.getEditionBasePath(), | 
|---|
| 703 | "Oni.app/Contents/MacOS/Oni"); | 
|---|
| 704 | if (exe.exists()) | 
|---|
| 705 | params.add(exe.getPath()); | 
|---|
| 706 | break; | 
|---|
| 707 | case LINUX: | 
|---|
| 708 | String wine = Settings.getWinePath(); | 
|---|
| 709 | exe = new File(Paths.getEditionBasePath(), "Oni.exe"); | 
|---|
| 710 | if (exe.exists()) { | 
|---|
| 711 | if (wine != null) { | 
|---|
| 712 | params.add(wine); | 
|---|
| 713 | params.add(exe.getPath()); | 
|---|
| 714 | } | 
|---|
| 715 | } | 
|---|
| 716 | break; | 
|---|
| 717 | default: | 
|---|
| 718 | } | 
|---|
| 719 | if (params.size() > 0) { | 
|---|
| 720 | params.add("-debugfiles"); | 
|---|
| 721 | } | 
|---|
| 722 | return params; | 
|---|
| 723 | } | 
|---|
| 724 |  | 
|---|
| 725 | @SuppressWarnings("unused") | 
|---|
| 726 | private void oniFull() { | 
|---|
| 727 | Vector<String> params = getBasicOniLaunchParams(); | 
|---|
| 728 | if (params.size() > 0) { | 
|---|
| 729 | AppExecution.execute(params, Paths.getEditionBasePath()); | 
|---|
| 730 | } | 
|---|
| 731 | } | 
|---|
| 732 |  | 
|---|
| 733 | @SuppressWarnings("unused") | 
|---|
| 734 | private void oniWin() { | 
|---|
| 735 | Vector<String> params = getBasicOniLaunchParams(); | 
|---|
| 736 | if (params.size() > 0) { | 
|---|
| 737 | params.add("-noswitch"); | 
|---|
| 738 | AppExecution.execute(params, Paths.getEditionBasePath()); | 
|---|
| 739 | } | 
|---|
| 740 | } | 
|---|
| 741 |  | 
|---|
| 742 | @SuppressWarnings("unused") | 
|---|
| 743 | private void openEditionFolder() { | 
|---|
| 744 | try { | 
|---|
| 745 | Desktop.getDesktop().open(Paths.getEditionBasePath()); | 
|---|
| 746 | } catch (IOException e) { | 
|---|
| 747 | e.printStackTrace(); | 
|---|
| 748 | } | 
|---|
| 749 | } | 
|---|
| 750 |  | 
|---|
| 751 | @Override | 
|---|
| 752 | public void handleAbout(ApplicationEvent event) { | 
|---|
| 753 | event.setHandled(true); | 
|---|
| 754 | showAbout(); | 
|---|
| 755 | } | 
|---|
| 756 |  | 
|---|
| 757 | @Override | 
|---|
| 758 | public void handleOpenApplication(ApplicationEvent event) { | 
|---|
| 759 | } | 
|---|
| 760 |  | 
|---|
| 761 | @Override | 
|---|
| 762 | public void handleOpenFile(ApplicationEvent event) { | 
|---|
| 763 | } | 
|---|
| 764 |  | 
|---|
| 765 | @Override | 
|---|
| 766 | public void handlePreferences(ApplicationEvent event) { | 
|---|
| 767 | showSettings(); | 
|---|
| 768 | } | 
|---|
| 769 |  | 
|---|
| 770 | @Override | 
|---|
| 771 | public void handlePrintFile(ApplicationEvent event) { | 
|---|
| 772 | } | 
|---|
| 773 |  | 
|---|
| 774 | @Override | 
|---|
| 775 | public void handleQuit(ApplicationEvent event) { | 
|---|
| 776 | event.setHandled(true); | 
|---|
| 777 | saveLocalData(); | 
|---|
| 778 | exit(); | 
|---|
| 779 | } | 
|---|
| 780 |  | 
|---|
| 781 | @Override | 
|---|
| 782 | public void handleReOpenApplication(ApplicationEvent event) { | 
|---|
| 783 | } | 
|---|
| 784 |  | 
|---|
| 785 | } | 
|---|