Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Dialog RTL as submitted by Dmitry Natenberg

  • Loading branch information...
commit 45eb906c04390fdae49cd971ff2fc92656d24a31 1 parent bb13c87
unknown authored
View
4 nbproject/genfiles.properties
@@ -1,8 +1,8 @@
-build.xml.data.CRC32=0b4f7456
+build.xml.data.CRC32=29749b2f
build.xml.script.CRC32=cb918ffc
build.xml.stylesheet.CRC32=a56c6a5b@1.45.1
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
-nbproject/build-impl.xml.data.CRC32=0b4f7456
+nbproject/build-impl.xml.data.CRC32=29749b2f
nbproject/build-impl.xml.script.CRC32=6a06ecb7
nbproject/build-impl.xml.stylesheet.CRC32=238281d1@1.45.1
View
8 nbproject/project.xml
@@ -32,6 +32,14 @@
</run-dependency>
</dependency>
<dependency>
+ <code-name-base>org.openide.dialogs</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>7.18.1</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
<code-name-base>org.openide.modules</code-name-base>
<build-prerequisite/>
<compile-dependency/>
View
2  nbproject/suite.properties
@@ -1 +1 @@
-suite.dir=${basedir}/..
+suite.dir=${basedir}/../../APP
View
3  src/META-INF/services/org.openide.DialogDisplayer
@@ -0,0 +1,3 @@
+#-org.netbeans.core.windows.services.DialogDisplayerImpl
+org.nbrtl.dialog.RTLDialogDisplayerImpl
+#position=0
View
106 src/org/nbrtl/dialog/Bundle.properties
@@ -0,0 +1,106 @@
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+#
+# Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
+#
+# Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+# Other names may be trademarks of their respective owners.
+#
+# The contents of this file are subject to the terms of either the GNU
+# General Public License Version 2 only ("GPL") or the Common
+# Development and Distribution License("CDDL") (collectively, the
+# "License"). You may not use this file except in compliance with the
+# License. You can obtain a copy of the License at
+# http://www.netbeans.org/cddl-gplv2.html
+# or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+# specific language governing permissions and limitations under the
+# License. When distributing the software, include this License Header
+# Notice in each file and include the License file at
+# nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the GPL Version 2 section of the License file that
+# accompanied this code. If applicable, add the following below the
+# License Header, with the fields enclosed by brackets [] replaced by
+# your own identifying information:
+# "Portions Copyrighted [year] [name of copyright owner]"
+#
+# Contributor(s):
+#
+# The Original Software is NetBeans. The Initial Developer of the Original
+# Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
+# Microsystems, Inc. All Rights Reserved.
+#
+# If you wish your version of this file to be governed by only the CDDL
+# or only the GPL Version 2, indicate your decision by adding
+# "[Contributor] elects to include this software in this distribution
+# under the [CDDL or GPL Version 2] license." If you do not indicate a
+# single choice of license, a recipient has the option to distribute
+# your version of this file under either the CDDL, the GPL Version 2 or
+# to extend the choice of license to its licensees as provided above.
+# However, if you add GPL Version 2 code and therefore, elected the GPL
+# Version 2 license, then the option applies only if the new code is
+# made subject to such option by the copyright holder.
+
+OpenIDE-Module-Name=RTLDialog
+OpenIDE-Module-Short-Description=Implementation for RTL oriented dialogs support.
+OpenIDE-Module-Long-Description=Provides the DialogDisplayer of the window system part of the APIs.
+
+
+# ButtonBar/ButtonBarButton
+# Common Button labels
+OKButton=\u05d0\u05d9\u05e9\u05d5\u05e8
+CancelButton=\u05d1\u05d9\u05d8\u05d5\u05dc
+CloseButton=\u05e1\u05d2\u05d5\u05e8
+# HelpButton=Help
+YesButton=\u05db\u05df
+NoButton=\u05d0\u05dc
+# ApplyButton=Apply
+DetailsButton=\u05e4\u05e8\u05d8\u05d9\u05dd
+# ButtoBarButoo
+CTL_Button=\u05db\u05e4\u05ea\u05d5\u05e8
+
+# FileSelector
+CTL_FileSelectorOkButton=\u05d0\u05d9\u05e9\u05d5\u05e8
+CTL_FileSelectorCancelButton=\u05d1\u05d9\u05d8\u05d5\u05dc
+ACSD_FileSelectorOkButton=\u05d0\u05d9\u05e9\u05d5\u05e8
+ACSD_FileSelectorCancelButton=\u05d1\u05d9\u05d8\u05d5\u05dc
+ACSD_FileSelectorDialog=\u05d3\u05d9\u05d0\u05dc\u05d5\u05d2 \u05d1\u05d7\u05d9\u05e8\u05ea \u05e7\u05d1\u05e6\u05d9\u05dd
+ACSN_FileSelectorTreeView=\u05ea\u05e6\u05d5\u05d2\u05ea \u05e2\u05e5
+ACSD_FileSelectorTreeView=\u05ea\u05e6\u05d5\u05d2\u05ea \u05e2\u05e5 \u05d1\u05d1\u05d5\u05d7\u05e8 \u05d4\u05e7\u05d1\u05e6\u05d9\u05dd
+
+# NbNodeOperationImpl
+CTL_Customizer_dialog_title=Customizer Dialog
+
+# NbPresenter/MbDialog
+CLOSED_OPTION_CAPTION=\u05e1\u05d2\u05d5\u05e8
+CANCEL_OPTION_CAPTION=\u05d1\u05d8\u05dc
+HELP_OPTION_CAPTION=\u05e2\u05d6\u05e8\u05d4
+NO_OPTION_CAPTION=\u05dc\u05d0
+OK_OPTION_CAPTION=\u05d0\u05d9\u05e9\u05d5\u05e8
+YES_OPTION_CAPTION=\u05db\u05df
+ACS_YES_OPTION_NAME=\u05db\u05df
+ACS_YES_OPTION_DESC=\u05db\u05e4\u05ea\u05d5\u05e8 \u05d4\u05db\u05df
+# - {0} message
+ACSD_ErrorMessage=\u05e9\u05d2\u05d9\u05d0\u05d4: {0}
+ACSD_WarningMessage=\u05d0\u05d6\u05d4\u05e8\u05d4: {0}
+ACSD_QuestionMessage=\u05e9\u05d0\u05dc\u05d4 {0}
+ACSD_InformationMessage=\u05de\u05d9\u05d3\u05e2 {0}
+ACSD_PlainMessage={0}
+
+ACS_CANCEL_OPTION_NAME=\u05d1\u05d9\u05d8\u05d5\u05dc
+ACS_CANCEL_OPTION_DESC=\u05db\u05e4\u05ea\u05d5\u05e8 \u05d1\u05d9\u05d8\u05d5\u05dc
+
+ACS_OK_OPTION_NAME=\u05d0\u05d9\u05e9\u05d5\u05e8
+ACS_OK_OPTION_DESC=\u05db\u05e4\u05ea\u05d5\u05e8 \u05d0\u05d9\u05e9\u05d5\u05e8
+
+ACS_NO_OPTION_NAME=\u05dc\u05d0
+ACS_NO_OPTION_DESC=\u05db\u05e4\u05ea\u05d5\u05e8 \u05d4\u05dc\u05d0
+
+ACS_HELP_OPTION_NAME=\u05e2\u05d6\u05e8\u05d4
+ACS_HELP_OPTION_DESC=\u05db\u05e4\u05ea\u05d5\u05e8 \u05e2\u05d6\u05e8\u05d4
+
+ACS_CLOSED_OPTION_NAME=\u05e1\u05d2\u05d5\u05e8
+ACS_CLOSED_OPTION_DESC=\u05db\u05e4\u05ea\u05d5\u05e8 \u05e1\u05d2\u05d9\u05e8\u05d4
+
+InformationMessage=\u05d4\u05d5\u05d3\u05e2\u05d4
+WarningMessage=\u05d0\u05d6\u05d4\u05e8\u05d4
+ErrorMessage=\u05d4\u05d5\u05d3\u05e2\u05ea \u05e9\u05d2\u05d9\u05d0\u05d4
View
181 src/org/nbrtl/dialog/Constants.java
@@ -0,0 +1,181 @@
+package org.nbrtl.dialog;
+
+
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
+ * Microsystems, Inc. All Rights Reserved.
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ */
+
+
+import java.awt.Dimension;
+import javax.swing.JSplitPane;
+//import org.netbeans.swing.tabcontrol.TabbedContainer;
+import org.openide.windows.TopComponent;
+
+/**
+ * Constants in window system.
+ *
+ * @author Peter Zavadsky
+ */
+public abstract class Constants {
+
+ /** Constant that identifies state of editor area */
+ public static final int EDITOR_AREA_JOINED = 0;
+ public static final int EDITOR_AREA_SEPARATED = 1;
+
+ /** Constant that identifies mode state. */
+ public static final int MODE_STATE_JOINED = 0;
+ public static final int MODE_STATE_SEPARATED = 1;
+
+// /** Constant that identifies mode kind */
+// public static final int MODE_KIND_EDITOR = TabbedContainer.TYPE_EDITOR;
+// public static final int MODE_KIND_VIEW = TabbedContainer.TYPE_VIEW;
+// public static final int MODE_KIND_SLIDING = TabbedContainer.TYPE_SLIDING;
+
+ /** Vertical orientation constant used in constraint. */
+ public static final int VERTICAL = JSplitPane.VERTICAL_SPLIT;
+ /** Horizontal orientation constant used in constraint. */
+ public static final int HORIZONTAL = JSplitPane.HORIZONTAL_SPLIT;
+
+ /** Sides of attaching, used both for regular modes and sliding modes */
+ public static final String TOP = JSplitPane.TOP;
+ public static final String BOTTOM = JSplitPane.BOTTOM;
+ public static final String LEFT = JSplitPane.LEFT;
+ public static final String RIGHT = JSplitPane.RIGHT;
+
+ /** Default value when value is not provided by UIManager */
+ public static final int DIVIDER_SIZE_VERTICAL = 4;
+ /** Default value when value is not provided by UIManager */
+ public static final int DIVIDER_SIZE_HORIZONTAL = 4;
+
+ /** Sets size of drop area (when splitting mode and around area). */
+ public static final int DROP_AREA_SIZE = 20;
+
+ /** How many pixels is necessary to drag to start the DnD. */
+ public static final int DRAG_GESTURE_START_DISTANCE = 10;
+ /** What time inmilliseconds is necessary to hold dragging mouse button for
+ & DnD to be started */
+ public static final int DRAG_GESTURE_START_TIME = 200;
+
+ // DnD drop ratios.
+ /** How big portion of the original mode has to be taken (range from 0.0 to 1.0). */
+ public static final double DROP_TO_SIDE_RATIO = 0.25D;
+ /** How big portion should take the new mode from each one (between which is dropped) (range from 0.0 to 1.0). */
+ public static final double DROP_BETWEEN_RATIO = 1.0D/3;
+ /** How big portion of entire area should take the dropped mode (range from 0.0 to 1.0). */
+ public static final double DROP_AROUND_RATIO = 0.25D;
+
+
+ /** Size of new separated mode when creting during DnD (separeted mode). */
+ public static final Dimension DROP_NEW_MODE_SIZE = new Dimension(300, 200);
+
+
+ /** Name of client property (of Boolean type) which says whether the TopComponent is allowed
+ * to be docked anywhere (even crossing view-editor border). */
+ public static final String TOPCOMPONENT_ALLOW_DOCK_ANYWHERE = "TopComponentAllowDockAnywhere"; // NOI18N
+
+ /** Name of client property (of Boolean type) which says whether position in model
+ * of the TopComponent which is nonpersistent when closed should be kept. */
+ public static final String KEEP_NON_PERSISTENT_TC_IN_MODEL_WHEN_CLOSED = "KeepNonPersistentTCInModelWhenClosed"; // NOI18N
+
+ /**
+ * Name of TopComponent's Boolean client property which forces the window system
+ * to respect TopComponent's preferred size when it is slided-in from left/right/bottom
+ * sliding bar when set to Boolean.TRUE. Otherwise the slided-in TopComponent
+ * will fill the entire width/length of the IDE window (the default behavior).
+ * This switch is intended for tools/palette windows like e.g. color chooser,
+ * tool picker etc.
+ *
+ * @since 6.22
+ */
+ public static final String KEEP_PREFERRED_SIZE_WHEN_SLIDED_IN = TopComponent.PROP_KEEP_PREFERRED_SIZE_WHEN_SLIDED_IN;
+
+ /**
+ * Name of TopComponent's Boolean client property which instructs the window system to activate
+ * the given TopComponent at startup time regardless which TopComponent was active at
+ * shutdown time. So it's usuable for welcome screen-like behavior.
+ * If more than one TopComponent has this property set to Boolean.TRUE then
+ * an arbitrary one will be selected and activated.
+ * @since 6.22
+ */
+ public static final String ACTIVATE_AT_STARTUP = "netbeans.winsys.tc.activate_at_startup"; //NOI18N
+
+ /** Client property to distinguish JWindows/JDialogs used as ui elements
+ * for separate modes - floating windows.
+ */
+ public static final String SEPARATE_WINDOW_PROPERTY = "SeparateWindow";
+
+ // System properties (switches):
+ /** Allows user to move <code>TopComponent</code>S between document and view modes,
+ * which is restricted otherwise. */
+ public static final boolean SWITCH_MODE_ADD_NO_RESTRICT = Boolean.getBoolean("netbeans.winsys.allow.dock.anywhere"); // NOI18N
+ /** Disables DnD of <code>TopComponent</code>S. */
+ public static final boolean SWITCH_DND_DISABLE = Boolean.getBoolean("netbeans.winsys.disable_dnd"); // NOI18N
+ /** During DnD it provides nicer feedback (fading of possible drop), however performance is worsen in that case. */
+ public static final boolean SWITCH_DROP_INDICATION_FADE = Boolean.getBoolean("netbeans.winsys.dndfade.on"); //NOI18N
+ /** Shows the status line at the end of menu bar instead of at the bottom of main window. */
+ public static final boolean SWITCH_STATUSLINE_IN_MENUBAR = Boolean.getBoolean("netbeans.winsys.statusLine.in.menuBar"); // NOI18N
+
+ /** Gets the image resource to be used in the empty editor area. */
+ public static final String SWITCH_IMAGE_SOURCE = System.getProperty("netbeans.winsys.imageSource"); // NOI18N
+
+ // XXX #37999
+ /** For view, do not show emty documents area, i.e. when no document is opened. */
+ public static final boolean SWITCH_HIDE_EMPTY_DOCUMENT_AREA = Boolean.getBoolean("netbeans.winsys.hideEmptyDocArea"); // NOI18N
+
+ /** Allowing complete removal of toolbars. */
+ public static final boolean NO_TOOLBARS = Boolean.getBoolean("netbeans.winsys.no_toolbars"); // NOI18N
+
+ /** File name whose InstanceCookie can contain custom menu bar component.*/
+ public static final String CUSTOM_MENU_BAR_PATH = System.getProperty("netbeans.winsys.menu_bar.path"); // NOI18N
+
+ /** File name whose InstanceCookie can contain custom status line component.*/
+ public static final String CUSTOM_STATUS_LINE_PATH = System.getProperty("netbeans.winsys.status_line.path"); // NOI18N
+
+ /** If set to true the help button will not be shown in the dialogs.*/
+ public static final boolean DO_NOT_SHOW_HELP_IN_DIALOGS = Boolean.getBoolean("netbeans.winsys.no_help_in_dialogs"); // NOI18N
+
+ /** True means automatic iconification/deiconification of all separate frames if main window is iconified/deiconified */
+ public static final boolean AUTO_ICONIFY = Boolean.getBoolean("netbeans.winsys.auto_iconify"); // NOI18N
+
+ private Constants() {}
+}
View
105 src/org/nbrtl/dialog/NbDialog.java
@@ -0,0 +1,105 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
+ * Microsystems, Inc. All Rights Reserved.
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ */
+package org.nbrtl.dialog;
+
+
+import org.openide.DialogDescriptor;
+import org.openide.util.HelpCtx;
+
+import java.awt.*;
+import java.awt.event.ActionListener;
+
+// XXx Before as org.netbeans.core.NbDialog
+
+/** Default implementation of Dialog created from DialogDescriptor.
+*
+* @author Ian Formanek
+*/
+final class NbDialog extends NbPresenter {
+ static final long serialVersionUID =-4508637164126678997L;
+
+ /** Creates a new Dialog from specified DialogDescriptor
+ * @param d The DialogDescriptor to create the dialog from
+ * @param owner Owner of this dialog.
+ */
+ public NbDialog (DialogDescriptor d, Frame owner) {
+ super (d, owner, d.isModal ());
+ }
+
+ /** Creates a new Dialog from specified DialogDescriptor
+ * @param d The DialogDescriptor to create the dialog from
+ * @param owner Owner of this dialog.
+ */
+ public NbDialog (DialogDescriptor d, Dialog owner) {
+ super (d, owner, d.isModal ());
+ }
+
+ /** Geter for help.
+ */
+ @Override
+ protected HelpCtx getHelpCtx () {
+ return ((DialogDescriptor)descriptor).getHelpCtx ();
+ }
+
+ /** Options align.
+ */
+ @Override
+ protected int getOptionsAlign () {
+ return ((DialogDescriptor)descriptor).getOptionsAlign ();
+ }
+
+ /** Getter for button listener or null
+ */
+ @Override
+ protected ActionListener getButtonListener () {
+ return ((DialogDescriptor)descriptor).getButtonListener ();
+ }
+
+ /** Closing options.
+ */
+ @Override
+ protected Object[] getClosingOptions () {
+ return ((DialogDescriptor)descriptor).getClosingOptions ();
+ }
+}
View
1,532 src/org/nbrtl/dialog/NbPresenter.java
@@ -0,0 +1,1532 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun
+ * Microsystems, Inc. All Rights Reserved.
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ */
+package org.nbrtl.dialog;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.ComponentOrientation;
+import java.awt.DefaultKeyboardFocusManager;
+import java.awt.Dialog;
+import java.awt.Dimension;
+import java.awt.EventQueue;
+import java.awt.FlowLayout;
+import java.awt.Frame;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.KeyboardFocusManager;
+import java.awt.Rectangle;
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ComponentListener;
+import java.awt.event.KeyEvent;
+import java.awt.event.WindowListener;
+import java.beans.PropertyChangeListener;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.ResourceBundle;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.GroupLayout;
+import javax.swing.GroupLayout.Alignment;
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.KeyStroke;
+import javax.swing.MenuElement;
+import javax.swing.MenuSelectionManager;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.WindowConstants;
+import javax.swing.event.ChangeListener;
+import javax.swing.plaf.basic.BasicLookAndFeel;
+import javax.swing.plaf.metal.MetalLookAndFeel;
+//import org.netbeans.core.windows.Constants;
+//import org.netbeans.core.windows.Constants;
+import org.openide.DialogDescriptor;
+import org.openide.NotificationLineSupport;
+import org.openide.NotifyDescriptor;
+import org.openide.WizardDescriptor;
+import org.openide.awt.Mnemonics;
+import org.openide.util.ChangeSupport;
+import org.openide.util.HelpCtx;
+import org.openide.util.ImageUtilities;
+import org.openide.util.Lookup;
+import org.openide.util.Mutex;
+import org.openide.util.NbBundle;
+import org.openide.util.RequestProcessor;
+import org.openide.util.Utilities;
+
+// XXX Before as org.netbeans.core.NbPresenter
+/** Default implementation of Dialog created from NotifyDescriptor.
+ *
+ * @author Ian Formanek, Jaroslav Tulach
+ *
+ * edited by Dmitry Natenberg
+ */
+class NbPresenter extends JDialog
+ implements PropertyChangeListener, WindowListener, Mutex.Action<Void>, Comparator<Object> {
+
+ /** variable holding current modal dialog in the system */
+ public static NbPresenter currentModalDialog;
+ private static final ChangeSupport cs = new ChangeSupport(NbPresenter.class);
+ private static Boolean isJava17 = null;
+ protected NotifyDescriptor descriptor;
+ private final JButton stdYesButton = new JButton(NbBundle.getBundle(NbPresenter.class).getString("YES_OPTION_CAPTION")); // NOI18N
+ private final JButton stdNoButton = new JButton(NbBundle.getBundle(NbPresenter.class).getString("NO_OPTION_CAPTION")); // NOI18N
+ private final JButton stdOKButton = new JButton(NbBundle.getBundle(NbPresenter.class).getString("OK_OPTION_CAPTION")); // NOI18N
+ private final JButton stdCancelButton = new JButton(NbBundle.getBundle(NbPresenter.class).getString("CANCEL_OPTION_CAPTION")); // NOI18N
+ private final JButton stdClosedButton = new JButton(NbBundle.getBundle(NbPresenter.class).getString("CLOSED_OPTION_CAPTION")); // NOI18N
+ private final JButton stdHelpButton = new JButton();
+ private final JButton stdDetailButton = new JButton(NbBundle.getBundle(NbPresenter.class).getString("HELP_OPTION_CAPTION")); // NOI18N
+
+ {
+ stdYesButton.setDefaultCapable(true);
+ stdOKButton.setDefaultCapable(true);
+ stdNoButton.setDefaultCapable(false);
+ stdCancelButton.setDefaultCapable(false);
+ stdCancelButton.setVerifyInputWhenFocusTarget(false);
+ stdClosedButton.setDefaultCapable(false);
+ stdHelpButton.setDefaultCapable(false);
+ stdDetailButton.setDefaultCapable(false);
+ Mnemonics.setLocalizedText(stdHelpButton, NbBundle.getBundle(NbPresenter.class).getString("HELP_OPTION_CAPTION")); // NOI18N
+
+ /** Initilizes accessible contexts */
+ initAccessibility();
+ }
+
+ private final static String ESCAPE_COMMAND = "Escape"; // NOI18N
+ private Component currentMessage;
+ private JScrollPane currentScrollPane;
+ private boolean leaf = false;
+ private JPanel currentButtonsPanel;
+ private JLabel notificationLine;
+ private Component[] currentPrimaryButtons;
+ private Component[] currentSecondaryButtons;
+ private static final int MSG_TYPE_ERROR = 1;
+ private static final int MSG_TYPE_WARNING = 2;
+ private static final int MSG_TYPE_INFO = 3;
+ private Color nbErrorForeground;
+ private Color nbWarningForeground;
+ private Color nbInfoForeground;
+ /** useful only for DialogDescriptor */
+ private int currentAlign;
+ private ButtonListener buttonListener;
+ /** Help context to actually associate with the dialog, as it is currently known. */
+ private transient HelpCtx currentHelp = null;
+ /** Used to prevent updateHelp from calling initializeButtons too many times. */
+ private transient boolean haveCalledInitializeButtons = false;
+ static final Logger LOG = Logger.getLogger(NbPresenter.class.getName());
+ static final long serialVersionUID = -4508637164126678997L;
+
+ /** Creates a new Dialog from specified NotifyDescriptor,
+ * with given frame owner.
+ * @param d The NotifyDescriptor to create the dialog from
+ */
+ public NbPresenter(NotifyDescriptor d, Frame owner, boolean modal) {
+ super(owner, d.getTitle(), modal); // modal
+ initialize(d);
+ }
+
+ /** Creates a new Dialog from specified NotifyDescriptor,
+ * with given dialog owner.
+ * @param d The NotifyDescriptor to create the dialog from
+ */
+ public NbPresenter(NotifyDescriptor d, Dialog owner, boolean modal) {
+ super(owner, d.getTitle(), modal); // modal
+ initialize(d);
+ }
+
+ boolean isLeaf() {
+ return leaf;
+ }
+
+ private void initAccessibility() {
+
+ ResourceBundle bundle;
+ bundle = NbBundle.getBundle(NbPresenter.class);
+
+ stdYesButton.getAccessibleContext().setAccessibleName(bundle.getString("ACS_YES_OPTION_NAME")); // NOI18N
+ stdYesButton.getAccessibleContext().setAccessibleDescription(bundle.getString("ACS_YES_OPTION_DESC")); // NOI18N
+
+ stdNoButton.getAccessibleContext().setAccessibleName(bundle.getString("ACS_NO_OPTION_NAME")); // NOI18N
+ stdNoButton.getAccessibleContext().setAccessibleDescription(bundle.getString("ACS_NO_OPTION_DESC")); // NOI18N
+
+ stdOKButton.getAccessibleContext().setAccessibleName(bundle.getString("ACS_OK_OPTION_NAME")); // NOI18N
+ stdOKButton.getAccessibleContext().setAccessibleDescription(bundle.getString("ACS_OK_OPTION_DESC")); // NOI18N
+
+ stdCancelButton.getAccessibleContext().setAccessibleName(bundle.getString("ACS_CANCEL_OPTION_NAME")); // NOI18N
+ stdCancelButton.getAccessibleContext().setAccessibleDescription(bundle.getString("ACS_CANCEL_OPTION_DESC")); // NOI18N
+
+ stdClosedButton.getAccessibleContext().setAccessibleName(bundle.getString("ACS_CLOSED_OPTION_NAME")); // NOI18N
+ stdClosedButton.getAccessibleContext().setAccessibleDescription(bundle.getString("ACS_CLOSED_OPTION_DESC")); // NOI18N
+
+ stdHelpButton.getAccessibleContext().setAccessibleName(bundle.getString("ACS_HELP_OPTION_NAME")); // NOI18N
+ stdHelpButton.getAccessibleContext().setAccessibleDescription(bundle.getString("ACS_HELP_OPTION_DESC")); // NOI18N
+
+ stdDetailButton.getAccessibleContext().setAccessibleName(bundle.getString("ACS_HELP_OPTION_NAME")); // NOI18N
+ stdDetailButton.getAccessibleContext().setAccessibleDescription(bundle.getString("ACS_HELP_OPTION_DESC")); // NOI18N
+ }
+
+ private void initialize(NotifyDescriptor d) {
+ //Optimization related to jdk bug 4393857 - on pre 1.5 jdk's an
+ //extra repaint is caused by the search for an opaque component up
+ //to the component root. Post 1.5, root pane will automatically be
+ //opaque.
+ getRootPane().setOpaque(true);
+
+ if (d instanceof WizardDescriptor) {
+ // #81938: wizard close button shouln't work during finish progress
+ setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
+ } else {
+ // #55273: Dialogs created by DialogDisplayer are not disposed after close
+ setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+ }
+
+ descriptor = d;
+
+ buttonListener = new ButtonListener();
+ // set leaf by DialogDescriptor, NotifyDescriptor is leaf as default
+ leaf = d instanceof DialogDescriptor ? ((DialogDescriptor) d).isLeaf() : true;
+
+ getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
+ KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), ESCAPE_COMMAND);
+ getRootPane().getActionMap().put(ESCAPE_COMMAND, new EscapeAction());
+
+ initializePresenter();
+
+ pack();
+ // a workaround jdkbug#6925473
+ if (isJava17()) {
+ pack();
+ }
+ setBounds(Utilities.findCenterBounds(getSize()));
+ }
+
+ /** Requests focus for <code>currentMessage</code> component.
+ * If it is of <code>JComponent</code> type it tries default focus
+ * request first. */
+ private void requestFocusForMessage() {
+ Component comp = currentMessage;
+
+ if (comp == null) {
+ return;
+ }
+
+ if (!(comp instanceof JComponent)
+ || !((JComponent) comp).requestDefaultFocus()) {
+
+ comp.requestFocus();
+ }
+ }
+
+ private void initializeMessage() {
+ Object newMessage = descriptor.getMessage();
+ // replace only if old and new messages are different
+ if ((currentMessage == null) || !currentMessage.equals(newMessage)) {
+ uninitializeMessage();
+
+ Component toAdd = null;
+
+ if (descriptor.getMessageType() == NotifyDescriptor.PLAIN_MESSAGE
+ && (newMessage instanceof Component)) {
+ // if plain message => use directly the component
+ currentMessage = (Component) newMessage;
+ } else {
+ currentMessage = createOptionPane();
+ }
+ Dimension prefSize = currentMessage.getPreferredSize();
+ final Rectangle screenBounds = Utilities.getUsableScreenBounds();
+
+ if (prefSize.width > screenBounds.width - 100
+ || prefSize.height > screenBounds.height - 100) {
+ currentScrollPane = new JScrollPane() {
+
+ @Override
+ public Dimension getPreferredSize() {
+ Dimension sz = new Dimension(super.getPreferredSize());
+ if (sz.width > screenBounds.width - 100) {
+ sz.width = screenBounds.width * 3 / 4;
+ }
+ if (sz.height > screenBounds.height - 100) {
+ sz.height = screenBounds.height * 3 / 4;
+ }
+ return sz;
+ }
+
+ };
+ currentScrollPane.setViewportView(currentMessage);
+ toAdd = currentScrollPane;
+ } else {
+ toAdd = currentMessage;
+ }
+
+ if (!(descriptor instanceof WizardDescriptor) && descriptor.getNotificationLineSupport() != null) {
+ JPanel enlargedToAdd = new JPanel(new BorderLayout());
+ enlargedToAdd.add(toAdd, BorderLayout.CENTER);
+
+ nbErrorForeground = UIManager.getColor("nb.errorForeground"); //NOI18N
+ if (nbErrorForeground == null) {
+ //nbErrorForeground = new Color(89, 79, 191); // RGB suggested by Bruce in #28466
+ nbErrorForeground = new Color(255, 0, 0); // RGB suggested by jdinga in #65358
+ }
+
+ nbWarningForeground = UIManager.getColor("nb.warningForeground"); //NOI18N
+ if (nbWarningForeground == null) {
+ nbWarningForeground = new Color(51, 51, 51); // Label.foreground
+ }
+
+ nbInfoForeground = UIManager.getColor("nb.warningForeground"); //NOI18N
+ if (nbInfoForeground == null) {
+ nbInfoForeground = UIManager.getColor("Label.foreground"); //NOI18N
+ }
+
+ notificationLine = new FixedHeightLabel();
+ NotificationLineSupport nls = descriptor.getNotificationLineSupport();
+ if (nls.getInformationMessage() != null) {
+ updateNotificationLine(MSG_TYPE_INFO, nls.getInformationMessage());
+ } else if (nls.getWarningMessage() != null) {
+ updateNotificationLine(MSG_TYPE_WARNING, nls.getWarningMessage());
+ } else if (nls.getErrorMessage() != null) {
+ updateNotificationLine(MSG_TYPE_ERROR, nls.getErrorMessage());
+ }
+ JPanel notificationPanel = new JPanel();
+ GroupLayout layout = new GroupLayout(notificationPanel);
+ notificationPanel.setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(Alignment.LEADING).addGroup(layout.createSequentialGroup().addContainerGap().addComponent(notificationLine).addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));
+ layout.setVerticalGroup(
+ layout.createParallelGroup(Alignment.LEADING).addGroup(layout.createSequentialGroup().addContainerGap().addComponent(notificationLine, FixedHeightLabel.ESTIMATED_HEIGHT, FixedHeightLabel.ESTIMATED_HEIGHT, Short.MAX_VALUE).addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));
+ enlargedToAdd.add(notificationPanel, BorderLayout.SOUTH);
+
+ // toAdd is now enlargedToAdd
+ toAdd = enlargedToAdd;
+ }
+
+ getContentPane().add(toAdd, BorderLayout.CENTER);
+ }
+ }
+
+ private static boolean isJava17() {
+ if (isJava17 != null) {
+ return isJava17;
+ }
+ String javaVersion = System.getProperty("java.version", "unknown"); // NOI18N
+ String javaRuntimeName = System.getProperty("java.runtime.name", "unknown"); // NOI18N
+ isJava17 = javaVersion.startsWith("1.7") || javaRuntimeName.startsWith("OpenJDK"); // NOI18N
+ return isJava17;
+ }
+
+ private static final class FixedHeightLabel extends JLabel {
+
+ private static final int ESTIMATED_HEIGHT = 16;
+
+ public FixedHeightLabel() {
+ super();
+ }
+
+ @Override
+ public Dimension getPreferredSize() {
+ Dimension preferredSize = super.getPreferredSize();
+ assert ESTIMATED_HEIGHT == ImageUtilities.loadImage("org/netbeans/core/windows/resources/warning.png").getHeight(null) : "Use only 16px icon.";
+ preferredSize.height = Math.max(ESTIMATED_HEIGHT, preferredSize.height);
+ return preferredSize;
+ }
+
+ }
+
+ private void uninitializeMessage() {
+ if (currentMessage != null) {
+ if (currentScrollPane != null) {
+ getContentPane().remove(currentScrollPane);
+ currentScrollPane = null;
+ } else {
+ getContentPane().remove(currentMessage);
+ }
+ currentMessage = null;
+ }
+ }
+
+ private void initializePresenter() {
+ if (currentMessage != null) {
+ return;
+ }
+
+ initializeMessage();
+
+ updateHelp();
+
+ initializeButtons();
+ haveCalledInitializeButtons = true;
+
+ descriptor.addPropertyChangeListener(this);
+ addWindowListener(this);
+
+ initializeClosingOptions();
+ }
+
+ /** Descriptor can be cached and reused. We need to remove listeners
+ * from descriptor, buttons and disconnect componets from container hierarchy.
+ */
+ private void uninitializePresenter() {
+ descriptor.removePropertyChangeListener(this);
+ uninitializeMessage();
+ uninitializeButtons();
+ uninitializeClosingOptions();
+ }
+
+ private final HackTypeAhead hack = new HackTypeAhead();
+
+ @Override
+ public void addNotify() {
+ super.addNotify();
+ initializePresenter();
+
+ hack.activate();
+ }
+
+ @Override
+ public void removeNotify() {
+ super.removeNotify();
+ uninitializePresenter();
+
+ }
+
+ /** Creates option pane message.
+ */
+ private JOptionPane createOptionPane() {
+ Object msg = descriptor.getMessage();
+ boolean override = true;
+ String strMsg = null, strMsgLower;
+
+ if (msg instanceof String) {
+ msg = ((String) msg).replace("\t", " "); // NOI18N
+ msg = ((String) msg).replace("\r", ""); // NOI18N
+ //If string is html text (contains "<html>" or "<HTML>")
+ //we will not override JOptionPane.getMaxCharactersPerLineCount
+ //so that html text will be displayed correctly in JOptionPane
+ strMsg = (String) msg;
+ strMsgLower = strMsg.toLowerCase();
+ override = !strMsgLower.startsWith("<html>"); // NOI18N
+ }
+ if (msg instanceof javax.accessibility.Accessible) {
+ strMsg = ((javax.accessibility.Accessible) msg).getAccessibleContext().getAccessibleDescription();
+ }
+
+ JOptionPane optionPane;
+ if (override) {
+ // initialize component (override max char count per line in a message)
+ optionPane = new JOptionPane(
+ msg,
+ descriptor.getMessageType(),
+ 0, // options type
+ null, // icon
+ new Object[0], // options
+ null // value
+ ) {
+
+ @Override
+ public int getMaxCharactersPerLineCount() {
+ return 100;
+ }
+
+ };
+ } else {
+ //Do not override JOptionPane.getMaxCharactersPerLineCount for html text
+ optionPane = new JOptionPane(
+ msg,
+ descriptor.getMessageType(),
+ 0, // options type
+ null, // icon
+ new Object[0], // options
+ null // value
+ );
+ }
+
+ if (UIManager.getLookAndFeel().getClass() == MetalLookAndFeel.class
+ || UIManager.getLookAndFeel().getClass() == BasicLookAndFeel.class) {
+ optionPane.setUI(new javax.swing.plaf.basic.BasicOptionPaneUI() {
+
+ @Override
+ public Dimension getMinimumOptionPaneSize() {
+ if (minimumSize == null) {
+ //minimumSize = UIManager.getDimension("OptionPane.minimumSize");
+ // this is called before defaults initialized?!!!
+ return new Dimension(MinimumWidth, 50);
+ }
+ return new Dimension(minimumSize.width, 50);
+ }
+
+ });
+ }
+ optionPane.setWantsInput(false);
+ optionPane.getAccessibleContext().setAccessibleDescription(strMsg);
+
+//RTL added
+ optionPane.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
+ return optionPane;
+ }
+
+ private void uninitializeButtons() {
+ if (currentButtonsPanel != null) {
+ if (currentPrimaryButtons != null) {
+ for (int i = 0; i < currentPrimaryButtons.length; i++) {
+ modifyListener(currentPrimaryButtons[i], buttonListener, false);
+ }
+ }
+ if (currentSecondaryButtons != null) {
+ for (int i = 0; i < currentSecondaryButtons.length; i++) {
+ modifyListener(currentSecondaryButtons[i], buttonListener, false);
+ }
+ }
+
+ getContentPane().remove(currentButtonsPanel);
+ currentButtonsPanel = null;
+ }
+ }
+
+ private void initializeClosingOptions(boolean init) {
+ Object[] options = getClosingOptions();
+
+ if (options == null) {
+ return;
+ }
+ for (int i = 0; i < options.length; i++) {
+ modifyListener(options[i], buttonListener, init);
+ }
+ }
+
+ private void initializeClosingOptions() {
+ initializeClosingOptions(true);
+ }
+
+ private void uninitializeClosingOptions() {
+ initializeClosingOptions(false);
+ }
+
+ /**
+ * On Aqua look and feel, options should be sorted such that the default
+ * button is always rightmost, and 'yes' options appear to thr right of
+ * 'no' options.
+ */
+ @Override
+ public int compare(Object a, Object b) {
+ boolean isDefaultButton = a.equals(descriptor.getDefaultValue());
+ int result;
+ if (a.equals(NotifyDescriptor.OK_OPTION) || a.equals(NotifyDescriptor.YES_OPTION)) {
+ result = 1;
+ } else {
+ result = 0;
+ }
+
+ if (isDefaultButton) {
+ result++;
+ }
+ return result;
+ }
+
+ protected final void initializeButtons() {
+ // -----------------------------------------------------------------------------
+ // If there were any buttons previously, remove them and removeActionListener from them
+
+ Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
+
+ boolean dontShowHelp = Constants.DO_NOT_SHOW_HELP_IN_DIALOGS
+ || (descriptor instanceof WizardDescriptor && (Boolean.FALSE.equals(((WizardDescriptor) descriptor).getProperty(WizardDescriptor.PROP_HELP_DISPLAYED)))); // NOI18N
+ boolean helpButtonShown =
+ stdHelpButton.isShowing() || (descriptor instanceof WizardDescriptor && !dontShowHelp);
+
+
+ uninitializeButtons();
+
+ Object[] primaryOptions = descriptor.getOptions();
+ Object[] secondaryOptions = descriptor.getAdditionalOptions();
+ currentAlign = getOptionsAlign();
+
+ // -----------------------------------------------------------------------------
+ // Obtain main (primary) and additional (secondary) buttons
+
+ currentPrimaryButtons = null;
+ currentSecondaryButtons = null;
+
+ boolean isAqua = "Aqua".equals(UIManager.getLookAndFeel().getID()) || //NOI18N
+ "true".equalsIgnoreCase(System.getProperty("xtest.looks_as_mac"));
+ if (isAqua) {
+ //No mac dialogs with buttons on side
+ currentAlign = DialogDescriptor.BOTTOM_ALIGN;
+ }
+
+ // explicitly provided options (AKA buttons)
+ // JST: The following line causes only problems,
+ // I hope that my change will not cause additional ones ;-)
+ // if (descriptor.getOptionType () == NotifyDescriptor.DEFAULT_OPTION) {
+ if (primaryOptions != null) {
+ if (isAqua) {
+ Arrays.sort(primaryOptions, this);
+ }
+ currentPrimaryButtons = new Component[primaryOptions.length];
+ for (int i = 0; i < primaryOptions.length; i++) {
+ if (primaryOptions[i] == NotifyDescriptor.YES_OPTION) {
+ currentPrimaryButtons[i] = stdYesButton;
+ } else if (primaryOptions[i] == NotifyDescriptor.NO_OPTION) {
+ currentPrimaryButtons[i] = stdNoButton;
+ } else if (primaryOptions[i] == NotifyDescriptor.OK_OPTION) {
+ currentPrimaryButtons[i] = stdOKButton;
+ stdOKButton.setEnabled(descriptor.isValid());
+ } else if (primaryOptions[i] == NotifyDescriptor.CANCEL_OPTION) {
+ currentPrimaryButtons[i] = stdCancelButton;
+ } else if (primaryOptions[i] == NotifyDescriptor.CLOSED_OPTION) {
+ currentPrimaryButtons[i] = stdClosedButton;
+ } else if (primaryOptions[i] instanceof Component) {
+ currentPrimaryButtons[i] = (Component) primaryOptions[i];
+ } else if (primaryOptions[i] instanceof Icon) {
+ JButton button = new JButton((Icon) primaryOptions[i]);
+ // ??? Why cannot be default capable ?
+ button.setDefaultCapable(false);
+ currentPrimaryButtons[i] = button;
+ } else {
+ JButton button = new JButton();
+ Mnemonics.setLocalizedText(button, primaryOptions[i].toString());
+ button.setDefaultCapable(primaryOptions[i].equals(descriptor.getDefaultValue()));
+ currentPrimaryButtons[i] = button;
+ }
+ }
+ } else { // predefined option types
+ switch (descriptor.getOptionType()) {
+ case NotifyDescriptor.YES_NO_OPTION:
+ if (isAqua) {
+ currentPrimaryButtons = new Component[2];
+ currentPrimaryButtons[0] = stdNoButton;
+ currentPrimaryButtons[1] = stdYesButton;
+ } else {
+ currentPrimaryButtons = new Component[2];
+ currentPrimaryButtons[0] = stdYesButton;
+ currentPrimaryButtons[1] = stdNoButton;
+ }
+ break;
+ case NotifyDescriptor.YES_NO_CANCEL_OPTION:
+ currentPrimaryButtons = new Component[3];
+ if (isAqua) {
+ currentPrimaryButtons[0] = stdCancelButton;
+ currentPrimaryButtons[1] = stdNoButton;
+ currentPrimaryButtons[2] = stdYesButton;
+ } else {
+ currentPrimaryButtons[0] = stdYesButton;
+ currentPrimaryButtons[1] = stdNoButton;
+ currentPrimaryButtons[2] = stdCancelButton;
+ }
+ break;
+ case NotifyDescriptor.OK_CANCEL_OPTION:
+ default:
+ if (isAqua) {
+ currentPrimaryButtons = new Component[2];
+ currentPrimaryButtons[0] = stdCancelButton;
+ currentPrimaryButtons[1] = stdOKButton;
+ } else {
+ currentPrimaryButtons = new Component[2];
+ currentPrimaryButtons[0] = stdOKButton;
+ currentPrimaryButtons[1] = stdCancelButton;
+ }
+ stdOKButton.setEnabled(descriptor.isValid());
+ break;
+ }
+ }
+
+ // Automatically add a help button if needed.
+
+ if (!dontShowHelp && (currentHelp != null || helpButtonShown)) {
+ if (currentPrimaryButtons == null) {
+ currentPrimaryButtons = new Component[]{};
+ }
+ Component[] cPB2 = new Component[currentPrimaryButtons.length + 1];
+ if (isAqua) { //NOI18N
+ //Mac default dlg button should be rightmost, not the help button
+ System.arraycopy(currentPrimaryButtons, 0, cPB2, 1, currentPrimaryButtons.length);
+ cPB2[0] = stdHelpButton;
+ } else {
+ System.arraycopy(currentPrimaryButtons, 0, cPB2, 0, currentPrimaryButtons.length);
+ cPB2[currentPrimaryButtons.length] = stdHelpButton;
+ }
+ currentPrimaryButtons = cPB2;
+
+ stdHelpButton.setEnabled(currentHelp != null);
+ }
+
+ if ((secondaryOptions != null) && (secondaryOptions.length != 0)) {
+ currentSecondaryButtons = new Component[secondaryOptions.length];
+ Arrays.sort(secondaryOptions, this);
+ for (int i = 0; i < secondaryOptions.length; i++) {
+ if (secondaryOptions[i] == NotifyDescriptor.YES_OPTION) {
+ currentSecondaryButtons[i] = stdYesButton;
+ } else if (secondaryOptions[i] == NotifyDescriptor.NO_OPTION) {
+ currentSecondaryButtons[i] = stdNoButton;
+ } else if (secondaryOptions[i] == NotifyDescriptor.OK_OPTION) {
+ currentSecondaryButtons[i] = stdOKButton;
+ stdOKButton.setEnabled(descriptor.isValid());
+ } else if (secondaryOptions[i] == NotifyDescriptor.CANCEL_OPTION) {
+ currentSecondaryButtons[i] = stdCancelButton;
+ } else if (secondaryOptions[i] == NotifyDescriptor.CLOSED_OPTION) {
+ currentSecondaryButtons[i] = stdClosedButton;
+ } else if (secondaryOptions[i] instanceof Component) {
+ currentSecondaryButtons[i] = (Component) secondaryOptions[i];
+ } else if (secondaryOptions[i] instanceof Icon) {
+ JButton button = new JButton((Icon) secondaryOptions[i]);
+ currentSecondaryButtons[i] = button;
+ } else {
+ JButton button = new JButton();
+ Mnemonics.setLocalizedText(button, secondaryOptions[i].toString());
+ currentSecondaryButtons[i] = button;
+ }
+ }
+ }
+
+ // -----------------------------------------------------------------------------
+ // Create panels for main (primary) and additional (secondary) buttons and add to content pane
+
+ if (currentAlign == DialogDescriptor.BOTTOM_ALIGN || currentAlign == -1) {
+
+ JPanel panelForPrimary = null;
+ JPanel panelForSecondary = null;
+
+
+ if (currentPrimaryButtons != null) {
+ panelForPrimary = new JPanel();
+
+ if (currentAlign == -1) {
+ panelForPrimary.setLayout(new org.openide.awt.EqualFlowLayout());
+ } else {
+//RTL added
+// panelForPrimary.setLayout(new org.openide.awt.EqualFlowLayout(FlowLayout.RIGHT));
+ panelForPrimary.setLayout(new org.openide.awt.EqualFlowLayout(FlowLayout.LEFT));
+ }
+ for (int i = 0; i < currentPrimaryButtons.length; i++) {
+ modifyListener(currentPrimaryButtons[i], buttonListener, true); // add button listener
+ panelForPrimary.add(currentPrimaryButtons[i]);
+ }
+ }
+
+ if (currentSecondaryButtons != null) {
+ panelForSecondary = new JPanel();
+//RTL added
+// panelForSecondary.setLayout(new org.openide.awt.EqualFlowLayout(FlowLayout.LEFT));
+ panelForSecondary.setLayout(new org.openide.awt.EqualFlowLayout(FlowLayout.RIGHT));
+ for (int i = 0; i < currentSecondaryButtons.length; i++) {
+ modifyListener(currentSecondaryButtons[i], buttonListener, true); // add button listener
+ panelForSecondary.add(currentSecondaryButtons[i]);
+ }
+ }
+
+ // both primary and secondary buttons are used
+ if ((panelForPrimary != null) && (panelForSecondary != null)) {
+ currentButtonsPanel = new JPanel();
+ currentButtonsPanel.setLayout(new BorderLayout());
+//RTL added
+// currentButtonsPanel.add(panelForPrimary, BorderLayout.EAST);
+// currentButtonsPanel.add(panelForSecondary, BorderLayout.WEST);
+ currentButtonsPanel.add(panelForPrimary, BorderLayout.WEST);
+ currentButtonsPanel.add(panelForSecondary, BorderLayout.EAST);
+ } else if (panelForPrimary != null) {
+ currentButtonsPanel = panelForPrimary;
+ } else {
+ currentButtonsPanel = panelForSecondary;
+ }
+
+ // add final button panel to the dialog
+ if ((currentButtonsPanel != null) && (currentButtonsPanel.getComponentCount() != 0)) {
+ if (currentButtonsPanel.getBorder() == null) {
+ currentButtonsPanel.setBorder(new javax.swing.border.EmptyBorder(new java.awt.Insets(11, 6, 5, 5)));
+ }
+ getContentPane().add(currentButtonsPanel, BorderLayout.SOUTH);
+ }
+
+ } else if (currentAlign == DialogDescriptor.RIGHT_ALIGN) {
+ currentButtonsPanel = new JPanel();
+ currentButtonsPanel.setLayout(new GridBagLayout());
+ GridBagConstraints gbc = new GridBagConstraints();
+ gbc.gridwidth = GridBagConstraints.REMAINDER;
+ gbc.weightx = 1.0f;
+ gbc.insets = new Insets(5, 4, 2, 5);
+ gbc.fill = GridBagConstraints.HORIZONTAL;
+
+ if (currentPrimaryButtons != null) {
+ for (int i = 0; i < currentPrimaryButtons.length; i++) {
+ modifyListener(currentPrimaryButtons[i], buttonListener, true); // add button listener
+ currentButtonsPanel.add(currentPrimaryButtons[i], gbc);
+ }
+ }
+
+ GridBagConstraints padding = new GridBagConstraints();
+ padding.gridwidth = GridBagConstraints.REMAINDER;
+ padding.weightx = 1.0f;
+ padding.weighty = 1.0f;
+ padding.fill = GridBagConstraints.BOTH;
+ currentButtonsPanel.add(new JPanel(), padding);
+
+ gbc.insets = new Insets(2, 4, 5, 5);
+ if (currentSecondaryButtons != null) {
+ for (int i = 0; i < currentSecondaryButtons.length; i++) {
+ modifyListener(currentSecondaryButtons[i], buttonListener, true); // add button listener
+ currentButtonsPanel.add(currentSecondaryButtons[i], gbc);
+ }
+ }
+
+ // add final button panel to the dialog
+ if (currentButtonsPanel != null) {
+ if (currentButtonsPanel.getBorder() == null) {
+ currentButtonsPanel.setBorder(new javax.swing.border.EmptyBorder(new java.awt.Insets(6, 7, 5, 5)));
+ }
+ getContentPane().add(currentButtonsPanel, BorderLayout.EAST);
+ }
+
+ }
+ updateDefaultButton();
+
+//RTL added
+ getContentPane().setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
+
+
+
+ Component fo = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
+
+ if (fo != focusOwner && focusOwner != null) {
+ focusOwner.requestFocus();
+ }
+ }
+
+ /** Checks default button and updates it
+ */
+ private void updateDefaultButton() {
+ // bugfix 37083, respects DialogDescriptor's initial value ?
+ if (descriptor.getDefaultValue() != null) {
+ if (descriptor.getDefaultValue() instanceof JButton) {
+ JButton b = (JButton) descriptor.getDefaultValue();
+ if (b.isVisible() && b.isEnabled() && b.isDefaultCapable()) {
+ getRootPane().setDefaultButton(b);
+ return;
+ }
+ } else {
+ JButton b = null;
+ Collection<Component> currentActive = new HashSet<Component>();
+ if (currentPrimaryButtons != null) {
+ currentActive.addAll(Arrays.asList(currentPrimaryButtons));
+ }
+ if (currentSecondaryButtons != null) {
+ currentActive.addAll(Arrays.asList(currentSecondaryButtons));
+ }
+ Arrays.asList(currentPrimaryButtons);
+ if (descriptor.getDefaultValue().equals(NotifyDescriptor.OK_OPTION) && currentActive.contains(stdOKButton)) {
+ b = stdOKButton;
+ } else if (descriptor.getDefaultValue().equals(NotifyDescriptor.YES_OPTION) && currentActive.contains(stdYesButton)) {
+ b = stdYesButton;
+ } else if (descriptor.getDefaultValue().equals(NotifyDescriptor.NO_OPTION)) {
+ b = stdNoButton;
+ } else if (descriptor.getDefaultValue().equals(NotifyDescriptor.CANCEL_OPTION)) {
+ b = stdCancelButton;
+ } else if (descriptor.getDefaultValue().equals(NotifyDescriptor.CLOSED_OPTION)) {
+ b = stdClosedButton;
+ }
+ if (b != null && b.isVisible() && b.isEnabled()) {
+ getRootPane().setDefaultButton(b);
+ return;
+ }
+ }
+ } else {
+ // ??? unset default button if descriptor.getValue() is null
+ }
+ if (currentPrimaryButtons != null) {
+ // finds default button
+ for (int i = 0; i < currentPrimaryButtons.length; i++) {
+ if (currentPrimaryButtons[i] instanceof JButton) {
+ JButton b = (JButton) currentPrimaryButtons[i];
+ if (b.isVisible() && b.isEnabled() && b.isDefaultCapable()) {
+ getRootPane().setDefaultButton(b);
+ return;
+ }
+ }
+ }
+ }
+ // no default capable button found
+ getRootPane().setDefaultButton(null);
+ }
+
+ private void updateNotificationLine(int msgType, Object o) {
+ String msg = o == null ? null : o.toString();
+ if (msg != null && msg.trim().length() > 0) {
+ switch (msgType) {
+ case MSG_TYPE_ERROR:
+ prepareMessage(notificationLine, ImageUtilities.loadImageIcon("org/netbeans/core/windows/resources/error.png", false),
+ nbErrorForeground);
+ break;
+ case MSG_TYPE_WARNING:
+ prepareMessage(notificationLine, ImageUtilities.loadImageIcon("org/netbeans/core/windows/resources/warning.png", false),
+ nbWarningForeground);
+ break;
+ case MSG_TYPE_INFO:
+ prepareMessage(notificationLine, ImageUtilities.loadImageIcon("org/netbeans/core/windows/resources/info.png", false),
+ nbInfoForeground);
+ break;
+ default:
+ }
+ notificationLine.setToolTipText(msg);
+ } else {
+ prepareMessage(notificationLine, null, null);
+ notificationLine.setToolTipText(null);
+ }
+ notificationLine.setText(msg);
+ }
+
+ private void prepareMessage(JLabel label, ImageIcon icon, Color fgColor) {
+ label.setIcon(icon);
+ label.setForeground(fgColor);
+ }
+
+ /** Enables/disables OK button if it is present
+ */
+ private void updateOKButton(boolean valid) {
+ if (currentPrimaryButtons != null) {
+ for (int i = 0; i < currentPrimaryButtons.length; i++) {
+ if (currentPrimaryButtons[i] instanceof JButton) {
+ JButton b = (JButton) currentPrimaryButtons[i];
+ if ((b == stdOKButton) && b.isVisible()) {
+ b.setEnabled(valid);
+ }
+ }
+ }
+ }
+ if (currentSecondaryButtons != null) {
+ for (int i = 0; i < currentSecondaryButtons.length; i++) {
+ if (currentSecondaryButtons[i] instanceof JButton) {
+ JButton b = (JButton) currentSecondaryButtons[i];
+ if ((b == stdOKButton) && b.isVisible()) {
+ b.setEnabled(valid);
+ }
+ }
+ }
+ }
+ }
+
+ private void modifyListener(Object comp, ButtonListener l, boolean add) {
+ // on JButtons attach simply by method call
+ if (comp instanceof JButton) {
+ JButton b = (JButton) comp;
+ if (add) {
+ List listeners;
+ listeners = Arrays.asList(b.getActionListeners());
+ if (!listeners.contains(l)) {
+ b.addActionListener(l);
+ }
+ listeners = Arrays.asList(b.getComponentListeners());
+ if (!listeners.contains(l)) {
+ b.addComponentListener(l);
+ }
+ listeners = Arrays.asList(b.getPropertyChangeListeners());
+ if (!listeners.contains(l)) {
+ b.addPropertyChangeListener(l);
+ }
+ } else {
+ b.removeActionListener(l);
+ b.removeComponentListener(l);
+ b.removePropertyChangeListener(l);
+ }
+ return;
+ } else {
+ // we will have to use dynamic method invocation to add the action listener
+ // to generic component (and we succeed only if it has the addActionListener method)
+ java.lang.reflect.Method m = null;
+ try {
+ m = comp.getClass().getMethod(add ? "addActionListener" : "removeActionListener", new Class[]{ActionListener.class});// NOI18N
+ try {
+ m.setAccessible(true);
+ } catch (SecurityException se) {
+ m = null; // no jo, we cannot make accessible
+ }
+ } catch (NoSuchMethodException e) {
+ m = null; // no jo, we cannot attach ActionListener to this Component
+ } catch (SecurityException e2) {
+ m = null; // no jo, we cannot attach ActionListener to this Component
+ }
+ if (m != null) {
+ try {
+ m.invoke(comp, new Object[]{l});
+ } catch (Exception e) {
+ // not succeeded, so give up
+ }
+ }
+ }
+ }
+
+ /** Shows the dialog, used in method show so no inner class is needed.
+ */
+ private void superShow() {
+ assert SwingUtilities.isEventDispatchThread() : "Invoked super.show() in AWT event thread."; // NOI18N
+ super.show();
+ }
+
+ @Override
+ @Deprecated
+ public void show() {
+ //Bugfix #29993: Call show() asynchronously for non modal dialogs.
+ if (isModal()) {
+ Mutex.EVENT.readAccess(this);
+ } else {
+ if (SwingUtilities.isEventDispatchThread()) {
+ doShow();
+ } else {
+ SwingUtilities.invokeLater(new Runnable() {
+
+ @Override
+ public void run() {
+ doShow();
+ }
+
+ });
+ }
+ }
+ }
+
+ @Override
+ public Void run() {
+ doShow();
+ return null;
+ }
+
+ private void doShow() {
+ NbPresenter prev = null;
+ if (isModal()) {
+ prev = currentModalDialog;
+ currentModalDialog = this;
+ fireChangeEvent();
+ }
+
+ superShow();
+
+ if (currentModalDialog != prev) {
+ currentModalDialog = prev;
+ fireChangeEvent();
+ }
+ }
+
+ @Override
+ public void propertyChange(final java.beans.PropertyChangeEvent evt) {
+ if (!SwingUtilities.isEventDispatchThread()) {
+ SwingUtilities.invokeLater(new Runnable() {
+
+ @Override
+ public void run() {
+ propertyChange(evt);
+ }
+
+ });
+ return;
+ }
+ boolean update = false;
+
+ if (DialogDescriptor.PROP_OPTIONS.equals(evt.getPropertyName())) {
+ initializeButtons();
+ update = true;
+ } else if (DialogDescriptor.PROP_OPTION_TYPE.equals(evt.getPropertyName())) {
+ initializeButtons();
+ update = true;
+ } else if (DialogDescriptor.PROP_OPTIONS_ALIGN.equals(evt.getPropertyName())) {
+ initializeButtons();
+ update = true;
+ } else if (DialogDescriptor.PROP_MESSAGE.equals(evt.getPropertyName())) {
+ initializeMessage();
+ requestFocusForMessage();
+ // In case change of help ID on component message:
+ updateHelp();
+ update = true;
+ } else if (DialogDescriptor.PROP_MESSAGE_TYPE.equals(evt.getPropertyName())) {
+ initializeMessage();
+ requestFocusForMessage();
+ update = true;
+ } else if (DialogDescriptor.PROP_TITLE.equals(evt.getPropertyName())) {
+ setTitle(descriptor.getTitle());
+ } else if (DialogDescriptor.PROP_HELP_CTX.equals(evt.getPropertyName())) {
+ // bugfix #40057, restore focus owner after help update
+ Component fo = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
+ updateHelp();
+ // In case buttons have changed: //just buttons!!
+ // note, currentButtonsPanel may be null
+ if (currentButtonsPanel != null) {
+ currentButtonsPanel.revalidate();
+ }
+ if (currentButtonsPanel != null) {
+ currentButtonsPanel.repaint();
+ }
+ if (fo != null) {
+ fo.requestFocus();
+ }
+ } else if (DialogDescriptor.PROP_VALID.equals(evt.getPropertyName())) {
+ updateOKButton(((Boolean) (evt.getNewValue())).booleanValue());
+ } else if (NotifyDescriptor.PROP_INFO_NOTIFICATION.equals(evt.getPropertyName())) {
+ // XXX: need set update on true?
+ updateNotificationLine(MSG_TYPE_INFO, evt.getNewValue());
+ } else if (NotifyDescriptor.PROP_WARNING_NOTIFICATION.equals(evt.getPropertyName())) {
+ // XXX: need set update on true?
+ updateNotificationLine(MSG_TYPE_WARNING, evt.getNewValue());
+ } else if (NotifyDescriptor.PROP_ERROR_NOTIFICATION.equals(evt.getPropertyName())) {
+ // XXX: need set update on true?
+ updateNotificationLine(MSG_TYPE_ERROR, evt.getNewValue());
+ }
+
+ if (update) {
+ Dimension sz = getSize();
+ Dimension prefSize = getPreferredSize();
+ if (prefSize.width > sz.width || prefSize.height > sz.height) {
+ setSize(Math.max(prefSize.width, sz.width),
+ Math.max(prefSize.height, sz.height));
+ }
+
+ validate();
+ repaint();
+ }
+ }
+
+ private void updateHelp() {
+ //System.err.println ("Updating help for NbDialog...");
+ HelpCtx help = getHelpCtx();
+ // Handle help from the inner component automatically (see docs
+ // in DialogDescriptor):
+ if (HelpCtx.DEFAULT_HELP.equals(help)) {
+ Object msg = descriptor.getMessage();
+ if (msg instanceof Component) {
+ help = HelpCtx.findHelp((Component) msg);
+ }
+ if (HelpCtx.DEFAULT_HELP.equals(help)) {
+ help = null;
+ }
+ }
+ if (!Utilities.compareObjects(currentHelp, help)) {
+ currentHelp = help;
+ if (help != null && help.getHelpID() != null) {
+ //System.err.println ("New help ID for root pane: " + help.getHelpID ());
+ HelpCtx.setHelpIDString(getRootPane(), help.getHelpID());
+ }
+ // Refresh button list if it had already been created.
+ if (haveCalledInitializeButtons) {
+ initializeButtons();
+ }
+ }
+ }
+
+ /** Options align.
+ */
+ protected int getOptionsAlign() {
+ return -1;
+ }
+
+ /** Getter for button listener or null
+ */
+ protected ActionListener getButtonListener() {
+ return null;
+ }
+
+ /** Closing options.
+ */
+ protected Object[] getClosingOptions() {
+ return null;
+ }
+
+ /** Updates help.
+ */
+ protected HelpCtx getHelpCtx() {
+ return null;
+ }
+
+ @Override
+ public void windowDeactivated(final java.awt.event.WindowEvent p1) {
+ }
+
+ @Override
+ public void windowClosed(final java.awt.event.WindowEvent p1) {
+ }
+
+ @Override
+ public void windowDeiconified(final java.awt.event.WindowEvent p1) {
+ }
+
+ @Override
+ public void windowOpened(final java.awt.event.WindowEvent p1) {
+ }
+
+ @Override
+ public void windowIconified(final java.awt.event.WindowEvent p1) {
+ }
+
+ @Override
+ public void windowClosing(final java.awt.event.WindowEvent p1) {
+ // #81938: special handling WizardDescriptor to avoid close wizard during instantiate
+ if (!(descriptor instanceof WizardDescriptor)) {
+ descriptor.setValue(NotifyDescriptor.CLOSED_OPTION);
+ }
+ }
+
+ @Override
+ public void windowActivated(final java.awt.event.WindowEvent p1) {
+ }
+
+ // Used by JavaHelp:
+ public static void addChangeListener(ChangeListener l) {
+ cs.addChangeListener(l);
+ }
+
+ public static void removeChangeListener(ChangeListener l) {
+ cs.removeChangeListener(l);
+ }
+
+ private static void fireChangeEvent() {
+ EventQueue.invokeLater(new Runnable() {
+
+ @Override
+ public void run() {
+ cs.fireChange();
+ }
+
+ });
+ }
+
+ private final class EscapeAction extends AbstractAction {
+
+ public EscapeAction() {
+ putValue(Action.ACTION_COMMAND_KEY, ESCAPE_COMMAND);
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ buttonListener.actionPerformed(e);
+ }
+
+ }
+
+ /** Button listener
+ */
+ private class ButtonListener implements ActionListener, ComponentListener, PropertyChangeListener {
+
+ ButtonListener() {
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent evt) {
+ boolean isAqua = "Aqua".equals(UIManager.getLookAndFeel().getID()) || //NOI18N
+ "true".equalsIgnoreCase(System.getProperty("xtest.looks_as_mac"));
+
+ Object pressedOption = evt.getSource();
+ // handle ESCAPE
+ if (ESCAPE_COMMAND.equals(evt.getActionCommand())) {
+ MenuElement[] selPath = MenuSelectionManager.defaultManager().getSelectedPath();
+ // part of #130919 fix - handle ESC key well in dialogs with menus
+ if (selPath == null || selPath.length == 0) {
+ pressedOption = NotifyDescriptor.CLOSED_OPTION;
+ } else {
+ MenuSelectionManager.defaultManager().clearSelectedPath();
+ return;
+ }
+ } else {
+ // handle buttons
+ if (evt.getSource() == stdHelpButton) {
+ showHelp(currentHelp);
+ return;
+ }
+
+ Object[] options = descriptor.getOptions();
+ if (isAqua && options != null) {
+ Arrays.sort(options, NbPresenter.this);
+ }
+
+ if (options != null
+ && currentPrimaryButtons != null
+ && options.length == (currentPrimaryButtons.length
+ - ((currentHelp != null) ? 1 : 0))) {
+ int offset = currentHelp != null && isAqua
+ ? -1 : 0;
+ for (int i = 0; i < currentPrimaryButtons.length; i++) {
+ if (evt.getSource() == currentPrimaryButtons[i]) {
+ pressedOption = options[i + offset];
+ }
+ }
+ }
+
+ options = descriptor.getAdditionalOptions();
+ if (isAqua && options != null) {
+ Arrays.sort(options, NbPresenter.this);
+ }
+
+ if (options != null
+ && currentSecondaryButtons != null
+ && options.length == currentSecondaryButtons.length) {
+ for (int i = 0; i < currentSecondaryButtons.length; i++) {
+ if (evt.getSource() == currentSecondaryButtons[i]) {
+ pressedOption = options[i];
+ }
+ }
+ }
+
+ if (evt.getSource() == stdYesButton) {
+ pressedOption = NotifyDescriptor.YES_OPTION;
+ } else if (evt.getSource() == stdNoButton) {
+ pressedOption = NotifyDescriptor.NO_OPTION;
+ } else if (evt.getSource() == stdCancelButton) {
+ pressedOption = NotifyDescriptor.CANCEL_OPTION;
+ } else if (evt.getSource() == stdClosedButton) {
+ pressedOption = NotifyDescriptor.CLOSED_OPTION;
+ } else if (evt.getSource() == stdOKButton) {
+ pressedOption = NotifyDescriptor.OK_OPTION;
+ }
+ }
+
+ descriptor.setValue(pressedOption);
+
+ ActionListener al = getButtonListener();
+ if (al != null) {
+
+ if (pressedOption == evt.getSource()) {
+ al.actionPerformed(evt);
+ } else {
+ al.actionPerformed(new ActionEvent(
+ pressedOption, evt.getID(), evt.getActionCommand(), evt.getModifiers()));
+ }
+ }
+
+ Object[] arr = getClosingOptions();
+ if (arr == null || pressedOption == NotifyDescriptor.CLOSED_OPTION) {
+ // all options should close
+ dispose();
+ } else {
+ java.util.List l = java.util.Arrays.asList(arr);
+
+ if (l.contains(pressedOption)) {
+ dispose();
+ }
+ }
+ }
+
+ @Override
+ public void componentShown(final java.awt.event.ComponentEvent p1) {
+ updateDefaultButton();
+ }
+
+ @Override
+ public void componentResized(final java.awt.event.ComponentEvent p1) {
+ }
+
+ @Override
+ public void componentHidden(final java.awt.event.ComponentEvent p1) {
+ updateDefaultButton();
+ }
+
+ @Override
+ public void componentMoved(final java.awt.event.ComponentEvent p1) {
+ }
+
+ @Override
+ public void propertyChange(final java.beans.PropertyChangeEvent p1) {
+ if ("enabled".equals(p1.getPropertyName())) {
+ updateDefaultButton();
+ }
+ }
+
+ }
+
+ @Override
+ public javax.accessibility.AccessibleContext getAccessibleContext() {
+ if (accessibleContext == null) {
+ accessibleContext = new AccessibleNbPresenter();
+ }
+ return accessibleContext;
+ }
+
+ private static String getMessageTypeDescription(int messageType) {
+ switch (messageType) {
+ case NotifyDescriptor.ERROR_MESSAGE:
+ return NbBundle.getBundle(NbPresenter.class).getString("ACSD_ErrorMessage"); // NOI18N
+ case NotifyDescriptor.WARNING_MESSAGE:
+ return NbBundle.getBundle(NbPresenter.class).getString("ACSD_WarningMessage"); // NOI18N
+ case NotifyDescriptor.QUESTION_MESSAGE:
+ return NbBundle.getBundle(NbPresenter.class).getString("ACSD_QuestionMessage"); // NOI18N
+ case NotifyDescriptor.INFORMATION_MESSAGE:
+ return NbBundle.getBundle(NbPresenter.class).getString("ACSD_InformationMessage"); // NOI18N
+ case NotifyDescriptor.PLAIN_MESSAGE:
+ return NbBundle.getBundle(NbPresenter.class).getString("ACSD_PlainMessage"); // NOI18N
+ }
+ return ""; // NOI18N
+ }
+
+ private class AccessibleNbPresenter extends AccessibleJDialog {
+
+ AccessibleNbPresenter() {
+ }
+
+ @Override
+ public String getAccessibleName() {
+ if (accessibleName != null) {
+ return accessibleName;
+ } else {
+ if (currentMessage instanceof javax.accessibility.Accessible
+ && currentMessage.getAccessibleContext().getAccessibleName() != null) {
+ return currentMessage.getAccessibleContext().getAccessibleName();
+ } else {
+ return super.getAccessibleName();
+ }
+ }
+ }
+
+ @Override
+ public String getAccessibleDescription() {
+ if (accessibleDescription != null) {
+ return accessibleDescription;
+ } else {
+ if (currentMessage instanceof javax.accessibility.Accessible
+ && currentMessage.getAccessibleContext().getAccessibleDescription() != null) {
+ return java.text.MessageFormat.format(
+ getMessageTypeDescription(descriptor.getMessageType()),
+ new Object[]{
+ currentMessage.getAccessibleContext().getAccessibleDescription()
+ });
+ } else {
+ return super.getAccessibleDescription();
+ }
+ }
+ }
+
+ }
+
+ static Field markers;
+ static Method dequeue;
+
+ static {
+ if (Boolean.getBoolean("netbeans.hack.50423")) { // NOI18N
+ try {
+ markers = DefaultKeyboardFocusManager.class.getDeclaredField("typeAheadMarkers"); // NOI18N
+ markers.setAccessible(true);
+ dequeue = DefaultKeyboardFocusManager.class.getDeclaredMethod("dequeueKeyEvents", new Class[]{Long.TYPE, java.awt.Component.class});
+ dequeue.setAccessible(true);
+ } catch (Throwable ex) {
+ LOG.log(Level.WARNING, "Not activating workaround for #50423", ex); // NOI18N
+ }
+ }
+ }
+
+ private final class HackTypeAhead implements Runnable {
+
+ private RequestProcessor.Task task = RequestProcessor.getDefault().create(this);
+
+ public HackTypeAhead() {
+ }
+
+ public void activate() {
+ if (markers != null) {
+ task.schedule(1000);
+ }
+ }
+
+ @Override
+ public void run() {
+ if (!SwingUtilities.isEventDispatchThread()) {
+ SwingUtilities.invokeLater(this);
+ return;
+ }
+
+ KeyboardFocusManager fm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
+ Collection result = null;
+ try {
+ result = (Collection) markers.get(fm);
+ } catch (Exception ex) {
+ Logger.getLogger(NbPresenter.class.getName()).log(Level.WARNING, null, ex);
+ }
+
+ if (result == null || result.isEmpty()) {
+ return;
+ }
+
+ LOG.warning("Symptoms of #50423: There is something in type ahead: " + result + " requesting focus change"); // NOI18N
+ try {
+ dequeue.invoke(fm, new Object[]{Long.valueOf(-1), NbPresenter.this});
+ } catch (Exception ex) {
+ Logger.getLogger(NbPresenter.class.getName()).log(Level.WARNING, null, ex);
+ }
+ }
+
+ } // end of HackTypeAhead
+
+ /** Shows a specified HelpCtx in IDE's help window.
+ * XXX would be better to directly depend on org.netbeans.api.javahelp.Help
+ * @param helpCtx thehelp to be shown
+ */
+ private static void showHelp(HelpCtx helpCtx) {
+ // Awkward but should work.
+ try {
+ Class<?> c = Lookup.getDefault().lookup(ClassLoader.class).loadClass("org.netbeans.api.javahelp.Help"); // NOI18N
+ Object o = Lookup.getDefault().lookup(c);
+ if (o != null) {
+ Method m = c.getMethod("showHelp", new Class[]{HelpCtx.class}); // NOI18N
+ m.invoke(o, new Object[]{helpCtx});
+ return;
+ }
+ } catch (ClassNotFoundException cnfe) {
+ // ignore - maybe javahelp module is not installed, not so strange
+ } catch (Exception e) {
+ // potentially more serious
+ Logger.getLogger(NbPresenter.class.getName()).log(Level.WARNING, null, e);
+ }
+ // Did not work.
+ Toolkit.getDefaultToolkit().beep();
+ }
+
+}
View
334 src/org/nbrtl/dialog/RTLDialogDisplayerImpl.java
@@ -0,0 +1,334 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
+ * Microsystems, Inc. All Rights Reserved.
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ */
+package org.nbrtl.dialog;
+
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dialog;
+import java.awt.EventQueue;
+import java.awt.Frame;
+import java.awt.KeyboardFocusManager;
+import java.awt.Window;
+import org.openide.DialogDescriptor;
+import org.openide.DialogDisplayer;
+import org.openide.NotifyDescriptor;
+import org.openide.util.Mutex;
+import org.openide.windows.WindowManager;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import javax.swing.JRootPane;
+
+/**
+ * TODO: test all available cases of DialogDisplayer usage
+ * TODO: test Wizard
+ * TODO: check about FileSelector
+ * TODO: compile as NBM, install it into an application and test again
+ * TODO: add Russian and Hebrew languages via installer
+ * TODO: check the Input line presentation
+ * TODO: fix LEFT alignment in all the lables
+ */
+
+/**
+ * Implementation of <code>org.openide.DialogDisplayer</code>.
+ *
+ * @author Jesse Glick
+ * edited by Dmitry Natenberg
+ */
+//@ServiceProvider(service=DialogDisplayer.class)
+public class RTLDialogDisplayerImpl extends DialogDisplayer {
+
+ /** delayed runnables */
+ private static List<Runnable> run = Collections.synchronizedList(new ArrayList<Runnable>());
+ /** non-null if we are running in unit test and should no show any dialogs */
+ private Object testResult;
+
+ /** Creates a new instance of RTLDialogDisplayer */
+ public RTLDialogDisplayerImpl() {
+ this(null);
+ }
+
+ RTLDialogDisplayerImpl(Object testResult) {
+ this.testResult = testResult;
+ }
+
+ /* Runs list of tasks gathered from notifyLater calls */
+ public static void runDelayed() {
+ NbPresenter.LOG.fine("runDelayed");
+ List<Runnable> local = run;
+ run = null;
+ if (local == null) {
+ NbPresenter.LOG.fine("runDelayed, nothing");
+ return;
+ }
+
+ assert EventQueue.isDispatchThread();
+ for (Runnable r : local) {
+ NbPresenter.LOG.fine("runDelayed, run = " + r);
+ r.run();
+ }
+ NbPresenter.LOG.fine("runDelayed, done");
+ }
+
+ /** Creates new dialog. */
+ @Override
+ public Dialog createDialog(final DialogDescriptor d) {
+ return Mutex.EVENT.readAccess(new Mutex.Action<Dialog>() {
+
+ @Override
+ public Dialog run() {
+ // if a modal dialog active use it as parent
+ // otherwise use the main window
+ if (NbPresenter.currentModalDialog != null) {
+ if (NbPresenter.currentModalDialog.isLeaf()) {
+ return new NbDialog(d, WindowManager.getDefault().getMainWindow());
+ } else {
+ return new NbDialog(d, NbPresenter.currentModalDialog);
+ }
+ } else {
+ Window w = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
+ if (!(w instanceof NbPresenter) || !w.isVisible()) {
+
+ // undocked window is not instanceof NbPresenter although it's NetBeans's native window
+ // all docked windows implements ModeUIBase interface
+
+// if (! (w instanceof DefaultSeparateContainer.ModeUIBase)) {
+// Container cont = SwingUtilities.getAncestorOfClass(Window.class, w);
+// if (cont != null && (cont instanceof DefaultSeparateContainer.ModeUIBase)) {
+// w = (Window) cont;
+// } else {
+// // don't set non-ide window as parent
+ w = WindowManager.getDefault ().getMainWindow ();
+// }
+// }
+ } else if (w instanceof NbPresenter && ((NbPresenter) w).isLeaf()) {
+ w = WindowManager.getDefault().getMainWindow();
+ }
+ if (w instanceof Dialog) {
+ NbDialog dlg = new NbDialog(d, (Dialog) w);
+ dlg.requestFocusInWindow();
+ return dlg;
+ } else {
+ Frame f = w instanceof Frame ? (Frame) w : WindowManager.getDefault().getMainWindow();
+ NbDialog dlg = new NbDialog(d, f);
+ dlg.requestFocusInWindow();
+ return dlg;
+ }
+ }
+ }
+
+ });
+ }
+
+ /** Notifies user by a dialog.
+ * @param descriptor description that contains needed informations
+ * @return the option that has been choosen in the notification.
+ */
+ @Override
+ public Object notify(NotifyDescriptor descriptor) {
+ return notify(descriptor, false);
+ }
+
+ /** Notifies user by a dialog.
+ * @param descriptor description that contains needed informations
+ * @param noParent don't set any window as parent of dialog, if flag is true
+ * @return the option that has been choosen in the notification.
+ */
+ private Object notify(final NotifyDescriptor descriptor, final boolean noParent) {
+ class AWTQuery implements Runnable {
+
+ public Object result;
+ public boolean running;
+
+ @Override
+ public void run() {
+ synchronized (RTLDialogDisplayerImpl.this) {
+ notify();
+ running = true;
+ }
+
+ showDialog();
+
+ synchronized (this) {
+ this.result = descriptor.getValue();
+ notifyAll();
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ public void showDialog() {
+ if (testResult != null) {
+ // running in Unit test
+ descriptor.setValue(testResult);
+ return;
+ }
+
+ Component focusOwner = null;
+ Component comp = org.openide.windows.TopComponent.getRegistry().getActivated();
+ Component win = comp;
+ while ((win != null) && (!(win instanceof Window))) {
+ win = win.getParent();
+ }
+ if (win != null) {
+ focusOwner = ((Window) win).getFocusOwner();
+ }
+
+ // if a modal dialog is active use it as parent
+ // otherwise use the main window
+
+ NbPresenter presenter = null;
+ if (descriptor instanceof DialogDescriptor) {
+ if (NbPresenter.currentModalDialog != null) {
+ if (NbPresenter.currentModalDialog.isLeaf()) {
+ presenter = new NbDialog((DialogDescriptor) descriptor, WindowManager.getDefault().getMainWindow());
+ } else {
+ presenter = new NbDialog((DialogDescriptor) descriptor, NbPresenter.currentModalDialog);
+ }
+ } else {
+ Window w = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
+ if (w instanceof NbPresenter && ((NbPresenter) w).isLeaf()) {
+ w = WindowManager.getDefault().getMainWindow();
+ }
+ Frame f = w instanceof Frame ? (Frame) w : WindowManager.getDefault().getMainWindow();
+ if (noParent) {
+ f = null;
+ }
+ presenter = new NbDialog((DialogDescriptor) descriptor, f);
+ }
+ } else {
+ if (NbPresenter.currentModalDialog != null) {
+ presenter = new NbPresenter(descriptor, NbPresenter.currentModalDialog, true);
+ } else {
+ Frame f = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow() instanceof Frame
+ ? (Frame) KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow()
+ : WindowManager.getDefault().getMainWindow();
+
+ if (noParent) {
+ f = null;
+ }
+ presenter = new NbPresenter(descriptor, f, true);
+ }
+ }
+
+ //#47150 - horrible hack for vcs module
+ if ("true".equals(System.getProperty("javahelp.ignore.modality"))) { //NOI18N
+ presenter.getRootPane().putClientProperty("javahelp.ignore.modality", "true"); //NOI18N
+ System.setProperty("javahelp.ignore.modality", "false"); //NOI18N
+ }
+
+ //Bugfix #8551
+ presenter.getRootPane().requestDefaultFocus();
+ presenter.setVisible(true);
+
+ // dialog is gone, restore the focus
+
+ if (focusOwner != null) {
+ win.requestFocusInWindow();
+ comp.requestFocusInWindow();
+ if (!(focusOwner instanceof JRootPane)) //#85068
+ {
+ focusOwner.requestFocusInWindow();
+ }
+ }
+ }
+
+ }
+
+ AWTQuery query = new AWTQuery();
+
+ if (javax.swing.SwingUtilities.isEventDispatchThread()) {
+ query.showDialog();
+ return descriptor.getValue();
+ }
+
+ synchronized (query) {
+ javax.swing.SwingUtilities.invokeLater(query);
+ try {
+ query.wait(10000);
+ } catch (InterruptedException ex) {
+ // ok, should not happen and does not matter
+ }
+
+ if (query.running) {
+ while (query.result == null) {
+ try {
+ query.wait();
+ } catch (InterruptedException ex) {
+ // one more round
+ }
+ }
+ return query.result;
+ } else {
+ return NotifyDescriptor.CLOSED_OPTION;
+ }
+ }
+ }
+
+ /* Schedules notification for specific later time if called before
+ * <code>runDelayed</code>, otherwise works as superclass method.
+ */
+ @Override
+ public void notifyLater(final NotifyDescriptor descriptor) {
+ class R implements Runnable {
+
+ public boolean noParent;
+
+ @Override
+ public void run() {
+ RTLDialogDisplayerImpl.this.notify(descriptor, noParent);
+ }
+
+ }
+ R r = new R();
+
+ List<Runnable> local = run;
+ if (local != null) {
+ r.noParent = true;
+ local.add(r);
+ } else {
+ EventQueue.invokeLater(r);
+ }
+ }
+
+}
View
BIN  src/org/nbrtl/dialog/resources/delete.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  src/org/nbrtl/dialog/resources/error.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  src/org/nbrtl/dialog/resources/info.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  src/org/nbrtl/dialog/resources/warning.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Please sign in to comment.
Something went wrong with that request. Please try again.