Line 1... |
Line 1... |
1 |
/*
|
1 |
/*
|
2 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
|
2 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
|
3 |
*
|
3 |
*
|
4 |
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
|
4 |
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
|
5 |
*
|
5 |
*
|
6 |
* The contents of this file are subject to the terms of the GNU General Public License Version 3
|
6 |
* The contents of this file are subject to the terms of the GNU General Public License Version 3
|
7 |
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
|
7 |
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
|
8 |
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
|
8 |
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
|
9 |
* language governing permissions and limitations under the License.
|
9 |
* language governing permissions and limitations under the License.
|
Line 31... |
Line 31... |
31 |
import org.openconcerto.utils.JImage;
|
31 |
import org.openconcerto.utils.JImage;
|
32 |
import org.openconcerto.utils.OSXAdapter;
|
32 |
import org.openconcerto.utils.OSXAdapter;
|
33 |
|
33 |
|
34 |
import java.awt.Color;
|
34 |
import java.awt.Color;
|
35 |
import java.awt.Container;
|
35 |
import java.awt.Container;
|
- |
|
36 |
import java.awt.Desktop;
|
36 |
import java.awt.Dimension;
|
37 |
import java.awt.Dimension;
|
37 |
import java.awt.GridBagConstraints;
|
38 |
import java.awt.GridBagConstraints;
|
38 |
import java.awt.GridBagLayout;
|
39 |
import java.awt.GridBagLayout;
|
39 |
import java.awt.Image;
|
40 |
import java.awt.Image;
|
40 |
import java.awt.event.ActionEvent;
|
41 |
import java.awt.event.ActionEvent;
|
41 |
import java.awt.event.WindowAdapter;
|
42 |
import java.awt.event.WindowAdapter;
|
42 |
import java.awt.event.WindowEvent;
|
43 |
import java.awt.event.WindowEvent;
|
43 |
import java.beans.PropertyChangeEvent;
|
44 |
import java.beans.PropertyChangeEvent;
|
44 |
import java.beans.PropertyChangeListener;
|
45 |
import java.beans.PropertyChangeListener;
|
45 |
import java.io.File;
|
46 |
import java.io.File;
|
- |
|
47 |
import java.lang.reflect.InvocationHandler;
|
- |
|
48 |
import java.lang.reflect.Method;
|
- |
|
49 |
import java.lang.reflect.Proxy;
|
46 |
import java.util.ArrayList;
|
50 |
import java.util.ArrayList;
|
47 |
import java.util.Arrays;
|
51 |
import java.util.Arrays;
|
48 |
import java.util.Collections;
|
52 |
import java.util.Collections;
|
49 |
import java.util.List;
|
53 |
import java.util.List;
|
50 |
|
54 |
|
Line 73... |
Line 77... |
73 |
public static final String LIST_MENU = "menu.list";
|
77 |
public static final String LIST_MENU = "menu.list";
|
74 |
public static final String CREATE_MENU = "menu.create";
|
78 |
public static final String CREATE_MENU = "menu.create";
|
75 |
public static final String FILE_MENU = "menu.file";
|
79 |
public static final String FILE_MENU = "menu.file";
|
76 |
public static final String HELP_MENU = "menu.help";
|
80 |
public static final String HELP_MENU = "menu.help";
|
77 |
|
81 |
|
- |
|
82 |
public static final String PREFS_MENU_ITEM = "preferences";
|
- |
|
83 |
public static final String QUIT_MENU_ITEM = "quit";
|
- |
|
84 |
public static final String ABOUT_MENU_ITEM = "information";
|
- |
|
85 |
|
78 |
static private final List<Runnable> runnables = new ArrayList<Runnable>();
|
86 |
static private final List<Runnable> runnables = new ArrayList<Runnable>();
|
79 |
@GuardedBy("MainFrame")
|
87 |
@GuardedBy("MainFrame")
|
80 |
static private MainFrame instance = null;
|
88 |
static private MainFrame instance = null;
|
81 |
|
89 |
|
82 |
// thread safe
|
90 |
// thread safe
|
Line 183... |
Line 191... |
183 |
this.setMinimumSize(minSize);
|
191 |
this.setMinimumSize(minSize);
|
184 |
|
192 |
|
185 |
final File confFile = new File(conf.getConfDir(), "Configuration" + File.separator + "Frame" + File.separator + "mainFrame" + confSuffix + ".xml");
|
193 |
final File confFile = new File(conf.getConfDir(), "Configuration" + File.separator + "Frame" + File.separator + "mainFrame" + confSuffix + ".xml");
|
186 |
new WindowStateManager(this, confFile).loadState();
|
194 |
new WindowStateManager(this, confFile).loadState();
|
187 |
|
195 |
|
188 |
registerForMacOSXEvents();
|
- |
|
189 |
|
- |
|
190 |
this.addWindowListener(new WindowAdapter() {
|
196 |
this.addWindowListener(new WindowAdapter() {
|
191 |
@Override
|
197 |
@Override
|
192 |
public void windowClosing(WindowEvent arg0) {
|
198 |
public void windowClosing(WindowEvent arg0) {
|
193 |
quit();
|
199 |
quit();
|
194 |
}
|
200 |
}
|
Line 209... |
Line 215... |
209 |
// Overrive logo
|
215 |
// Overrive logo
|
210 |
final Image im = conf instanceof ComptaPropsConfiguration ? ((ComptaPropsConfiguration) conf).getCustomLogo() : null;
|
216 |
final Image im = conf instanceof ComptaPropsConfiguration ? ((ComptaPropsConfiguration) conf).getCustomLogo() : null;
|
211 |
if (im != null) {
|
217 |
if (im != null) {
|
212 |
image.setImage(im);
|
218 |
image.setImage(im);
|
213 |
}
|
219 |
}
|
214 |
new NewsUpdater(this.image);
|
- |
|
- |
|
220 |
|
215 |
}
|
221 |
}
|
216 |
|
222 |
|
217 |
// create the UI menu from the menu manager
|
223 |
// create the UI menu from the MenuAndActions and hide items handled by java.awt.Desktop
|
218 |
public final void initMenuBar() {
|
224 |
public final void initMenuBar() {
|
219 |
final MenuManager mm = MenuManager.getInstance();
|
225 |
final MenuManager mm = MenuManager.getInstance();
|
220 |
final PropertyChangeListener listener = new PropertyChangeListener() {
|
226 |
final PropertyChangeListener listener = new PropertyChangeListener() {
|
221 |
@Override
|
227 |
@Override
|
222 |
public void propertyChange(PropertyChangeEvent evt) {
|
228 |
public void propertyChange(PropertyChangeEvent evt) {
|
Line 380... |
Line 386... |
380 |
if (SwingThreadUtils.getAncestorOrSelf(JMenuBar.class, item) != this.getJMenuBar())
|
386 |
if (SwingThreadUtils.getAncestorOrSelf(JMenuBar.class, item) != this.getJMenuBar())
|
381 |
throw new IllegalArgumentException("Item not in this menu " + item);
|
387 |
throw new IllegalArgumentException("Item not in this menu " + item);
|
382 |
MenuUtils.removeMenuItem(item);
|
388 |
MenuUtils.removeMenuItem(item);
|
383 |
}
|
389 |
}
|
384 |
|
390 |
|
- |
|
391 |
public void registerDesktopEvents(final MenuAndActions menuAndActions) {
|
- |
|
392 |
// First try standard >=9 way, otherwise fall back to com.apple.eawt.Application
|
- |
|
393 |
if (!this.registerAWTDesktopEvents(menuAndActions))
|
- |
|
394 |
this.registerForMacOSXEvents(menuAndActions);
|
- |
|
395 |
}
|
- |
|
396 |
|
- |
|
397 |
private boolean registerAWTDesktopEvents(final MenuAndActions menuAndActions) {
|
- |
|
398 |
if (!Desktop.isDesktopSupported())
|
- |
|
399 |
return false;
|
- |
|
400 |
final Desktop desktop = Desktop.getDesktop();
|
- |
|
401 |
final boolean quitHandled = registerAWTDesktopEvent(desktop, "QuitHandler", "APP_QUIT_HANDLER", menuAndActions, QUIT_MENU_ITEM);
|
- |
|
402 |
final boolean aboutHandled = registerAWTDesktopEvent(desktop, "AboutHandler", "APP_ABOUT", menuAndActions, ABOUT_MENU_ITEM);
|
- |
|
403 |
final boolean prefsHandled = registerAWTDesktopEvent(desktop, "PreferencesHandler", "APP_PREFERENCES", menuAndActions, PREFS_MENU_ITEM);
|
- |
|
404 |
return quitHandled && aboutHandled && prefsHandled;
|
- |
|
405 |
}
|
- |
|
406 |
|
- |
|
407 |
private boolean registerAWTDesktopEvent(final Desktop desktop, final String handlerClassName, final String desktopActionName, final MenuAndActions menuAndActions, final String menuActionName) {
|
- |
|
408 |
final Desktop.Action appPrefsAction;
|
- |
|
409 |
try {
|
- |
|
410 |
appPrefsAction = Desktop.Action.valueOf(desktopActionName);
|
- |
|
411 |
} catch (Exception e) {
|
- |
|
412 |
// JRE <9, fallback to the old way
|
- |
|
413 |
return false;
|
- |
|
414 |
}
|
- |
|
415 |
if (!desktop.isSupported(appPrefsAction)) {
|
- |
|
416 |
// JRE >= 9, but not supported
|
- |
|
417 |
return false;
|
- |
|
418 |
}
|
- |
|
419 |
try {
|
- |
|
420 |
final Class<?> prefHandlerClass = Class.forName("java.awt.desktop." + handlerClassName);
|
- |
|
421 |
final Object prefHandler = Proxy.newProxyInstance(prefHandlerClass.getClassLoader(), new Class<?>[] { prefHandlerClass }, new InvocationHandler() {
|
- |
|
422 |
@Override
|
- |
|
423 |
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
- |
|
424 |
menuAndActions.getAction(menuActionName).actionPerformed(null);
|
- |
|
425 |
return null;
|
- |
|
426 |
}
|
- |
|
427 |
});
|
- |
|
428 |
desktop.getClass().getMethod("set" + handlerClassName, prefHandlerClass).invoke(desktop, prefHandler);
|
- |
|
429 |
menuAndActions.setMenuItemVisible(menuActionName, false);
|
- |
|
430 |
return true;
|
- |
|
431 |
} catch (Exception e) {
|
- |
|
432 |
// Unknown error, still try to fallback to the old way
|
- |
|
433 |
e.printStackTrace();
|
- |
|
434 |
return false;
|
- |
|
435 |
}
|
- |
|
436 |
}
|
- |
|
437 |
|
385 |
// Generic registration with the Mac OS X application menu
|
438 |
// Generic registration with the Mac OS X application menu
|
386 |
// Checks the platform, then attempts to register with the Apple EAWT
|
439 |
// Checks the platform, then attempts to register with the Apple EAWT
|
387 |
// See OSXAdapter.java to see how this is done without directly referencing any Apple APIs
|
440 |
// See OSXAdapter.java to see how this is done without directly referencing any Apple APIs
|
- |
|
441 |
// Remove once depending on Java 11.
|
- |
|
442 |
@Deprecated
|
388 |
public void registerForMacOSXEvents() {
|
443 |
public void registerForMacOSXEvents(final MenuAndActions menuAndActions) {
|
389 |
if (Gestion.MAC_OS_X) {
|
444 |
if (Gestion.MAC_OS_X) {
|
390 |
try {
|
445 |
try {
|
391 |
// Generate and register the OSXAdapter, passing it a hash of all the methods we
|
446 |
// Generate and register the OSXAdapter, passing it a hash of all the methods we
|
392 |
// wish to use as delegates for various com.apple.eawt.ApplicationListener methods
|
447 |
// wish to use as delegates for various com.apple.eawt.ApplicationListener methods
|
393 |
OSXAdapter.setQuitHandler(this, getClass().getDeclaredMethod("quit", new Class[0]));
|
448 |
OSXAdapter.setQuitHandler(this, getClass().getDeclaredMethod("quit", new Class[0]));
|
394 |
OSXAdapter.setAboutHandler(this, getClass().getDeclaredMethod("about", new Class[0]));
|
449 |
OSXAdapter.setAboutHandler(this, getClass().getDeclaredMethod("about", new Class[0]));
|
395 |
OSXAdapter.setPreferencesHandler(this, getClass().getDeclaredMethod("preferences", new Class[0]));
|
450 |
OSXAdapter.setPreferencesHandler(this, getClass().getDeclaredMethod("preferences", new Class[0]));
|
- |
|
451 |
menuAndActions.setMenuItemVisible(QUIT_MENU_ITEM, false);
|
- |
|
452 |
menuAndActions.setMenuItemVisible(ABOUT_MENU_ITEM, false);
|
- |
|
453 |
menuAndActions.setMenuItemVisible(PREFS_MENU_ITEM, false);
|
396 |
// no OSXAdapter.setFileHandler() for now
|
454 |
// no OSXAdapter.setFileHandler() for now
|
397 |
} catch (Exception e) {
|
455 |
} catch (Exception e) {
|
398 |
System.err.println("Error while loading the OSXAdapter:");
|
456 |
System.err.println("Error while loading the OSXAdapter:");
|
399 |
e.printStackTrace();
|
457 |
e.printStackTrace();
|
400 |
}
|
458 |
}
|
401 |
}
|
459 |
}
|
402 |
}
|
460 |
}
|
403 |
|
461 |
|
404 |
// used by OSXAdapter
|
462 |
// used by OSXAdapter
|
- |
|
463 |
@Deprecated
|
405 |
public final void preferences() {
|
464 |
public final void preferences() {
|
406 |
MenuManager.getInstance().getActionForId("preferences").actionPerformed(null);
|
465 |
MenuManager.getInstance().getActionForId(PREFS_MENU_ITEM).actionPerformed(null);
|
407 |
}
|
466 |
}
|
408 |
|
467 |
|
- |
|
468 |
@Deprecated
|
409 |
public final void about() {
|
469 |
public final void about() {
|
410 |
MenuManager.getInstance().getActionForId("information").actionPerformed(null);
|
470 |
MenuManager.getInstance().getActionForId(ABOUT_MENU_ITEM).actionPerformed(null);
|
411 |
}
|
471 |
}
|
412 |
|
472 |
|
413 |
public boolean quit() {
|
473 |
public boolean quit() {
|
414 |
if (this.getTodoPanel() != null)
|
474 |
if (this.getTodoPanel() != null)
|
415 |
this.getTodoPanel().stopUpdate();
|
475 |
this.getTodoPanel().stopUpdate();
|