1 /*
   2  * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.apple.eawt;
  27 
  28 import java.awt.Image;
  29 import java.awt.Point;
  30 import java.awt.PopupMenu;
  31 import java.awt.Toolkit;
  32 import java.awt.Window;
  33 import java.awt.desktop.*;
  34 import java.beans.Beans;
  35 
  36 import javax.swing.JMenuBar;
  37 
  38 import sun.awt.AWTAccessor;
  39 import sun.lwawt.LWWindowPeer;
  40 import sun.lwawt.macosx.CPlatformWindow;
  41 
  42 /**
  43  * The <code>Application</code> class allows you to integrate your Java application with the native Mac OS X environment.
  44  * You can provide your Mac OS X users a greatly enhanced experience by implementing a few basic handlers for standard system events.
  45  *
  46  * For example:
  47  * <ul>
  48  * <li>Open an about dialog when a user chooses About from the application menu.</li>
  49  * <li>Open a preferences window when the users chooses Preferences from the application menu.</li>
  50  * <li>Create a new document when the user clicks on your Dock icon, and no windows are open.</li>
  51  * <li>Open a document that the user double-clicked on in the Finder.</li>
  52  * <li>Open a custom URL scheme when a user clicks on link in a web browser.</li>
  53  * <li>Reconnect to network services after the system has awoke from sleep.</li>
  54  * <li>Cleanly shutdown your application when the user chooses Quit from the application menu, Dock icon, or types Command-Q.</li>
  55  * <li>Cancel shutdown/logout if the user has unsaved changes in your application.</li>
  56  * </ul>
  57  *
  58  * @since 1.4
  59  */
  60 public class Application {
  61     private static native void nativeInitializeApplicationDelegate();
  62 
  63     static Application sApplication = null;
  64 
  65     static {
  66         checkSecurity();
  67         Toolkit.getDefaultToolkit(); // Start AppKit
  68         if (!Beans.isDesignTime()) {
  69             nativeInitializeApplicationDelegate();
  70         }
  71 
  72         sApplication = new Application();
  73     }
  74 
  75     private static void checkSecurity() {
  76         final SecurityManager security = System.getSecurityManager();
  77         if (security == null) return;
  78         security.checkPermission(new RuntimePermission("canProcessApplicationEvents"));
  79     }
  80 
  81     /**
  82      * @return the singleton representing this Mac OS X Application
  83      *
  84      * @since 1.4
  85      */
  86     public static Application getApplication() {
  87         checkSecurity();
  88         return sApplication;
  89     }
  90 
  91     // some singletons, since they get called back into from native
  92     final _AppEventHandler eventHandler = _AppEventHandler.getInstance();
  93     final _AppMenuBarHandler menuBarHandler = _AppMenuBarHandler.getInstance();
  94     final _AppDockIconHandler iconHandler = new _AppDockIconHandler();
  95 
  96     /**
  97      * Creates an Application instance. Should only be used in JavaBean environments.
  98      * @deprecated use {@link #getApplication()}
  99      *
 100      * @since 1.4
 101      */
 102     @Deprecated
 103     public Application() {
 104         checkSecurity();
 105     }
 106 
 107     /**
 108      * Adds sub-types of {@link SystemEventListener} to listen for notifications from the native Mac OS X system.
 109      *
 110      * @see AppForegroundListener
 111      * @see AppHiddenListener
 112      * @see AppReOpenedListener
 113      * @see AppScreenSleepListener
 114      * @see AppSystemSleepListener
 115      * @see AppUserSessionListener
 116      *
 117      * @param listener
 118      * @since Java for Mac OS X 10.6 Update 3
 119      * @since Java for Mac OS X 10.5 Update 8
 120      */
 121     public void addAppEventListener(final SystemEventListener listener) {
 122         eventHandler.addListener(listener);
 123     }
 124 
 125     /**
 126      * Removes sub-types of {@link SystemEventListener} from listening for notifications from the native Mac OS X system.
 127      *
 128      * @see AppForegroundListener
 129      * @see AppHiddenListener
 130      * @see AppReOpenedListener
 131      * @see AppScreenSleepListener
 132      * @see AppSystemSleepListener
 133      * @see AppUserSessionListener
 134      *
 135      * @param listener
 136      * @since Java for Mac OS X 10.6 Update 3
 137      * @since Java for Mac OS X 10.5 Update 8
 138      */
 139     public void removeAppEventListener(final SystemEventListener listener) {
 140         eventHandler.removeListener(listener);
 141     }
 142 
 143     /**
 144      * Installs a handler to show a custom About window for your application.
 145      *
 146      * Setting the {@link AboutHandler} to <code>null</code> reverts it to the default Cocoa About window.
 147      *
 148      * @param aboutHandler the handler to respond to the {@link AboutHandler#handleAbout()} message
 149      * @since Java for Mac OS X 10.6 Update 3
 150      * @since Java for Mac OS X 10.5 Update 8
 151      */
 152     public void setAboutHandler(final AboutHandler aboutHandler) {
 153         eventHandler.aboutDispatcher.setHandler(aboutHandler);
 154     }
 155 
 156     /**
 157      * Installs a handler to create the Preferences menu item in your application's app menu.
 158      *
 159      * Setting the {@link PreferencesHandler} to <code>null</code> will remove the Preferences item from the app menu.
 160      *
 161      * @param preferencesHandler
 162      * @since Java for Mac OS X 10.6 Update 3
 163      * @since Java for Mac OS X 10.5 Update 8
 164      */
 165     public void setPreferencesHandler(final PreferencesHandler preferencesHandler) {
 166         eventHandler.preferencesDispatcher.setHandler(preferencesHandler);
 167     }
 168 
 169     /**
 170      * Installs the handler which is notified when the application is asked to open a list of files.
 171      * The {@link OpenFilesHandler#openFiles(AppEvent.OpenFilesEvent)} notifications are only sent if the Java app is a bundled application, with a <code>CFBundleDocumentTypes</code> array present in it's Info.plist.
 172      * See the <a href="http://developer.apple.com/mac/library/documentation/General/Reference/InfoPlistKeyReference">Info.plist Key Reference</a> for more information about adding a <code>CFBundleDocumentTypes</code> key to your app's Info.plist.
 173      *
 174      * @param openFileHandler
 175      * @since Java for Mac OS X 10.6 Update 3
 176      * @since Java for Mac OS X 10.5 Update 8
 177      */
 178     public void setOpenFileHandler(final OpenFilesHandler openFileHandler) {
 179         eventHandler.openFilesDispatcher.setHandler(openFileHandler);
 180     }
 181 
 182     /**
 183      * Installs the handler which is notified when the application is asked to print a list of files.
 184      * The {@link PrintFilesHandler#printFiles(AppEvent.PrintFilesEvent)} notifications are only sent if the Java app is a bundled application, with a <code>CFBundleDocumentTypes</code> array present in it's Info.plist.
 185      * See the <a href="http://developer.apple.com/mac/library/documentation/General/Reference/InfoPlistKeyReference">Info.plist Key Reference</a> for more information about adding a <code>CFBundleDocumentTypes</code> key to your app's Info.plist.
 186      *
 187      * @param printFileHandler
 188      * @since Java for Mac OS X 10.6 Update 3
 189      * @since Java for Mac OS X 10.5 Update 8
 190      */
 191     public void setPrintFileHandler(final PrintFilesHandler printFileHandler) {
 192         eventHandler.printFilesDispatcher.setHandler(printFileHandler);
 193     }
 194 
 195     /**
 196      * Installs the handler which is notified when the application is asked to open a URL.
 197      * The {@link OpenURIHandler#openURI(AppEvent.OpenURIEvent)} notifications are only sent if the Java app is a bundled application, with a <code>CFBundleURLTypes</code> array present in it's Info.plist.
 198      * See the <a href="http://developer.apple.com/mac/library/documentation/General/Reference/InfoPlistKeyReference">Info.plist Key Reference</a> for more information about adding a <code>CFBundleURLTypes</code> key to your app's Info.plist.
 199      *
 200      * Setting the handler to <code>null</code> causes all {@link OpenURIHandler#openURI(AppEvent.OpenURIEvent)} requests to be enqueued until another handler is set.
 201      *
 202      * @param openURIHandler
 203      * @since Java for Mac OS X 10.6 Update 3
 204      * @since Java for Mac OS X 10.5 Update 8
 205      */
 206     public void setOpenURIHandler(final OpenURIHandler openURIHandler) {
 207         eventHandler.openURIDispatcher.setHandler(openURIHandler);
 208     }
 209 
 210     /**
 211      * Installs the handler which determines if the application should quit.
 212      * The handler is passed a one-shot {@link QuitResponse} which can cancel or proceed with the quit.
 213      * Setting the handler to <code>null</code> causes all quit requests to directly perform the default {@link QuitStrategy}.
 214      *
 215      * @param quitHandler the handler that is called when the application is asked to quit
 216      * @since Java for Mac OS X 10.6 Update 3
 217      * @since Java for Mac OS X 10.5 Update 8
 218      */
 219     public void setQuitHandler(final QuitHandler quitHandler) {
 220         eventHandler.quitDispatcher.setHandler(quitHandler);
 221     }
 222 
 223     /**
 224      * Sets the default strategy used to quit this application. The default is calling SYSTEM_EXIT_0.
 225      *
 226      * The quit strategy can also be set with the "apple.eawt.quitStrategy" system property.
 227      *
 228      * @param strategy the way this application should be shutdown
 229      * @since Java for Mac OS X 10.6 Update 3
 230      * @since Java for Mac OS X 10.5 Update 8
 231      */
 232     public void setQuitStrategy(final QuitStrategy strategy) {
 233         eventHandler.setDefaultQuitStrategy(strategy);
 234     }
 235 
 236     /**
 237      * Enables this application to be suddenly terminated.
 238      *
 239      * Call this method to indicate your application's state is saved, and requires no notification to be terminated.
 240      * Letting your application remain terminatable improves the user experience by avoiding re-paging in your application when it's asked to quit.
 241      *
 242      * <b>Note: enabling sudden termination will allow your application to be quit without notifying your QuitHandler, or running any shutdown hooks.</b>
 243      * User initiated Cmd-Q, logout, restart, or shutdown requests will effectively "kill -KILL" your application.
 244      *
 245      * This call has no effect on Mac OS X versions prior to 10.6.
 246      *
 247      * @see <a href="http://developer.apple.com/mac/library/documentation/cocoa/reference/foundation/Classes/NSProcessInfo_Class">NSProcessInfo class references</a> for more information about Sudden Termination.
 248      * @see Application#disableSuddenTermination()
 249      *
 250      * @since Java for Mac OS X 10.6 Update 3
 251      * @since Java for Mac OS X 10.5 Update 8
 252      */
 253     public void enableSuddenTermination() {
 254         _AppMiscHandlers.enableSuddenTermination();
 255     }
 256 
 257     /**
 258      * Prevents this application from being suddenly terminated.
 259      *
 260      * Call this method to indicate that your application has unsaved state, and may not be terminated without notification.
 261      *
 262      * This call has no effect on Mac OS X versions prior to 10.6.
 263      *
 264      * @see <a href="http://developer.apple.com/mac/library/documentation/cocoa/reference/foundation/Classes/NSProcessInfo_Class">NSProcessInfo class references</a> for more information about Sudden Termination.
 265      * @see Application#enableSuddenTermination()
 266      *
 267      * @since Java for Mac OS X 10.6 Update 3
 268      * @since Java for Mac OS X 10.5 Update 8
 269      */
 270     public void disableSuddenTermination() {
 271         _AppMiscHandlers.disableSuddenTermination();
 272     }
 273 
 274     /**
 275      * Requests this application to move to the foreground.
 276      *
 277      * @param allWindows if all windows of this application should be moved to the foreground, or only the foremost one
 278      *
 279      * @since Java for Mac OS X 10.6 Update 1
 280      * @since Java for Mac OS X 10.5 Update 6 - 1.6, 1.5
 281      */
 282     public void requestForeground(final boolean allWindows) {
 283         _AppMiscHandlers.requestActivation(allWindows);
 284     }
 285 
 286     /**
 287      * Requests user attention to this application (usually through bouncing the Dock icon). Critical
 288      * requests will continue to bounce the Dock icon until the app is activated. An already active
 289      * application requesting attention does nothing.
 290      *
 291      * @param critical if this is an important request
 292      *
 293      * @since Java for Mac OS X 10.6 Update 1
 294      * @since Java for Mac OS X 10.5 Update 6 - 1.6, 1.5
 295      */
 296     public void requestUserAttention(final boolean critical) {
 297         _AppMiscHandlers.requestUserAttention(critical);
 298     }
 299 
 300     /**
 301      * Opens the native help viewer application if a Help Book has been added to the
 302      * application bundler and registered in the Info.plist with CFBundleHelpBookFolder.
 303      *
 304      * See http://developer.apple.com/qa/qa2001/qa1022.html for more information.
 305      *
 306      * @since Java for Mac OS X 10.5 - 1.5
 307      * @since Java for Mac OS X 10.5 Update 1 - 1.6
 308      */
 309     public void openHelpViewer() {
 310         _AppMiscHandlers.openHelpViewer();
 311     }
 312 
 313     /**
 314      * Attaches the contents of the provided PopupMenu to the application's Dock icon.
 315      *
 316      * @param menu the PopupMenu to attach to this application's Dock icon
 317      *
 318      * @since Java for Mac OS X 10.5 - 1.5
 319      * @since Java for Mac OS X 10.5 Update 1 - 1.6
 320      */
 321     public void setDockMenu(final PopupMenu menu) {
 322         iconHandler.setDockMenu(menu);
 323     }
 324 
 325     /**
 326      * @return the PopupMenu used to add items to this application's Dock icon
 327      *
 328      * @since Java for Mac OS X 10.5 - 1.5
 329      * @since Java for Mac OS X 10.5 Update 1 - 1.6
 330      */
 331     public PopupMenu getDockMenu() {
 332         return iconHandler.getDockMenu();
 333     }
 334 
 335     /**
 336      * Changes this application's Dock icon to the provided image.
 337      *
 338      * @param image
 339      *
 340      * @since Java for Mac OS X 10.5 - 1.5
 341      * @since Java for Mac OS X 10.5 Update 1 - 1.6
 342      */
 343     public void setDockIconImage(final Image image) {
 344         iconHandler.setDockIconImage(image);
 345     }
 346 
 347     /**
 348      * Obtains an image of this application's Dock icon.
 349      *
 350      * @return an image of this application's Dock icon
 351      *
 352      * @since Java for Mac OS X 10.5 - 1.5
 353      * @since Java for Mac OS X 10.5 Update 1 - 1.6
 354      */
 355     public Image getDockIconImage() {
 356         return iconHandler.getDockIconImage();
 357     }
 358 
 359     /**
 360      * Affixes a small system provided badge to this application's Dock icon. Usually a number.
 361      *
 362      * @param badge textual label to affix to the Dock icon
 363      *
 364      * @since Java for Mac OS X 10.5 - 1.5
 365      * @since Java for Mac OS X 10.5 Update 1 - 1.6
 366      */
 367     public void setDockIconBadge(final String badge) {
 368         iconHandler.setDockIconBadge(badge);
 369     }
 370     
 371     /**
 372      * Displays a progress bar to this application's Dock icon.
 373      * Acceptable values are from 0 to 100, any other disables progress indication.
 374      *
 375      * @param value progress value
 376      */
 377     public void setDockIconProgress(final int value) {
 378         iconHandler.setDockIconProgress(value);
 379     }
 380 
 381     /**
 382      * Sets the default menu bar to use when there are no active frames.
 383      * Only used when the system property "apple.laf.useScreenMenuBar" is "true", and
 384      * the Aqua Look and Feel is active.
 385      *
 386      * @param menuBar to use when no other frames are active
 387      *
 388      * @since Java for Mac OS X 10.6 Update 1
 389      * @since Java for Mac OS X 10.5 Update 6 - 1.6, 1.5
 390      */
 391     public void setDefaultMenuBar(final JMenuBar menuBar) {
 392         menuBarHandler.setDefaultMenuBar(menuBar);
 393     }
 394 
 395     /**
 396      * Requests that a {@link Window} should animate into or out of full screen mode.
 397      * Only {@link Window}s marked as full screenable by {@link FullScreenUtilities#setWindowCanFullScreen(Window, boolean)} can be toggled.
 398      *
 399      * @param window to animate into or out of full screen mode
 400      *
 401      * @since Java for Mac OS X 10.7 Update 1
 402      */
 403     public void requestToggleFullScreen(final Window window) {
 404         final Object peer = AWTAccessor.getComponentAccessor().getPeer(window);
 405         if (!(peer instanceof LWWindowPeer)) return;
 406         Object platformWindow = ((LWWindowPeer) peer).getPlatformWindow();
 407         if (!(platformWindow instanceof CPlatformWindow)) return;
 408         ((CPlatformWindow)platformWindow).toggleFullScreen();
 409     }
 410 
 411 }