Index: src/org/openide/WizardDescriptor.java
===================================================================
RCS file: /cvs/openide/src/org/openide/WizardDescriptor.java,v
retrieving revision 1.77
diff -c -r1.77 WizardDescriptor.java
*** src/org/openide/WizardDescriptor.java 29 Jan 2003 01:42:35 -0000 1.77
--- src/org/openide/WizardDescriptor.java 13 Feb 2003 17:02:03 -0000
***************
*** 40,45 ****
--- 40,46 ----
import org.openide.awt.HtmlBrowser;
import javax.accessibility.*;
+ import org.openide.DialogDisplayer;
import org.openide.util.RequestProcessor;
/** Implements a basic "wizard" GUI system.
***************
*** 67,77 ****
private final JButton cancelButton = new JButton ();
private final JButton previousButton = new JButton ();
! private static final ActionListener CLOSE_PREVENTER = new ActionListener () {
! public void actionPerformed (ActionEvent evt) {
! }
! };
!
{
// button init
ResourceBundle b = NbBundle.getBundle ("org.openide.Bundle"); // NOI18N
--- 68,76 ----
private final JButton cancelButton = new JButton ();
private final JButton previousButton = new JButton ();
! private ActionListenerImpl buttonListener;
!
!
{
// button init
ResourceBundle b = NbBundle.getBundle ("org.openide.Bundle"); // NOI18N
***************
*** 196,202 ****
private Iterator panels;
/** Change listener that invokes method update state */
! private Listener listener;
/** current panel */
private Panel current;
--- 195,201 ----
private Iterator panels;
/** Change listener that invokes method update state */
! private ChangeListenerImpl listener;
/** current panel */
private Panel current;
***************
*** 212,217 ****
--- 211,219 ----
*/
private Map properties;
+ /** Log everything happening in the wizard system. */
+ private static final ErrorManager err = ErrorManager.getDefault().getInstance("org.openide.wizards"); // NOI18N
+
/** Create a new wizard from a fixed list of panels, passing some settings to the panels.
* @param wizardPanels the panels to use
* @param settings the settings to pass to panels, or null
***************
*** 228,235 ****
* @see #WizardDescriptor(WizardDescriptor.Iterator, Object)
*/
public WizardDescriptor (Panel[] wizardPanels) {
! // passing CLOSE_PREVENTER which is treated especially
! this (wizardPanels, CLOSE_PREVENTER);
}
/** Create wizard for a sequence of panels, passing some settings to the panels.
--- 230,236 ----
* @see #WizardDescriptor(WizardDescriptor.Iterator, Object)
*/
public WizardDescriptor (Panel[] wizardPanels) {
! this (wizardPanels, null);
}
/** Create wizard for a sequence of panels, passing some settings to the panels.
***************
*** 239,253 ****
* @see WizardDescriptor.Panel#storeSettings
*/
public WizardDescriptor (Iterator panels, Object settings) {
! super ("", "", true, DEFAULT_OPTION, null, CLOSE_PREVENTER); // NOI18N
! this.settings = settings == CLOSE_PREVENTER ? this : settings;
!
! listener = new Listener ();
! nextButton.addActionListener (listener);
! previousButton.addActionListener (listener);
! finishButton.addActionListener (listener);
! cancelButton.addActionListener (listener);
super.setOptions (new Object[] { previousButton, nextButton, finishButton, cancelButton });
super.setClosingOptions (new Object[] { finishButton, cancelButton });
--- 240,251 ----
* @see WizardDescriptor.Panel#storeSettings
*/
public WizardDescriptor (Iterator panels, Object settings) {
! super ("", "", true, DEFAULT_OPTION, null, null); // NOI18N
! if (settings == null) {
! this.settings = this;
! }
! listener = new ChangeListenerImpl ();
super.setOptions (new Object[] { previousButton, nextButton, finishButton, cancelButton });
super.setClosingOptions (new Object[] { finishButton, cancelButton });
***************
*** 263,270 ****
* @param panels iterator over all {@link WizardDescriptor.Panel}s that can appear in the wizard
*/
public WizardDescriptor (Iterator panels) {
! // passing CLOSE_PREVENTER which is treated especially
! this (panels, CLOSE_PREVENTER);
}
/** Initializes settings.
--- 261,267 ----
* @param panels iterator over all {@link WizardDescriptor.Panel}s that can appear in the wizard
*/
public WizardDescriptor (Iterator panels) {
! this (panels, null);
}
/** Initializes settings.
***************
*** 275,280 ****
--- 272,288 ----
updateState ();
}
+ public ActionListener getButtonListener () {
+ ActionListener al = super.getButtonListener();
+ if (buttonListener == null) {
+ buttonListener = new ActionListenerImpl();
+ }
+ if (al != null) {
+ buttonListener.setDelegate(al);
+ }
+ return buttonListener;
+ }
+
/** Set a different list of panels.
* Correctly updates the buttons.
* @param panels the new list of {@link WizardDescriptor.Panel}s
***************
*** 310,316 ****
* @param options the options to set
*/
public void setClosingOptions (Object[] options) {
! super.setClosingOptions (convertOptions (options));
}
/** Converts some options.
--- 318,327 ----
* @param options the options to set
*/
public void setClosingOptions (Object[] options) {
! if (options != null) {
! options = convertOptions(options);
! }
! super.setClosingOptions (options);
}
/** Converts some options.
***************
*** 475,485 ****
// nextButton.setVisible (next);
// finishButton.setVisible (!next || (current instanceof FinishPanel));
! if (next) {
! setValue (nextButton);
! } else {
! // setValue (finishButton);
! }
setHelpCtx (p.getHelp ());
--- 486,498 ----
// nextButton.setVisible (next);
// finishButton.setVisible (!next || (current instanceof FinishPanel));
! // I'm commenting out this code completely. It fires IMHO useless
! // events whenever there is a change in the state of the wizard
! // if (next) {
! // doSetValue (nextButton);
! // } else {
! // // setValue (finishButton);
! // }
setHelpCtx (p.getHelp ());
***************
*** 682,704 ****
/** Overrides superclass method. Adds reseting of wizard
* for CLOSED_OPTION
. */
public void setValue(Object value) {
- //Bugfix #25820: Call resetWizard to make sure that storeSettings
- //is called before propertyChange.
- Object convertedValue = backConvertOption(value);
- if (convertedValue == OK_OPTION) {
- resetWizard();
- }
- super.setValue(backConvertOption(value));
! // #17360: Reset wizard on CLOSED_OPTION too.
if(value == CLOSED_OPTION) {
resetWizard();
}
}
/** Resets wizard when after closed/cancelled/finished the wizard dialog. */
private void resetWizard() {
if(current != null) {
current.storeSettings (settings);
current.removeChangeListener(listener);
current = null;
--- 695,744 ----
/** Overrides superclass method. Adds reseting of wizard
* for CLOSED_OPTION
. */
public void setValue(Object value) {
! // WizardDescript handles buttons on its own.
! // This method is called from NbPresenter and
! // apart from CLOSED_OPTION case must be all
! // calls be ignored.
if(value == CLOSED_OPTION) {
+ if (err.isLoggable(ErrorManager.UNKNOWN)) {
+ err.log("WD.setValue: CLOSED_OPTION received"); //NOI18N
+ }
+ doSetValue(value);
+ } else {
+ if (err.isLoggable(ErrorManager.UNKNOWN)) {
+ err.log("WD.setValue: ignoring value. The WD will handle it itself."); //NOI18N
+ }
+ }
+
+ }
+
+ /** This is internal implementaiton of setValue which is called
+ * directly from button handlers in this class.
+ */
+ private void doSetValue(Object value) {
+ if (err.isLoggable(ErrorManager.UNKNOWN)) {
+ err.log("WD.doSetValue: value before conversion "+value); //NOI18N
+ }
+ if (Arrays.asList(getClosingOptions()).contains(value) || value == CLOSED_OPTION) {
resetWizard();
}
+
+ value = backConvertOption(value);
+
+ if (err.isLoggable(ErrorManager.UNKNOWN)) {
+ err.log("WD.doSetValue: notify listeners with value "+value); //NOI18N
+ }
+ super.setValue(value);
}
+
/** Resets wizard when after closed/cancelled/finished the wizard dialog. */
private void resetWizard() {
if(current != null) {
+ if (err.isLoggable(ErrorManager.UNKNOWN)) {
+ err.log("WD.resetWizard: storeSettings() + removeListeners"); //NOI18N
+ }
current.storeSettings (settings);
current.removeChangeListener(listener);
current = null;
***************
*** 978,992 ****
/** Listener to changes in the iterator and panels.
*/
! private final class Listener implements ChangeListener, ActionListener {
! Listener() {}
/** Change in the observed objects */
public void stateChanged (ChangeEvent ev) {
updateState ();
}
/** Action listener */
public void actionPerformed (ActionEvent ev) {
if (ev.getSource () == nextButton) {
panels.nextPanel ();
try {
updateState ();
--- 1018,1079 ----
/** Listener to changes in the iterator and panels.
*/
! private final class ChangeListenerImpl implements ChangeListener {
! ChangeListenerImpl() {}
!
/** Change in the observed objects */
public void stateChanged (ChangeEvent ev) {
updateState ();
}
+ }
+
+ /** This is implementation of action listener which checks
+ * "WizardPanel_errorMessage" property and if it is set it
+ * shows error message. If it is not set then the next or finish
+ * buttons are executed. The next button is handled completely
+ * in WD so there is no problem with it. The problematic is Finish
+ * button which closes dialog. The solution depends on the implementation
+ * detail of NbPresenter which (quite logically) calls WD.getButtonListener
+ * first and notifies it about action and then it checks WD.getClosingOptions
+ * and if the button is in closing options it will close throws the dialog. The
+ * trik done here is that if wizard is invalid then Finish is removed from the
+ * getClosingOptions and vice versa.
+ */
+ private final class ActionListenerImpl implements ActionListener {
+
+ private ActionListener al;
+
+ public ActionListenerImpl() {
+ }
+
+ public void setDelegate(ActionListener al) {
+ this.al = al;
+ }
+
+ private String getErrorMessage() {
+ return (String)getProperty("WizardPanel_errorMessage");
+ }
+
+ private void showErrorMessage() {
+ DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(
+ getErrorMessage(), NotifyDescriptor.ERROR_MESSAGE));
+ }
+
+ private void resetErrorMessage() {
+ putProperty("WizardPanel_errorMessage", null);
+ }
+
/** Action listener */
public void actionPerformed (ActionEvent ev) {
+
+ // Next button was pressed
if (ev.getSource () == nextButton) {
+
+ if (getErrorMessage() != null) {
+ showErrorMessage();
+ return;
+ }
+
panels.nextPanel ();
try {
updateState ();
***************
*** 1004,1029 ****
}
}
if (ev.getSource () == previousButton) {
panels.previousPanel ();
updateState ();
}
if (ev.getSource () == finishButton) {
! if (Arrays.asList(getClosingOptions()).contains(finishButton)) {
! resetWizard();
}
! setValue (OK_OPTION);
}
if (ev.getSource () == cancelButton) {
! if (Arrays.asList(getClosingOptions()).contains(cancelButton)) {
! resetWizard();
}
! setValue (CANCEL_OPTION);
}
}
}
/** Listenes on a users client property changes
*/
--- 1091,1162 ----
}
}
+ // Previous button was pressed
if (ev.getSource () == previousButton) {
+ resetErrorMessage();
panels.previousPanel ();
updateState ();
}
+ // Finish button was pressed
if (ev.getSource () == finishButton) {
!
! if (getErrorMessage() != null) {
! showErrorMessage();
! // this is kind of trick. but if Finish button remains there
! // the NbPresenter would dispose this dialog. In order
! // to prevent it I have to temporarily remove Finish
! // button from allowed close options
! removeFinishButtonFromCloseOptions();
! return;
! } else {
! // add Finish button into close options again
! // if it was removed.
! addFinishButtonToCloseOptions();
! }
!
! if (err.isLoggable(ErrorManager.UNKNOWN)) {
! err.log("WD.ActionListenerImpl: everything shoul be OK - Finish it"); //NOI18N
}
! doSetValue(finishButton);
}
+ // Cancel button was pressed
if (ev.getSource () == cancelButton) {
! if (err.isLoggable(ErrorManager.UNKNOWN)) {
! err.log("WD.ActionListenerImpl: Cancel it"); //NOI18N
}
! doSetValue(cancelButton);
! }
!
! if (al != null) {
! al.actionPerformed(ev);
! }
! }
! }
!
! private void removeFinishButtonFromCloseOptions() {
! List list = new LinkedList(Arrays.asList(getClosingOptions()));
! if (list.contains(finishButton)) {
! if (err.isLoggable(ErrorManager.UNKNOWN)) {
! err.log("WD.removeFinishButtonFromCloseOptions: Finish button will be removed"); //NOI18N
}
+ list.remove(finishButton);
+ setClosingOptions(list.toArray(new Object[list.size()]));
}
}
+
+ private void addFinishButtonToCloseOptions() {
+ List list = new LinkedList(Arrays.asList(getClosingOptions()));
+ if (!list.contains(finishButton)) {
+ if (err.isLoggable(ErrorManager.UNKNOWN)) {
+ err.log("WD.addFinishButtonToCloseOptions: Finish button will be added"); //NOI18N
+ }
+ list.add(finishButton);
+ setClosingOptions(list.toArray(new Object[list.size()]));
+ }
+ }
+
/** Listenes on a users client property changes
*/
Index: src/org/openide/loaders/Bundle.properties
===================================================================
RCS file: /cvs/openide/src/org/openide/loaders/Bundle.properties,v
retrieving revision 1.94
diff -c -r1.94 Bundle.properties
*** src/org/openide/loaders/Bundle.properties 13 Jan 2003 17:56:38 -0000 1.94
--- src/org/openide/loaders/Bundle.properties 13 Feb 2003 17:02:03 -0000
***************
*** 197,199 ****
--- 197,205 ----
MSG_renameError=This object cannot be renamed from {0} to {1}.
MSG_NotValidName=Cannot give {0} an empty name.
ERR_NoFilesystem=No enabled filesystem. Make sure that you have at least one filesystem that is not read-only and is not hidden.
+
+ # TemplateWizardPanel2
+ MSG_fs_or_folder_does_not_exist=Target filesystem or folder does not exist
+ MSG_fs_is_readonly=Target filesystem is readonly
+ # {0} - name of the existing file
+ MSG_file_already_exist=File {0} already exist
\ No newline at end of file
Index: src/org/openide/loaders/TemplateWizard2.java
===================================================================
RCS file: /cvs/openide/src/org/openide/loaders/TemplateWizard2.java,v
retrieving revision 1.51
diff -c -r1.51 TemplateWizard2.java
*** src/org/openide/loaders/TemplateWizard2.java 29 Jan 2003 01:42:48 -0000 1.51
--- src/org/openide/loaders/TemplateWizard2.java 13 Feb 2003 17:02:03 -0000
***************
*** 32,37 ****
--- 32,38 ----
import org.openide.explorer.propertysheet.PropertyPanel;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileSystem;
+ import org.openide.util.NbBundle;
import org.openide.util.Utilities;
/** Dialog that can be used in create from template.
***************
*** 220,242 ****
/** Helper implementation of WizardDescription.Panel for TemplateWizard.Panel2.
* Test whether the panel is finished and it is safe to proceed to the next one.
* If the panel is valid, the "Next" (or "Finish") button will be enabled.
! * @return true
if the user has entered satisfactory information
*/
! boolean implIsValid () {
!
// test whether the selected folder on selected filesystem already exists
FileSystem fs = (FileSystem)fileSystemRef.get ();
if (locationFolder == null || fs == null)
! return false;
// target filesystem should be writable
if (((FileSystem)fileSystemRef.get ()).isReadOnly ())
! return false;
// test whether the selected name already exists
StringBuffer sb = new StringBuffer ();
sb.append (locationFolder.getPrimaryFile ().getPath ());
! sb.append (java.io.File.separatorChar);
sb.append (newObjectName.getText ());
if ("" != extension) { // NOI18N
sb.append ('.');
--- 221,243 ----
/** Helper implementation of WizardDescription.Panel for TemplateWizard.Panel2.
* Test whether the panel is finished and it is safe to proceed to the next one.
* If the panel is valid, the "Next" (or "Finish") button will be enabled.
! * @return null
if the user has entered satisfactory information
! * or localized string describing the error.
*/
! String implIsValid () {
// test whether the selected folder on selected filesystem already exists
FileSystem fs = (FileSystem)fileSystemRef.get ();
if (locationFolder == null || fs == null)
! return NbBundle.getMessage(TemplateWizard2.class, "MSG_fs_or_folder_does_not_exist");
// target filesystem should be writable
if (((FileSystem)fileSystemRef.get ()).isReadOnly ())
! return NbBundle.getMessage(TemplateWizard2.class, "MSG_fs_is_readonly");
// test whether the selected name already exists
StringBuffer sb = new StringBuffer ();
sb.append (locationFolder.getPrimaryFile ().getPath ());
! sb.append ("/");
sb.append (newObjectName.getText ());
if ("" != extension) { // NOI18N
sb.append ('.');
***************
*** 244,254 ****
}
FileObject f = fs.findResource (sb.toString ());
if (f != null) {
! return false;
}
!
// all ok
! return true;
}
/** Gives notification that an attribute or set of attributes changed.
--- 245,255 ----
}
FileObject f = fs.findResource (sb.toString ());
if (f != null) {
! return NbBundle.getMessage(TemplateWizard2.class, "MSG_file_already_exist", sb.toString());
}
!
// all ok
! return null;
}
/** Gives notification that an attribute or set of attributes changed.
Index: src/org/openide/loaders/TemplateWizardPanel2.java
===================================================================
RCS file: /cvs/openide/src/org/openide/loaders/TemplateWizardPanel2.java,v
retrieving revision 1.2
diff -c -r1.2 TemplateWizardPanel2.java
*** src/org/openide/loaders/TemplateWizardPanel2.java 3 Dec 2002 14:11:55 -0000 1.2
--- src/org/openide/loaders/TemplateWizardPanel2.java 13 Feb 2003 17:02:04 -0000
***************
*** 26,31 ****
--- 26,33 ----
/** listener to changes in the wizard */
private ChangeListener listener;
+ private WizardDescriptor settings;
+
private TemplateWizard2 getPanelUI () {
if (templateWizard2UI == null) {
templateWizard2UI = new TemplateWizard2 ();
***************
*** 82,88 ****
public boolean isValid() {
if (templateWizard2UI == null)
return false;
! return getPanelUI ().implIsValid ();
}
/** Provides the wizard panel with the current data--either
--- 84,97 ----
public boolean isValid() {
if (templateWizard2UI == null)
return false;
!
! // #28466 - hack to solve this issue. See issues for details.
! // Postpone validation of panel to Next/Finish button handlers.
! // This is temporary solution which must be solved by
! // redesign of templates. It is strongly recommended to
! // NOT USE this property outside of openide/core modules.
! settings.putProperty("WizardPanel_errorMessage", getPanelUI().implIsValid());
! return true;
}
/** Provides the wizard panel with the current data--either
***************
*** 97,102 ****
--- 106,112 ----
*
*/
public void readSettings(Object settings) {
+ this.settings = (WizardDescriptor)settings;
getPanelUI ().implReadSettings (settings);
}
***************
*** 116,121 ****
--- 126,132 ----
*/
public void storeSettings(Object settings) {
getPanelUI ().implStoreSettings (settings);
+ this.settings = null;
}
}