package ch.cyberduck; /* * Copyright (c) 2005 David Kocher. All rights reserved. * http://cyberduck.ch/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * Bug fixes, suggestions and comments should be sent to: * dkocher@cyberduck.ch */ import ch.cyberduck.threading.WindowMainAction; //import ch.cyberduck.ui.cocoa.application.AppKitFunctionsLibrary; //import ch.cyberduck.ui.cocoa.application.NSApplication; //import ch.cyberduck.ui.cocoa.application.NSButton; //import ch.cyberduck.ui.cocoa.application.NSWindow; //import ch.cyberduck.ui.cocoa.threading.WindowMainAction; import org.apache.log4j.Logger; //import org.rococoa.Foundation; //import org.rococoa.ID; import java.util.ArrayList; import java.util.List; /** * @version $Id$ */ public abstract class SheetController extends WindowController implements SheetCallback { private static Logger log = Logger.getLogger(SheetController.class); /** * The controller of the parent window * @uml.property name="parent" * @uml.associationEnd */ protected final WindowController parent; /** * The sheet window must be provided later with #setWindow (usually called when loading the NIB file) * * @param parent The controller of the parent window */ public SheetController(final WindowController parent) { this.parent = parent; } // /** // * Use this if no custom sheet is given (and no NIB file loaded) // * // * @param parent The controller of the parent window // * @param sheet The window to attach as the sheet // */ // public SheetController(final WindowController parent, NSWindow sheet) { // this.parent = parent; //// this.window = sheet; // } /** * @return Null by default, a sheet with no custom NIB */ @Override protected String getBundleName() { return null; } /** * @return The controller of this sheet parent window */ protected WindowController getParentController() { return parent; } // /** // * This must be the target action for any button in the sheet dialog. Will validate the input // * and close the sheet; #sheetDidClose will be called afterwards // * // * @param sender A button in the sheet dialog // */ // @Action // public void closeSheet(final NSButton sender) { // log.debug("closeSheet:" + sender); // if(sender.tag() == DEFAULT_OPTION // || sender.tag() == OTHER_OPTION) { // if(!this.validateInput()) { // AppKitFunctionsLibrary.beep(); // return; // } // } // NSApplication.sharedApplication().endSheet(this.window(), sender.tag()); // } /** * @uml.property name="returncode" */ private int returncode; /** * @return The tag of the button this sheet was dismissed with */ public int returnCode() { return this.returncode; } /** * Check input fields for any errors * * @return true if a valid input has been given */ protected boolean validateInput() { return true; } /** * @param returncode * @param context */ // protected void callback(final int returncode, ID context) { protected void callback(final int returncode, String context) { this.returncode = returncode; this.callback(returncode); // synchronized(parent.window()) { // parent.window().notify(); // } if(!this.isSingleton()) { this.invalidate(); } } /** * */ public void beginSheet() { // Synchronize on parent controller. Only display one sheet at once. synchronized(parent) { if(isMainThread()) { // No need to call invoke on main thread this.beginSheetImpl(); return; } invoke(new WindowMainAction(parent) { public void run() { //Invoke again on main thread beginSheetImpl(); } }, true); // synchronized(parent.window()) { // while(parent.hasSheet()) { // try { // log.debug("Sleeping:waitForSheetDismiss..."); // parent.window().wait(); // log.debug("Awakened:waitForSheetDismiss"); // } // catch(InterruptedException e) { // log.error(e.getMessage()); // } // } // } } } /** * Keep a reference to the sheet to protect it from being * deallocated as a weak reference before the callback from the runtime */ @SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"}) protected static final List<SheetController> sheetRegistry = new ArrayList<SheetController>(); protected void beginSheetImpl() { this.loadBundle(); // parent.window().makeKeyAndOrderFront(null); // NSApplication.sharedApplication().beginSheet(this.window(), //window // parent.window(), // modalForWindow // this.id(), // modalDelegate // Foundation.selector("sheetDidClose:returnCode:contextInfo:"), // null); //context sheetRegistry.add(this); } /** * Called by the runtime after a sheet has been dismissed. Ends any modal session and * sends the returncode to the callback implementation. Also invalidates this controller to be * garbage collected and notifies the lock object * * @param sheet * @param returncode Identifier for the button clicked by the user * @param contextInfo Not used */ public void sheetDidClose_returnCode_contextInfo(final int returncode) { //, ID contextInfo) { //final NSWindow sheet, final int returncode, ID contextInfo) { // sheet.orderOut(null); String contextInfo = ""; this.callback(returncode, contextInfo); sheetRegistry.remove(this); } /** * @return True if the class is a singleton and the object should * not be invlidated upon the sheet is closed * @see #sheetDidClose_returnCode_contextInfo(ch.cyberduck.ui.cocoa.application.NSWindow, int, org.rococoa.ID) */ @Override public boolean isSingleton() { return false; } }