source: AE/installer2/src/net/oni2/aeinstaller/gui/MainWin.java@ 606

Last change on this file since 606 was 606, checked in by alloc, 12 years ago

AEI2:

  • Table columns "Type" and "Platform" removed
  • Column "Install" moved to front
  • Added Type+Platform to the description pane for now
  • Order of level-installation: now in alphabetical order (0, 10...19, 1...9)
  • Oni launched with WorkDir set to the Edition folder instead of AEI folder
File size: 15.4 KB
Line 
1package net.oni2.aeinstaller.gui;
2
3import java.io.File;
4import java.io.IOException;
5import java.util.ArrayList;
6import java.util.HashMap;
7import java.util.HashSet;
8import java.util.List;
9import java.util.ResourceBundle;
10import java.util.TreeMap;
11import java.util.TreeSet;
12import java.util.Vector;
13
14import javax.swing.JButton;
15import javax.swing.JComboBox;
16import javax.swing.JComponent;
17import javax.swing.JFileChooser;
18import javax.swing.JFrame;
19import javax.swing.JLabel;
20import javax.swing.JMenu;
21import javax.swing.JOptionPane;
22import javax.swing.JSplitPane;
23import javax.swing.JTable;
24import javax.swing.ListSelectionModel;
25import javax.swing.RowSorter;
26import javax.swing.SortOrder;
27import javax.swing.SwingUtilities;
28import javax.swing.event.ListSelectionEvent;
29import javax.swing.event.ListSelectionListener;
30import javax.swing.filechooser.FileFilter;
31import javax.swing.table.TableRowSorter;
32
33import net.oni2.aeinstaller.backend.Paths;
34import net.oni2.aeinstaller.backend.Settings;
35import net.oni2.aeinstaller.backend.Settings.Platform;
36import net.oni2.aeinstaller.backend.SizeFormatter;
37import net.oni2.aeinstaller.backend.depot.DepotCacheUpdateProgressListener;
38import net.oni2.aeinstaller.backend.depot.DepotManager;
39import net.oni2.aeinstaller.backend.mods.Mod;
40import net.oni2.aeinstaller.backend.mods.ModManager;
41import net.oni2.aeinstaller.backend.mods.Type;
42import net.oni2.aeinstaller.backend.mods.download.ModDownloader;
43import net.oni2.aeinstaller.backend.mods.download.ModDownloader.State;
44import net.oni2.aeinstaller.backend.mods.download.ModDownloaderListener;
45import net.oni2.aeinstaller.backend.oni.InstallProgressListener;
46import net.oni2.aeinstaller.backend.oni.Installer;
47import net.oni2.aeinstaller.gui.about.AboutDialog;
48import net.oni2.aeinstaller.gui.downloadwindow.Downloader;
49import net.oni2.aeinstaller.gui.modtable.DownloadSizeListener;
50import net.oni2.aeinstaller.gui.modtable.ModTableFilter;
51import net.oni2.aeinstaller.gui.modtable.ModTableModel;
52import net.oni2.aeinstaller.gui.settings.SettingsDialog;
53
54import org.javabuilders.BuildResult;
55import org.javabuilders.annotations.DoInBackground;
56import org.javabuilders.event.BackgroundEvent;
57import org.javabuilders.swing.SwingJavaBuilder;
58import org.simplericity.macify.eawt.ApplicationEvent;
59import org.simplericity.macify.eawt.ApplicationListener;
60
61/**
62 * @author Christian Illy
63 */
64public class MainWin extends JFrame implements ApplicationListener,
65 DownloadSizeListener {
66 private static final long serialVersionUID = -4027395051382659650L;
67
68 private ResourceBundle bundle = ResourceBundle.getBundle(getClass()
69 .getName());
70 @SuppressWarnings("unused")
71 private BuildResult result = SwingJavaBuilder.build(this, bundle);
72
73 private JMenu mainMenu;
74
75 private JSplitPane contents;
76
77 private JComboBox cmbModTypes;
78 private JTable tblMods;
79 private ModTableModel model;
80 private TableRowSorter<ModTableModel> sorter;
81 private JLabel lblDownloadSizeVal;
82
83 private JLabel lblSubmitterVal;
84 private JLabel lblCreatorVal;
85 private JLabel lblTypesVal;
86 private JLabel lblPlatformVal;
87 private HTMLLinkLabel lblDescriptionVal;
88
89 private JButton btnInstall;
90
91 /**
92 * Constructor of main window.
93 */
94 public MainWin() {
95 this.setTitle(SwingJavaBuilder.getConfig().getResource("appname")
96 + " - v"
97 + SwingJavaBuilder.getConfig().getResource("appversion"));
98
99 contents.setDividerLocation(400);
100
101 if (Settings.getPlatform() == Platform.MACOS) {
102 mainMenu.setVisible(false);
103 }
104
105 getRootPane().setDefaultButton(btnInstall);
106 lblDownloadSizeVal.setText(SizeFormatter.format(0, 2));
107 }
108
109 private void initModTypeBox() {
110 cmbModTypes.removeAllItems();
111
112 TreeMap<String, Type> types = new TreeMap<String, Type>();
113 for (Type t : ModManager.getInstance().getTypesWithContent()) {
114 types.put(t.getName(), t);
115 }
116 for (Type t : types.values()) {
117 cmbModTypes.addItem(t);
118 }
119 cmbModTypes.setSelectedIndex(0);
120 }
121
122 private void initTable() {
123 tblMods.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
124 tblMods.getSelectionModel().addListSelectionListener(
125 new ListSelectionListener() {
126
127 @Override
128 public void valueChanged(ListSelectionEvent e) {
129 int viewRow = tblMods.getSelectedRow();
130 if (viewRow < 0) {
131 modSelection(null);
132 } else {
133 int modelRow = tblMods
134 .convertRowIndexToModel(viewRow);
135 Mod mod = (Mod) model.getValueAt(modelRow, -1);
136 modSelection(mod);
137 }
138 }
139 });
140
141 // To get checkbox-cells with background of row
142 ((JComponent) tblMods.getDefaultRenderer(Boolean.class))
143 .setOpaque(true);
144
145 model = new ModTableModel();
146 model.addDownloadSizeListener(this);
147
148 tblMods.setModel(model);
149
150 sorter = new TableRowSorter<ModTableModel>(model);
151 tblMods.setRowSorter(sorter);
152
153 sorter.setRowFilter(new ModTableFilter(null));
154
155 List<RowSorter.SortKey> sortKeys = new ArrayList<RowSorter.SortKey>();
156 sortKeys.add(new RowSorter.SortKey(1, SortOrder.ASCENDING));
157 sorter.setSortKeys(sortKeys);
158
159 for (int i = 0; i < model.getColumnCount(); i++) {
160 model.setColumnConstraints(i, tblMods.getColumnModel().getColumn(i));
161 }
162 }
163
164 private void exit() {
165 setVisible(false);
166 dispose();
167 }
168
169 private void saveLocalData() {
170 Settings.getInstance().serializeToFile();
171 DepotManager.getInstance().saveToFile(Settings.getDepotCacheFilename());
172 }
173
174 @DoInBackground(progressMessage = "updateDepot.title", cancelable = false, indeterminateProgress = false)
175 private void execDepotUpdate(final BackgroundEvent evt) {
176 try {
177 DepotManager.getInstance().updateInformation(false,
178 new DepotCacheUpdateProgressListener() {
179
180 @Override
181 public void cacheUpdateProgress(String stepName,
182 int current, int total) {
183 evt.setProgressEnd(total);
184 evt.setProgressValue(current);
185 evt.setProgressMessage(stepName);
186 }
187 });
188 ModManager.getInstance().init();
189 initTable();
190 initModTypeBox();
191
192 tblMods.setVisible(true);
193 } catch (Exception e) {
194 e.printStackTrace();
195 }
196 }
197
198 @SuppressWarnings("unused")
199 private void checkUpdates() {
200 if (Settings.getInstance().get("notifyupdates", true)) {
201 }
202 }
203
204 @SuppressWarnings("unused")
205 private void focus() {
206 SwingUtilities.invokeLater(new Runnable() {
207
208 @Override
209 public void run() {
210 toFront();
211 repaint();
212 }
213 });
214
215 }
216
217 private void showSettings() {
218 new SettingsDialog().setVisible(true);
219 }
220
221 private void showAbout() {
222 new AboutDialog().setVisible(true);
223 }
224
225 private JFileChooser getConfigOpenSaveDialog(boolean save) {
226 JFileChooser fc = new JFileChooser();
227 fc.setCurrentDirectory(Paths.getEditionBasePath());
228 if (save)
229 fc.setDialogType(JFileChooser.SAVE_DIALOG);
230 else
231 fc.setDialogType(JFileChooser.OPEN_DIALOG);
232 fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
233 fc.setFileFilter(new FileFilter() {
234 @Override
235 public String getDescription() {
236 return "XML files";
237 }
238
239 @Override
240 public boolean accept(File arg0) {
241 return (arg0.isDirectory())
242 || (arg0.getName().toLowerCase().endsWith(".xml"));
243 }
244 });
245 fc.setMultiSelectionEnabled(false);
246 return fc;
247 }
248
249 @SuppressWarnings("unused")
250 private void loadConfig() {
251 JFileChooser fc = getConfigOpenSaveDialog(false);
252 int res = fc.showOpenDialog(this);
253 if (res == JFileChooser.APPROVE_OPTION) {
254 if (fc.getSelectedFile().exists())
255 model.reloadSelection(fc.getSelectedFile());
256 }
257 }
258
259 @SuppressWarnings("unused")
260 private void saveConfig() {
261 JFileChooser fc = getConfigOpenSaveDialog(true);
262 int res = fc.showSaveDialog(this);
263 if (res == JFileChooser.APPROVE_OPTION) {
264 File f = fc.getSelectedFile();
265 if (!f.getName().endsWith(".xml"))
266 f = new File(f.getParentFile(), f.getName() + ".xml");
267 ModManager.getInstance().saveModSelection(f,
268 model.getSelectedMods());
269 }
270 }
271
272 @DoInBackground(progressMessage = "initializingEdition.title", cancelable = false, indeterminateProgress = false)
273 private void reglobalize(final BackgroundEvent evt) {
274 Installer.initializeEdition(new InstallProgressListener() {
275 @Override
276 public void installProgressUpdate(int done, int total, String step) {
277 evt.setProgressEnd(total);
278 evt.setProgressValue(done);
279 evt.setProgressMessage(step);
280 }
281 });
282 }
283
284 @SuppressWarnings("unused")
285 private void tools() {
286 // TODO method stub
287 JOptionPane.showMessageDialog(this, "tools", "todo",
288 JOptionPane.INFORMATION_MESSAGE);
289 }
290
291 @SuppressWarnings("unused")
292 private void revertSelection() {
293 model.revertSelection();
294 }
295
296 @DoInBackground(progressMessage = "mandatoryFiles.title", cancelable = false, indeterminateProgress = false)
297 private void checkMandatoryFiles(final BackgroundEvent evt) {
298 TreeSet<Mod> mand = new TreeSet<Mod>();
299 for (Mod m : ModManager.getInstance().getMandatoryTools()) {
300 if (m.isNewerAvailable()) {
301 mand.add(m);
302 }
303 }
304 for (Mod m : ModManager.getInstance().getMandatoryMods()) {
305 if (m.isNewerAvailable()) {
306 mand.add(m);
307 }
308 }
309 if (mand.size() > 0) {
310 ModDownloader m = new ModDownloader(mand,
311 new ModDownloaderListener() {
312 @Override
313 public void updateStatus(ModDownloader source,
314 State state, int filesDown, int filesTotal,
315 int bytesDown, int bytesTotal, int duration,
316 int remaining, int speed) {
317 evt.setProgressEnd(filesTotal);
318 evt.setProgressValue(filesDown);
319 }
320 });
321 while (!m.isFinished()) {
322 try {
323 Thread.sleep(10);
324 } catch (InterruptedException e) {
325 // TODO Auto-generated catch block
326 e.printStackTrace();
327 }
328 }
329 }
330 evt.setProgressMessage(bundle.getString("mandatoryToolsInstall.title"));
331 Installer.installTools(ModManager.getInstance().getMandatoryTools());
332 }
333
334 @DoInBackground(progressMessage = "installing.title", cancelable = false, indeterminateProgress = false)
335 private void install(final BackgroundEvent evt) {
336 TreeSet<Mod> mods = new TreeSet<Mod>();
337 mods.addAll(ModManager.getInstance().getMandatoryMods());
338 mods.addAll(model.getSelectedMods());
339
340 boolean instReady = false;
341
342 while (!instReady) {
343 System.out.println("Checking downloads:");
344 TreeSet<Mod> toDownload = new TreeSet<Mod>();
345 for (Mod m : mods) {
346 if (!m.isLocalAvailable())
347 toDownload.add(m);
348 }
349 if (toDownload.size() > 0) {
350 System.out.println("Download files: " + toDownload.toString());
351 Downloader dl = new Downloader(toDownload);
352 dl.setVisible(true);
353 if (!dl.isFinished())
354 break;
355 }
356 HashMap<Mod, HashSet<Mod>> dependencies = ModManager.getInstance()
357 .checkDependencies(mods);
358 if (dependencies.size() > 0) {
359 System.out.println("Unmet dependencies: "
360 + dependencies.toString());
361 for (Mod m : dependencies.keySet()) {
362 for (Mod mDep : dependencies.get(m))
363 mods.add(mDep);
364 }
365 } else {
366 HashMap<Mod, HashSet<Mod>> conflicts = ModManager.getInstance()
367 .checkConflicts(mods);
368 if (conflicts.size() > 0) {
369 System.err.println("Conflicting mods: "
370 + conflicts.toString());
371 break;
372 } else {
373 instReady = true;
374 }
375 }
376 }
377
378 if (instReady) {
379 Installer.install(mods, new InstallProgressListener() {
380 @Override
381 public void installProgressUpdate(int done, int total,
382 String step) {
383 evt.setProgressEnd(total);
384 evt.setProgressValue(done);
385 evt.setProgressMessage(step);
386 }
387 });
388
389 JOptionPane.showMessageDialog(this,
390 bundle.getString("installDone.text"),
391 bundle.getString("installDone.title"),
392 JOptionPane.INFORMATION_MESSAGE);
393 }
394 }
395
396 private void modSelection(Mod m) {
397 lblSubmitterVal.setText("");
398 lblCreatorVal.setText("");
399 lblDescriptionVal.setText("");
400 lblTypesVal.setText("");
401 lblPlatformVal.setText("");
402 if (m != null) {
403 lblSubmitterVal.setText(m.getName());
404 lblCreatorVal.setText(m.getCreator());
405 lblDescriptionVal.setText(m.getDescription());
406
407 String types = "";
408 for (Type t : m.getTypes()) {
409 if (types.length() > 0)
410 types += ", ";
411 types += t.getName();
412 }
413 lblTypesVal.setText(types);
414 lblPlatformVal.setText(m.getPlatform().toString());
415 }
416 // TODO
417 }
418
419 @SuppressWarnings("unused")
420 private void modTypeSelection() {
421 Type t = (Type) cmbModTypes.getSelectedItem();
422 if (t != null)
423 sorter.setRowFilter(new ModTableFilter(t));
424 else
425 sorter.setRowFilter(new ModTableFilter(null));
426 }
427
428 @Override
429 public void downloadSizeChanged(int newSize) {
430 lblDownloadSizeVal.setText(SizeFormatter.format(newSize, 2));
431 }
432
433 @DoInBackground(progressMessage = "initializingEdition.title", cancelable = false, indeterminateProgress = false)
434 private void initialize(final BackgroundEvent evt) {
435 if (!Installer.isEditionInitialized()) {
436 int res = JOptionPane.showConfirmDialog(this,
437 bundle.getString("askInitialize.text"),
438 bundle.getString("askInitialize.title"),
439 JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
440 if (res == JOptionPane.NO_OPTION) {
441 exit();
442 } else {
443 Installer.initializeEdition(new InstallProgressListener() {
444 @Override
445 public void installProgressUpdate(int done, int total,
446 String step) {
447 evt.setProgressEnd(total);
448 evt.setProgressValue(done);
449 evt.setProgressMessage(step);
450 }
451 });
452 }
453 }
454 }
455
456 private Vector<String> getBasicOniLaunchParams() {
457 Vector<String> params = new Vector<String>();
458 switch (Settings.getPlatform()) {
459 case WIN:
460 params.add(new File(Paths.getEditionBasePath(), "Oni.exe")
461 .getPath());
462 break;
463 case MACOS:
464 params.add(new File(Paths.getEditionBasePath(), "Oni")
465 .getPath());
466 break;
467 case LINUX:
468 String wine = Settings.getWinePath();
469 if (wine != null) {
470 params.add(wine);
471 params.add(new File(Paths.getEditionBasePath(), "Oni.exe")
472 .getPath());
473 }
474 break;
475 default:
476 }
477 if (params.size() > 0) {
478 params.add("-debugfiles");
479 }
480 return params;
481 }
482
483 @SuppressWarnings("unused")
484 private void oniFull() {
485 Vector<String> params = getBasicOniLaunchParams();
486 if (params.size() > 0) {
487 try {
488 ProcessBuilder pb = new ProcessBuilder(params);
489 pb.directory(Paths.getEditionBasePath());
490 pb.start();
491 } catch (IOException e) {
492 // TODO Auto-generated catch block
493 e.printStackTrace();
494 }
495 }
496 }
497
498 @SuppressWarnings("unused")
499 private void oniWin() {
500 Vector<String> params = getBasicOniLaunchParams();
501 if (params.size() > 0) {
502 params.add("-noswitch");
503 try {
504 ProcessBuilder pb = new ProcessBuilder(params);
505 pb.directory(Paths.getEditionBasePath());
506 pb.start();
507 } catch (IOException e) {
508 // TODO Auto-generated catch block
509 e.printStackTrace();
510 }
511 }
512 }
513
514 @Override
515 public void handleAbout(ApplicationEvent event) {
516 event.setHandled(true);
517 showAbout();
518 }
519
520 @Override
521 public void handleOpenApplication(ApplicationEvent event) {
522 }
523
524 @Override
525 public void handleOpenFile(ApplicationEvent event) {
526 }
527
528 @Override
529 public void handlePreferences(ApplicationEvent event) {
530 showSettings();
531 }
532
533 @Override
534 public void handlePrintFile(ApplicationEvent event) {
535 }
536
537 @Override
538 public void handleQuit(ApplicationEvent event) {
539 event.setHandled(true);
540 saveLocalData();
541 exit();
542 }
543
544 @Override
545 public void handleReOpenApplication(ApplicationEvent event) {
546 }
547
548}
Note: See TracBrowser for help on using the repository browser.