1.1 --- a/apisupport.project/src/org/netbeans/modules/apisupport/project/ui/resources/layer.xml Wed May 25 16:24:45 2011 +0200
1.2 +++ b/apisupport.project/src/org/netbeans/modules/apisupport/project/ui/resources/layer.xml Wed May 25 16:50:33 2011 +0200
1.3 @@ -218,6 +218,9 @@
1.4 <file name="templateDataNode.java" url="../wizard/loader/templateDataNode.javx"/>
1.5 <file name="templateDataObject.java" url="../wizard/loader/templateDataObject.javx"/>
1.6 <file name="templateDataObjectWithLookup.java" url="../wizard/loader/templateDataObjectWithLookup.javx"/>
1.7 + <file name="templateDataObjectMulti.java" url="../wizard/loader/templateDataObjectMulti.javx"/>
1.8 + <file name="templateDataObjectMultiForm.java" url="../wizard/loader/templateDataObjectMultiVisual.javx"/>
1.9 + <file name="templateDataObjectMultiForm.form" url="../wizard/loader/templateDataObjectMultiVisual.forx"/>
1.10 <file name="templateDataObjectInLayer.java" url="../wizard/loader/templateDataObjectInLayer.javx"/>
1.11 <file name="templateNew1" url="../wizard/loader/templateNew1"/>
1.12 <file name="templateNew2" url="../wizard/loader/templateNew2"/>
2.1 --- a/apisupport.project/src/org/netbeans/modules/apisupport/project/ui/wizard/loader/Bundle.properties Wed May 25 16:24:45 2011 +0200
2.2 +++ b/apisupport.project/src/org/netbeans/modules/apisupport/project/ui/wizard/loader/Bundle.properties Wed May 25 16:50:33 2011 +0200
2.3 @@ -67,7 +67,7 @@
2.4 LBL_CreatedFiles=&Created Files\:
2.5 LBL_ModifiedFiles=&Modified Files\:
2.6 LBL_Icon_Browse=Bro&wse...
2.7 -LBL_Icon=&Icon\:
2.8 +LBL_Icon=&Icon:
2.9 LBL_Prefix=Class &Name Prefix\:
2.10 LBL_Select=Select
2.11 ERR_Name_Prefix_Empty=Please specify Class Name Prefix.
3.1 --- a/apisupport.project/src/org/netbeans/modules/apisupport/project/ui/wizard/loader/NameAndLocationPanel.form Wed May 25 16:24:45 2011 +0200
3.2 +++ b/apisupport.project/src/org/netbeans/modules/apisupport/project/ui/wizard/loader/NameAndLocationPanel.form Wed May 25 16:50:33 2011 +0200
3.3 @@ -1,9 +1,10 @@
3.4 -<?xml version="1.0" encoding="UTF-8" ?>
3.5 +<?xml version="1.1" encoding="UTF-8" ?>
3.6
3.7 <Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
3.8 <AuxValues>
3.9 <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
3.10 <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
3.11 + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
3.12 <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
3.13 <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
3.14 <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
3.15 @@ -36,21 +37,6 @@
3.16 </Constraint>
3.17 </Constraints>
3.18 </Component>
3.19 - <Component class="javax.swing.JLabel" name="lblIcon">
3.20 - <Properties>
3.21 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
3.22 - <ComponentRef name="txtIcon"/>
3.23 - </Property>
3.24 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
3.25 - <ResourceString bundle="org/netbeans/modules/apisupport/project/ui/wizard/loader/Bundle.properties" key="LBL_Icon" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
3.26 - </Property>
3.27 - </Properties>
3.28 - <Constraints>
3.29 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
3.30 - <GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="12" anchor="10" weightX="0.0" weightY="0.0"/>
3.31 - </Constraint>
3.32 - </Constraints>
3.33 - </Component>
3.34 <Component class="javax.swing.JTextField" name="txtIcon">
3.35 <Constraints>
3.36 <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
3.37 @@ -84,7 +70,7 @@
3.38 </Properties>
3.39 <Constraints>
3.40 <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
3.41 - <GridBagConstraints gridX="0" gridY="2" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="18" insetsLeft="0" insetsBottom="6" insetsRight="12" anchor="10" weightX="0.0" weightY="0.0"/>
3.42 + <GridBagConstraints gridX="0" gridY="3" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="18" insetsLeft="0" insetsBottom="6" insetsRight="12" anchor="10" weightX="0.0" weightY="0.0"/>
3.43 </Constraint>
3.44 </Constraints>
3.45 </Component>
3.46 @@ -97,7 +83,7 @@
3.47 </AuxValues>
3.48 <Constraints>
3.49 <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
3.50 - <GridBagConstraints gridX="1" gridY="2" gridWidth="2" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="18" insetsLeft="0" insetsBottom="6" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
3.51 + <GridBagConstraints gridX="1" gridY="3" gridWidth="2" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="18" insetsLeft="0" insetsBottom="6" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
3.52 </Constraint>
3.53 </Constraints>
3.54 </Component>
3.55 @@ -112,7 +98,7 @@
3.56 </Properties>
3.57 <Constraints>
3.58 <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
3.59 - <GridBagConstraints gridX="0" gridY="3" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="12" anchor="10" weightX="0.0" weightY="0.0"/>
3.60 + <GridBagConstraints gridX="0" gridY="4" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="12" anchor="10" weightX="0.0" weightY="0.0"/>
3.61 </Constraint>
3.62 </Constraints>
3.63 </Component>
3.64 @@ -128,7 +114,7 @@
3.65 </AuxValues>
3.66 <Constraints>
3.67 <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
3.68 - <GridBagConstraints gridX="1" gridY="3" gridWidth="2" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
3.69 + <GridBagConstraints gridX="1" gridY="4" gridWidth="2" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
3.70 </Constraint>
3.71 </Constraints>
3.72 </Component>
3.73 @@ -143,7 +129,7 @@
3.74 </Properties>
3.75 <Constraints>
3.76 <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
3.77 - <GridBagConstraints gridX="0" gridY="4" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="36" insetsLeft="0" insetsBottom="6" insetsRight="12" anchor="18" weightX="0.0" weightY="0.0"/>
3.78 + <GridBagConstraints gridX="0" gridY="5" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="36" insetsLeft="0" insetsBottom="6" insetsRight="12" anchor="18" weightX="0.0" weightY="0.0"/>
3.79 </Constraint>
3.80 </Constraints>
3.81 </Component>
3.82 @@ -158,14 +144,14 @@
3.83 </Properties>
3.84 <Constraints>
3.85 <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
3.86 - <GridBagConstraints gridX="0" gridY="5" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="12" anchor="18" weightX="0.0" weightY="0.0"/>
3.87 + <GridBagConstraints gridX="0" gridY="6" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="12" anchor="18" weightX="0.0" weightY="0.0"/>
3.88 </Constraint>
3.89 </Constraints>
3.90 </Component>
3.91 <Component class="javax.swing.JLabel" name="filler">
3.92 <Constraints>
3.93 <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
3.94 - <GridBagConstraints gridX="0" gridY="6" gridWidth="3" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
3.95 + <GridBagConstraints gridX="0" gridY="7" gridWidth="3" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
3.96 </Constraint>
3.97 </Constraints>
3.98 </Component>
3.99 @@ -183,7 +169,7 @@
3.100 </Properties>
3.101 <Constraints>
3.102 <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
3.103 - <GridBagConstraints gridX="1" gridY="4" gridWidth="2" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="36" insetsLeft="0" insetsBottom="6" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
3.104 + <GridBagConstraints gridX="1" gridY="5" gridWidth="2" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="36" insetsLeft="0" insetsBottom="6" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
3.105 </Constraint>
3.106 </Constraints>
3.107 </Component>
3.108 @@ -202,7 +188,32 @@
3.109 </Properties>
3.110 <Constraints>
3.111 <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
3.112 - <GridBagConstraints gridX="1" gridY="5" gridWidth="2" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
3.113 + <GridBagConstraints gridX="1" gridY="6" gridWidth="2" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
3.114 + </Constraint>
3.115 + </Constraints>
3.116 + </Component>
3.117 + <Component class="javax.swing.JLabel" name="lblIcon2">
3.118 + <Properties>
3.119 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
3.120 + <ComponentRef name="txtIcon"/>
3.121 + </Property>
3.122 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
3.123 + <ResourceString bundle="org/netbeans/modules/apisupport/project/ui/wizard/loader/Bundle.properties" key="LBL_Icon" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
3.124 + </Property>
3.125 + </Properties>
3.126 + <Constraints>
3.127 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
3.128 + <GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="12" anchor="10" weightX="0.0" weightY="0.0"/>
3.129 + </Constraint>
3.130 + </Constraints>
3.131 + </Component>
3.132 + <Component class="javax.swing.JCheckBox" name="useMultiView">
3.133 + <Properties>
3.134 + <Property name="text" type="java.lang.String" value="&Use MultiView"/>
3.135 + </Properties>
3.136 + <Constraints>
3.137 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
3.138 + <GridBagConstraints gridX="1" gridY="2" gridWidth="2" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
3.139 </Constraint>
3.140 </Constraints>
3.141 </Component>
4.1 --- a/apisupport.project/src/org/netbeans/modules/apisupport/project/ui/wizard/loader/NameAndLocationPanel.java Wed May 25 16:24:45 2011 +0200
4.2 +++ b/apisupport.project/src/org/netbeans/modules/apisupport/project/ui/wizard/loader/NameAndLocationPanel.java Wed May 25 16:50:33 2011 +0200
4.3 @@ -88,6 +88,14 @@
4.4 JTextField txt = (JTextField)comPackageName.getEditor().getEditorComponent();
4.5 txt.getDocument().addDocumentListener(dListener);
4.6 }
4.7 +
4.8 + if (data.canUseMultiview()) {
4.9 + useMultiView.setEnabled(true);
4.10 + useMultiView.setSelected(true);
4.11 + } else {
4.12 + useMultiView.setEnabled(false);
4.13 + useMultiView.setSelected(false);
4.14 + }
4.15 }
4.16
4.17 protected void storeToDataModel() {
4.18 @@ -99,6 +107,7 @@
4.19 String icon = txtIcon.getText().trim();
4.20 data.setIconPath(icon.length() == 0 ? (String)null : icon);
4.21 data.setPrefix(txtPrefix.getText().trim());
4.22 + data.setUseMultiview(useMultiView.isSelected());
4.23 NewLoaderIterator.generateFileChanges(data);
4.24 createdFilesValue.setText(UIUtil.generateTextAreaContent(
4.25 data.getCreatedModifiedFiles().getCreatedPaths()));
4.26 @@ -172,13 +181,12 @@
4.27 * WARNING: Do NOT modify this code. The content of this method is
4.28 * always regenerated by the Form Editor.
4.29 */
4.30 - // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
4.31 + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
4.32 private void initComponents() {
4.33 java.awt.GridBagConstraints gridBagConstraints;
4.34
4.35 lblPrefix = new javax.swing.JLabel();
4.36 txtPrefix = new javax.swing.JTextField();
4.37 - lblIcon = new javax.swing.JLabel();
4.38 txtIcon = new javax.swing.JTextField();
4.39 btnIcon = new javax.swing.JButton();
4.40 lblProjectName = new javax.swing.JLabel();
4.41 @@ -190,18 +198,19 @@
4.42 filler = new javax.swing.JLabel();
4.43 createdFilesValue = new javax.swing.JTextArea();
4.44 modifiedFilesValue = new javax.swing.JTextArea();
4.45 + lblIcon2 = new javax.swing.JLabel();
4.46 + useMultiView = new javax.swing.JCheckBox();
4.47
4.48 setLayout(new java.awt.GridBagLayout());
4.49
4.50 lblPrefix.setLabelFor(txtPrefix);
4.51 - org.openide.awt.Mnemonics.setLocalizedText(lblPrefix, org.openide.util.NbBundle.getMessage(NameAndLocationPanel.class, "LBL_Prefix"));
4.52 + org.openide.awt.Mnemonics.setLocalizedText(lblPrefix, org.openide.util.NbBundle.getMessage(NameAndLocationPanel.class, "LBL_Prefix")); // NOI18N
4.53 gridBagConstraints = new java.awt.GridBagConstraints();
4.54 gridBagConstraints.gridx = 0;
4.55 gridBagConstraints.gridy = 0;
4.56 gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
4.57 gridBagConstraints.insets = new java.awt.Insets(1, 0, 6, 12);
4.58 add(lblPrefix, gridBagConstraints);
4.59 -
4.60 gridBagConstraints = new java.awt.GridBagConstraints();
4.61 gridBagConstraints.gridx = 1;
4.62 gridBagConstraints.gridy = 0;
4.63 @@ -210,16 +219,6 @@
4.64 gridBagConstraints.weightx = 1.0;
4.65 gridBagConstraints.insets = new java.awt.Insets(1, 0, 6, 0);
4.66 add(txtPrefix, gridBagConstraints);
4.67 -
4.68 - lblIcon.setLabelFor(txtIcon);
4.69 - org.openide.awt.Mnemonics.setLocalizedText(lblIcon, org.openide.util.NbBundle.getMessage(NameAndLocationPanel.class, "LBL_Icon"));
4.70 - gridBagConstraints = new java.awt.GridBagConstraints();
4.71 - gridBagConstraints.gridx = 0;
4.72 - gridBagConstraints.gridy = 1;
4.73 - gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
4.74 - gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 12);
4.75 - add(lblIcon, gridBagConstraints);
4.76 -
4.77 gridBagConstraints = new java.awt.GridBagConstraints();
4.78 gridBagConstraints.gridx = 1;
4.79 gridBagConstraints.gridy = 1;
4.80 @@ -227,13 +226,12 @@
4.81 gridBagConstraints.weightx = 1.0;
4.82 add(txtIcon, gridBagConstraints);
4.83
4.84 - org.openide.awt.Mnemonics.setLocalizedText(btnIcon, org.openide.util.NbBundle.getMessage(NameAndLocationPanel.class, "LBL_Icon_Browse"));
4.85 + org.openide.awt.Mnemonics.setLocalizedText(btnIcon, org.openide.util.NbBundle.getMessage(NameAndLocationPanel.class, "LBL_Icon_Browse")); // NOI18N
4.86 btnIcon.addActionListener(new java.awt.event.ActionListener() {
4.87 public void actionPerformed(java.awt.event.ActionEvent evt) {
4.88 btnIconActionPerformed(evt);
4.89 }
4.90 });
4.91 -
4.92 gridBagConstraints = new java.awt.GridBagConstraints();
4.93 gridBagConstraints.gridx = 2;
4.94 gridBagConstraints.gridy = 1;
4.95 @@ -241,10 +239,11 @@
4.96 add(btnIcon, gridBagConstraints);
4.97
4.98 lblProjectName.setLabelFor(txtProjectName);
4.99 - org.openide.awt.Mnemonics.setLocalizedText(lblProjectName, java.util.ResourceBundle.getBundle("org/netbeans/modules/apisupport/project/ui/wizard/librarydescriptor/Bundle").getString("LBL_ProjectName"));
4.100 + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("org/netbeans/modules/apisupport/project/ui/wizard/librarydescriptor/Bundle"); // NOI18N
4.101 + org.openide.awt.Mnemonics.setLocalizedText(lblProjectName, bundle.getString("LBL_ProjectName")); // NOI18N
4.102 gridBagConstraints = new java.awt.GridBagConstraints();
4.103 gridBagConstraints.gridx = 0;
4.104 - gridBagConstraints.gridy = 2;
4.105 + gridBagConstraints.gridy = 3;
4.106 gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
4.107 gridBagConstraints.insets = new java.awt.Insets(18, 0, 6, 12);
4.108 add(lblProjectName, gridBagConstraints);
4.109 @@ -252,7 +251,7 @@
4.110 txtProjectName.setEditable(false);
4.111 gridBagConstraints = new java.awt.GridBagConstraints();
4.112 gridBagConstraints.gridx = 1;
4.113 - gridBagConstraints.gridy = 2;
4.114 + gridBagConstraints.gridy = 3;
4.115 gridBagConstraints.gridwidth = 2;
4.116 gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
4.117 gridBagConstraints.weightx = 1.0;
4.118 @@ -260,10 +259,10 @@
4.119 add(txtProjectName, gridBagConstraints);
4.120
4.121 lblPackageName.setLabelFor(comPackageName);
4.122 - org.openide.awt.Mnemonics.setLocalizedText(lblPackageName, java.util.ResourceBundle.getBundle("org/netbeans/modules/apisupport/project/ui/wizard/librarydescriptor/Bundle").getString("LBL_PackageName"));
4.123 + org.openide.awt.Mnemonics.setLocalizedText(lblPackageName, bundle.getString("LBL_PackageName")); // NOI18N
4.124 gridBagConstraints = new java.awt.GridBagConstraints();
4.125 gridBagConstraints.gridx = 0;
4.126 - gridBagConstraints.gridy = 3;
4.127 + gridBagConstraints.gridy = 4;
4.128 gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
4.129 gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 12);
4.130 add(lblPackageName, gridBagConstraints);
4.131 @@ -271,35 +270,34 @@
4.132 comPackageName.setEditable(true);
4.133 gridBagConstraints = new java.awt.GridBagConstraints();
4.134 gridBagConstraints.gridx = 1;
4.135 - gridBagConstraints.gridy = 3;
4.136 + gridBagConstraints.gridy = 4;
4.137 gridBagConstraints.gridwidth = 2;
4.138 gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
4.139 gridBagConstraints.weightx = 1.0;
4.140 add(comPackageName, gridBagConstraints);
4.141
4.142 createdFiles.setLabelFor(createdFilesValue);
4.143 - org.openide.awt.Mnemonics.setLocalizedText(createdFiles, java.util.ResourceBundle.getBundle("org/netbeans/modules/apisupport/project/ui/wizard/librarydescriptor/Bundle").getString("LBL_CreatedFiles"));
4.144 + org.openide.awt.Mnemonics.setLocalizedText(createdFiles, bundle.getString("LBL_CreatedFiles")); // NOI18N
4.145 gridBagConstraints = new java.awt.GridBagConstraints();
4.146 gridBagConstraints.gridx = 0;
4.147 - gridBagConstraints.gridy = 4;
4.148 + gridBagConstraints.gridy = 5;
4.149 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
4.150 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
4.151 gridBagConstraints.insets = new java.awt.Insets(36, 0, 6, 12);
4.152 add(createdFiles, gridBagConstraints);
4.153
4.154 modifiedFiles.setLabelFor(modifiedFilesValue);
4.155 - org.openide.awt.Mnemonics.setLocalizedText(modifiedFiles, java.util.ResourceBundle.getBundle("org/netbeans/modules/apisupport/project/ui/wizard/librarydescriptor/Bundle").getString("LBL_ModifiedFiles"));
4.156 + org.openide.awt.Mnemonics.setLocalizedText(modifiedFiles, bundle.getString("LBL_ModifiedFiles")); // NOI18N
4.157 gridBagConstraints = new java.awt.GridBagConstraints();
4.158 gridBagConstraints.gridx = 0;
4.159 - gridBagConstraints.gridy = 5;
4.160 + gridBagConstraints.gridy = 6;
4.161 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
4.162 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
4.163 gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 12);
4.164 add(modifiedFiles, gridBagConstraints);
4.165 -
4.166 gridBagConstraints = new java.awt.GridBagConstraints();
4.167 gridBagConstraints.gridx = 0;
4.168 - gridBagConstraints.gridy = 6;
4.169 + gridBagConstraints.gridy = 7;
4.170 gridBagConstraints.gridwidth = 3;
4.171 gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
4.172 gridBagConstraints.weightx = 1.0;
4.173 @@ -313,7 +311,7 @@
4.174 createdFilesValue.setBorder(null);
4.175 gridBagConstraints = new java.awt.GridBagConstraints();
4.176 gridBagConstraints.gridx = 1;
4.177 - gridBagConstraints.gridy = 4;
4.178 + gridBagConstraints.gridy = 5;
4.179 gridBagConstraints.gridwidth = 2;
4.180 gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
4.181 gridBagConstraints.weightx = 1.0;
4.182 @@ -328,14 +326,29 @@
4.183 modifiedFilesValue.setBorder(null);
4.184 gridBagConstraints = new java.awt.GridBagConstraints();
4.185 gridBagConstraints.gridx = 1;
4.186 - gridBagConstraints.gridy = 5;
4.187 + gridBagConstraints.gridy = 6;
4.188 gridBagConstraints.gridwidth = 2;
4.189 gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
4.190 gridBagConstraints.weightx = 1.0;
4.191 add(modifiedFilesValue, gridBagConstraints);
4.192
4.193 - }
4.194 - // </editor-fold>//GEN-END:initComponents
4.195 + lblIcon2.setLabelFor(txtIcon);
4.196 + org.openide.awt.Mnemonics.setLocalizedText(lblIcon2, org.openide.util.NbBundle.getMessage(NameAndLocationPanel.class, "LBL_Icon")); // NOI18N
4.197 + gridBagConstraints = new java.awt.GridBagConstraints();
4.198 + gridBagConstraints.gridx = 0;
4.199 + gridBagConstraints.gridy = 1;
4.200 + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
4.201 + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 12);
4.202 + add(lblIcon2, gridBagConstraints);
4.203 +
4.204 + org.openide.awt.Mnemonics.setLocalizedText(useMultiView, "&Use MultiView");
4.205 + gridBagConstraints = new java.awt.GridBagConstraints();
4.206 + gridBagConstraints.gridx = 1;
4.207 + gridBagConstraints.gridy = 2;
4.208 + gridBagConstraints.gridwidth = 2;
4.209 + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
4.210 + add(useMultiView, gridBagConstraints);
4.211 + }// </editor-fold>//GEN-END:initComponents
4.212
4.213 private void btnIconActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnIconActionPerformed
4.214 JFileChooser chooser = UIUtil.getIconFileChooser(txtIcon.getText());
4.215 @@ -352,7 +365,7 @@
4.216 private javax.swing.JLabel createdFiles;
4.217 private javax.swing.JTextArea createdFilesValue;
4.218 private javax.swing.JLabel filler;
4.219 - private javax.swing.JLabel lblIcon;
4.220 + private javax.swing.JLabel lblIcon2;
4.221 private javax.swing.JLabel lblPackageName;
4.222 private javax.swing.JLabel lblPrefix;
4.223 private javax.swing.JLabel lblProjectName;
4.224 @@ -361,6 +374,7 @@
4.225 private javax.swing.JTextField txtIcon;
4.226 private javax.swing.JTextField txtPrefix;
4.227 private javax.swing.JTextField txtProjectName;
4.228 + private javax.swing.JCheckBox useMultiView;
4.229 // End of variables declaration//GEN-END:variables
4.230
4.231 private void initAccessibility() {
5.1 --- a/apisupport.project/src/org/netbeans/modules/apisupport/project/ui/wizard/loader/NewLoaderIterator.java Wed May 25 16:24:45 2011 +0200
5.2 +++ b/apisupport.project/src/org/netbeans/modules/apisupport/project/ui/wizard/loader/NewLoaderIterator.java Wed May 25 16:50:33 2011 +0200
5.3 @@ -115,6 +115,7 @@
5.4 private boolean extensionBased = true;
5.5 private String extension;
5.6 private String namespace;
5.7 + private boolean useMultiview;
5.8
5.9 private CreatedModifiedFiles files;
5.10
5.11 @@ -161,6 +162,25 @@
5.12 public void setExtensionBased(boolean extensionBased) {
5.13 this.extensionBased = extensionBased;
5.14 }
5.15 +
5.16 + public boolean canUseMultiview() {
5.17 + try {
5.18 + SpecificationVersion v = getModuleInfo().getDependencyVersion("org.netbeans.core.multiview"); // NOI18N
5.19 + if (v == null) {
5.20 + return false;
5.21 + }
5.22 + return v.compareTo(new SpecificationVersion("1.24")) >= 0; // NOI18N
5.23 + } catch (IOException ex) {
5.24 + return false;
5.25 + }
5.26 + }
5.27 + public boolean isUseMultiview() {
5.28 + return useMultiview;
5.29 + }
5.30 +
5.31 + public void setUseMultiview(boolean useMultiview) {
5.32 + this.useMultiview = useMultiview;
5.33 + }
5.34
5.35 public String getExtension() {
5.36 return extension;
5.37 @@ -186,7 +206,7 @@
5.38 boolean loaderlessObject;
5.39 boolean lookupReadyObject;
5.40 try {
5.41 - SpecificationVersion current = model.getModuleInfo().getDependencyVersion("org.openide.loaders");
5.42 + SpecificationVersion current = model.getModuleInfo().getDependencyVersion("org.openide.loaders"); // NOI18N
5.43 loaderlessObject = current == null || current.compareTo(new SpecificationVersion("7.1")) >= 0; // NOI18N
5.44 lookupReadyObject = current == null || current.compareTo(new SpecificationVersion("6.0")) >= 0; // NOI18N
5.45 } catch (IOException ex) {
5.46 @@ -250,7 +270,11 @@
5.47 String doName = model.getDefaultPackagePath(namePrefix + "DataObject.java", false); // NOI18N
5.48 template = null;
5.49 if (loaderlessObject) {
5.50 - template = CreatedModifiedFiles.getTemplate("templateDataObjectInLayer.java");//NOI18N
5.51 + if (model.isUseMultiview()) {
5.52 + template = CreatedModifiedFiles.getTemplate("templateDataObjectMulti.java");//NOI18N
5.53 + } else {
5.54 + template = CreatedModifiedFiles.getTemplate("templateDataObjectInLayer.java");//NOI18N
5.55 + }
5.56 } else {
5.57 if (lookupReadyObject) {
5.58 template = CreatedModifiedFiles.getTemplate("templateDataObjectWithLookup.java");//NOI18N
5.59 @@ -260,6 +284,14 @@
5.60 template = CreatedModifiedFiles.getTemplate("templateDataObject.java");//NOI18N
5.61 }
5.62 fileChanges.add(fileChanges.createFileWithSubstitutions(doName, template, replaceTokens));
5.63 + if (model.isUseMultiview()) {
5.64 + String formName = model.getDefaultPackagePath(namePrefix + "VisualElement.form", false); // NOI18N
5.65 + String javaName = model.getDefaultPackagePath(namePrefix + "VisualElement.java", false); // NOI18N
5.66 + FileObject java = CreatedModifiedFiles.getTemplate("templateDataObjectMultiForm.java");
5.67 + FileObject form = CreatedModifiedFiles.getTemplate("templateDataObjectMultiForm.form");
5.68 + fileChanges.add(fileChanges.createFile(formName, form));
5.69 + fileChanges.add(fileChanges.createFileWithSubstitutions(javaName, java, replaceTokens));
5.70 + }
5.71
5.72 if (!loaderlessObject) {
5.73 // 3. node file
5.74 @@ -288,6 +320,12 @@
5.75 if (isEditable) {
5.76 fileChanges.add(fileChanges.addModuleDependency("org.openide.windows")); //NOI18N
5.77 }
5.78 + if (model.isUseMultiview()) {
5.79 + fileChanges.add(fileChanges.addModuleDependency("org.netbeans.core.multiview")); //NOI18N
5.80 + String bundlePath = model.getDefaultPackagePath("Bundle.properties", true); // NOI18N
5.81 + fileChanges.add(fileChanges.bundleKey(bundlePath, "LBL_" + namePrefix + "_EDITOR", // NOI18N
5.82 + "Source")); //NOI18N
5.83 + }
5.84
5.85 if (!loaderlessObject) {
5.86 // 6. update/create bundle file
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/apisupport.project/src/org/netbeans/modules/apisupport/project/ui/wizard/loader/templateDataObjectMulti.javx Wed May 25 16:50:33 2011 +0200
6.3 @@ -0,0 +1,62 @@
6.4 +<#assign licenseFirst = "/*">
6.5 +<#assign licensePrefix = " * ">
6.6 +<#assign licenseLast = " */">
6.7 +<#include "../Licenses/license-${project.license}.txt">
6.8 +
6.9 +package ${PACKAGENAME};
6.10 +
6.11 +import java.io.IOException;
6.12 +import java.util.concurrent.Callable;
6.13 +import org.netbeans.core.api.multiview.MultiViews;
6.14 +import org.netbeans.core.spi.multiview.MultiViewElement;
6.15 +import org.netbeans.core.spi.multiview.text.MultiViewEditorElement;
6.16 +import org.openide.filesystems.FileObject;
6.17 +import org.openide.loaders.DataNode;
6.18 +import org.openide.loaders.DataObjectExistsException;
6.19 +import org.openide.loaders.MultiDataObject;
6.20 +import org.openide.loaders.MultiFileLoader;
6.21 +import org.openide.text.DataEditorSupport;
6.22 +import org.openide.nodes.Children;
6.23 +import org.openide.nodes.CookieSet;
6.24 +import org.openide.nodes.Node;
6.25 +import org.openide.text.CloneableEditorSupport;
6.26 +import org.openide.text.CloneableEditorSupport.Pane;
6.27 +import org.openide.util.Lookup;
6.28 +import org.openide.windows.TopComponent;
6.29 +
6.30 +public class ${PREFIX}DataObject extends MultiDataObject implements Callable<Pane> {
6.31 +
6.32 + public ${PREFIX}DataObject(FileObject pf, MultiFileLoader loader) throws DataObjectExistsException, IOException {
6.33 + super(pf, loader);
6.34 + CookieSet cookies = getCookieSet();
6.35 + cookies.add((Node.Cookie) DataEditorSupport.create(this, getPrimaryEntry(), cookies, this));
6.36 + }
6.37 +
6.38 + @Override
6.39 + protected Node createNodeDelegate() {
6.40 + return new DataNode(this, Children.LEAF, getLookup());
6.41 + }
6.42 +
6.43 + @Override
6.44 + public Lookup getLookup() {
6.45 + return getCookieSet().getLookup();
6.46 + }
6.47 +
6.48 + @Override
6.49 + public Pane call() {
6.50 + return (Pane)MultiViews.createCloneableMultiView("${MIMETYPE}", this);
6.51 + }
6.52 +
6.53 + @MultiViewElement.Registration(
6.54 + displayName = "#LBL_${PREFIX}_EDITOR",
6.55 + iconBase = "${ICONPATH}",
6.56 + mimeType = "${MIMETYPE}",
6.57 + persistenceType = TopComponent.PERSISTENCE_ONLY_OPENED,
6.58 + preferredID = "${PREFIX}",
6.59 + position = 1000
6.60 + )
6.61 + public static MultiViewEditorElement createEditor(Lookup lkp) {
6.62 + return new MultiViewEditorElement(lkp);
6.63 + }
6.64 +
6.65 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/apisupport.project/src/org/netbeans/modules/apisupport/project/ui/wizard/loader/templateDataObjectMultiVisual.forx Wed May 25 16:50:33 2011 +0200
7.3 @@ -0,0 +1,24 @@
7.4 +<?xml version="1.0" encoding="UTF-8" ?>
7.5 +
7.6 +<Form version="1.3" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
7.7 + <AuxValues>
7.8 + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
7.9 + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
7.10 + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
7.11 + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
7.12 + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
7.13 + </AuxValues>
7.14 +
7.15 + <Layout>
7.16 + <DimensionLayout dim="0">
7.17 + <Group type="103" groupAlignment="0" attributes="0">
7.18 + <EmptySpace min="0" pref="400" max="32767" attributes="0"/>
7.19 + </Group>
7.20 + </DimensionLayout>
7.21 + <DimensionLayout dim="1">
7.22 + <Group type="103" groupAlignment="0" attributes="0">
7.23 + <EmptySpace min="0" pref="300" max="32767" attributes="0"/>
7.24 + </Group>
7.25 + </DimensionLayout>
7.26 + </Layout>
7.27 +</Form>
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/apisupport.project/src/org/netbeans/modules/apisupport/project/ui/wizard/loader/templateDataObjectMultiVisual.javx Wed May 25 16:50:33 2011 +0200
8.3 @@ -0,0 +1,132 @@
8.4 +<#assign licenseFirst = "/*">
8.5 +<#assign licensePrefix = " * ">
8.6 +<#assign licenseLast = " */">
8.7 +<#include "../Licenses/license-${project.license}.txt">
8.8 +
8.9 +package ${PACKAGENAME};
8.10 +
8.11 +import javax.swing.Action;
8.12 +import javax.swing.JComponent;
8.13 +import javax.swing.JPanel;
8.14 +import javax.swing.JToolBar;
8.15 +import org.netbeans.core.spi.multiview.CloseOperationState;
8.16 +import org.netbeans.core.spi.multiview.MultiViewElement;
8.17 +import org.netbeans.core.spi.multiview.MultiViewElementCallback;
8.18 +import org.openide.awt.UndoRedo;
8.19 +import org.openide.util.Lookup;
8.20 +import org.openide.util.NbBundle.Messages;
8.21 +import org.openide.windows.TopComponent;
8.22 +
8.23 +@MultiViewElement.Registration(
8.24 + displayName = "#LBL_${PREFIX}_VISUAL",
8.25 + iconBase = "${ICONPATH}",
8.26 + mimeType = "${MIMETYPE}",
8.27 + persistenceType = TopComponent.PERSISTENCE_NEVER,
8.28 + preferredID = "${PREFIX}Visual",
8.29 + position = 2000
8.30 +)
8.31 +@Messages({
8.32 + "LBL_${PREFIX}_VISUAL=Visual"
8.33 +})
8.34 +public final class ${PREFIX}VisualElement extends JPanel implements MultiViewElement {
8.35 + private ${PREFIX}DataObject obj;
8.36 + private JToolBar toolbar = new JToolBar();
8.37 + private transient MultiViewElementCallback callback;
8.38 +
8.39 + public ${PREFIX}VisualElement(Lookup lkp) {
8.40 + obj = lkp.lookup(${PREFIX}DataObject.class);
8.41 + assert obj != null;
8.42 + initComponents();
8.43 + }
8.44 +
8.45 + @Override
8.46 + public String getName() {
8.47 + return "${PREFIX}VisualElement";
8.48 + }
8.49 +
8.50 + /** This method is called from within the constructor to
8.51 + * initialize the form.
8.52 + * WARNING: Do NOT modify this code. The content of this method is
8.53 + * always regenerated by the Form Editor.
8.54 + */
8.55 + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
8.56 + private void initComponents() {
8.57 +
8.58 + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
8.59 + this.setLayout(layout);
8.60 + layout.setHorizontalGroup(
8.61 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
8.62 + .addGap(0, 400, Short.MAX_VALUE)
8.63 + );
8.64 + layout.setVerticalGroup(
8.65 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
8.66 + .addGap(0, 300, Short.MAX_VALUE)
8.67 + );
8.68 + }// </editor-fold>//GEN-END:initComponents
8.69 +
8.70 +
8.71 + // Variables declaration - do not modify//GEN-BEGIN:variables
8.72 + // End of variables declaration//GEN-END:variables
8.73 +
8.74 +
8.75 + @Override
8.76 + public JComponent getVisualRepresentation() {
8.77 + return this;
8.78 + }
8.79 +
8.80 + @Override
8.81 + public JComponent getToolbarRepresentation() {
8.82 + return toolbar;
8.83 + }
8.84 +
8.85 + @Override
8.86 + public Action[] getActions() {
8.87 + return new Action[0];
8.88 + }
8.89 +
8.90 + @Override
8.91 + public Lookup getLookup() {
8.92 + return obj.getLookup();
8.93 + }
8.94 +
8.95 + @Override
8.96 + public void componentOpened() {
8.97 + }
8.98 +
8.99 + @Override
8.100 + public void componentClosed() {
8.101 + }
8.102 +
8.103 + @Override
8.104 + public void componentShowing() {
8.105 + }
8.106 +
8.107 + @Override
8.108 + public void componentHidden() {
8.109 + }
8.110 +
8.111 + @Override
8.112 + public void componentActivated() {
8.113 + }
8.114 +
8.115 + @Override
8.116 + public void componentDeactivated() {
8.117 + }
8.118 +
8.119 + @Override
8.120 + public UndoRedo getUndoRedo() {
8.121 + return UndoRedo.NONE;
8.122 + }
8.123 +
8.124 + @Override
8.125 + public void setMultiViewCallback(MultiViewElementCallback callback) {
8.126 + this.callback = callback;
8.127 + }
8.128 +
8.129 + @Override
8.130 + public CloseOperationState canCloseElement() {
8.131 + return CloseOperationState.STATE_OK;
8.132 + }
8.133 +
8.134 +}
8.135 +
9.1 --- a/core.multiview/apichanges.xml Wed May 25 16:24:45 2011 +0200
9.2 +++ b/core.multiview/apichanges.xml Wed May 25 16:50:33 2011 +0200
9.3 @@ -103,12 +103,58 @@
9.4 <apidefs>
9.5 <apidef name="multiview_api">MultiView API</apidef>
9.6 <apidef name="multiview_spi">MultiView SPI</apidef>
9.7 + <apidef name="multiview_text">MultiView Text SPI</apidef>
9.8 <!-- etc. -->
9.9 </apidefs>
9.10
9.11 <!-- ACTUAL CHANGES BEGIN HERE: -->
9.12
9.13 <changes>
9.14 + <change id="MultiViewEditorElement">
9.15 + <api name="multiview_text"/>
9.16 + <summary>MultiViewEditorElement</summary>
9.17 + <version major="1" minor="22"/>
9.18 + <date day="14" month="4" year="2011"/>
9.19 + <author login="jtulach"/>
9.20 + <compatibility addition="yes"/>
9.21 + <description>
9.22 + Common support class for integrating multi view and text
9.23 + infrastructure.
9.24 + </description>
9.25 + <class package="org.netbeans.core.spi.multiview.text" name="MultiViewEditorElement"/>
9.26 + <issue number="196810"/>
9.27 + </change>
9.28 + <change id="MultiViews.create.mimetype">
9.29 + <api name="multiview_api"/>
9.30 + <summary>MultiViews.create for MIME type</summary>
9.31 + <version major="1" minor="22"/>
9.32 + <date day="14" month="4" year="2011"/>
9.33 + <author login="jtulach"/>
9.34 + <compatibility addition="yes"/>
9.35 + <description>
9.36 + New factory methods to create multiview components for a given
9.37 + mime type.
9.38 + </description>
9.39 + <class package="org.netbeans.core.api.multiview" name="MultiViews"/>
9.40 + <issue number="196810"/>
9.41 + </change>
9.42 + <change id="MultiViewElement.Registration">
9.43 + <api name="multiview_spi"/>
9.44 + <summary>@MultiViewElement.Registration</summary>
9.45 + <version major="1" minor="22"/>
9.46 + <date day="14" month="4" year="2011"/>
9.47 + <author login="jtulach"/>
9.48 + <compatibility addition="yes"/>
9.49 + <description>
9.50 + Declarative way to register
9.51 + <a href="@TOP@org/netbeans/core/spi/multiview/MultiViewElement.html">
9.52 + MultiViewElement</a> via
9.53 + <a href="@TOP@org/netbeans/core/spi/multiview/MultiViewElement.Registration.html">
9.54 + @Registration</a> annotation.
9.55 + </description>
9.56 + <class package="org.netbeans.core.spi.multiview" name="MultiViewElement"/>
9.57 + <issue number="196810"/>
9.58 + </change>
9.59 <change>
9.60 <api name="multiview_spi"/>
9.61 <summary>Added marker interface SourceViewMarker to identify elements with sourcecode.</summary>
10.1 --- a/core.multiview/arch.xml Wed May 25 16:24:45 2011 +0200
10.2 +++ b/core.multiview/arch.xml Wed May 25 16:50:33 2011 +0200
10.3 @@ -71,8 +71,16 @@
10.4 </question>
10.5 -->
10.6 <answer id="arch-overall">
10.7 - <api name="MultiView" group="java" type="export" category="devel"
10.8 - url="@TOP@/overview-summary.html"/>
10.9 + <api name="MultiView" group="java" type="export" category="stable"
10.10 + url="@TOP@/overview-summary.html">
10.11 + Provides support for creation of editors composed from
10.12 + multiple (independent) elements. One can either specify
10.13 + the <a href="@TOP@/org/netbeans/core/spi/multiview/MultiViewFactory.html">
10.14 + elements directly</a>
10.15 + or read them from a
10.16 + <a href="@TOP@/org/netbeans/core/api/multiview/MultiViews.html">
10.17 + declarative registration</a> for a particular mime type.
10.18 + </api>
10.19
10.20 </answer>
10.21
11.1 --- a/core.multiview/manifest.mf Wed May 25 16:24:45 2011 +0200
11.2 +++ b/core.multiview/manifest.mf Wed May 25 16:50:33 2011 +0200
11.3 @@ -1,6 +1,6 @@
11.4 Manifest-Version: 1.0
11.5 OpenIDE-Module: org.netbeans.core.multiview/1
11.6 -OpenIDE-Module-Specification-Version: 1.23
11.7 +OpenIDE-Module-Specification-Version: 1.24
11.8 OpenIDE-Module-Localizing-Bundle: org/netbeans/core/multiview/resources/Bundle.properties
11.9 OpenIDE-Module-Layer: org/netbeans/core/multiview/resources/mf-layer.xml
11.10 AutoUpdate-Essential-Module: true
12.1 --- a/core.multiview/nbproject/project.xml Wed May 25 16:24:45 2011 +0200
12.2 +++ b/core.multiview/nbproject/project.xml Wed May 25 16:50:33 2011 +0200
12.3 @@ -75,6 +75,11 @@
12.4 </run-dependency>
12.5 </dependency>
12.6 <dependency>
12.7 + <code-name-base>org.openide.filesystems</code-name-base>
12.8 + <build-prerequisite/>
12.9 + <compile-dependency/>
12.10 + </dependency>
12.11 + <dependency>
12.12 <code-name-base>org.openide.nodes</code-name-base>
12.13 <build-prerequisite/>
12.14 <compile-dependency/>
12.15 @@ -87,7 +92,7 @@
12.16 <build-prerequisite/>
12.17 <compile-dependency/>
12.18 <run-dependency>
12.19 - <specification-version>6.16</specification-version>
12.20 + <specification-version>6.39</specification-version>
12.21 </run-dependency>
12.22 </dependency>
12.23 <dependency>
12.24 @@ -119,6 +124,11 @@
12.25 <test-type>
12.26 <name>unit</name>
12.27 <test-dependency>
12.28 + <code-name-base>org.netbeans.modules.editor.mimelookup.impl</code-name-base>
12.29 + <recursive/>
12.30 + <compile-dependency/>
12.31 + </test-dependency>
12.32 + <test-dependency>
12.33 <code-name-base>org.netbeans.core.multiview</code-name-base>
12.34 <recursive/>
12.35 <compile-dependency/>
12.36 @@ -141,11 +151,17 @@
12.37 <compile-dependency/>
12.38 <test/>
12.39 </test-dependency>
12.40 + <test-dependency>
12.41 + <code-name-base>org.openide.util.lookup</code-name-base>
12.42 + <compile-dependency/>
12.43 + <test/>
12.44 + </test-dependency>
12.45 </test-type>
12.46 </test-dependencies>
12.47 <public-packages>
12.48 <package>org.netbeans.core.api.multiview</package>
12.49 <package>org.netbeans.core.spi.multiview</package>
12.50 + <package>org.netbeans.core.spi.multiview.text</package>
12.51 </public-packages>
12.52 </data>
12.53 </configuration>
13.1 --- a/core.multiview/src/org/netbeans/core/api/multiview/MultiViews.java Wed May 25 16:24:45 2011 +0200
13.2 +++ b/core.multiview/src/org/netbeans/core/api/multiview/MultiViews.java Wed May 25 16:50:33 2011 +0200
13.3 @@ -44,26 +44,32 @@
13.4
13.5 package org.netbeans.core.api.multiview;
13.6
13.7 -import javax.swing.Action;
13.8 -import javax.swing.JPanel;
13.9 -import javax.swing.JToolBar;
13.10 +import java.io.Serializable;
13.11 +import org.netbeans.api.editor.mimelookup.MimeLookup;
13.12 import org.netbeans.core.multiview.MultiViewCloneableTopComponent;
13.13 import org.netbeans.core.multiview.MultiViewTopComponent;
13.14 +import org.netbeans.core.spi.multiview.MultiViewElement;
13.15 +import org.netbeans.core.spi.multiview.MultiViewElement.Registration;
13.16 +import org.openide.text.CloneableEditorSupport;
13.17 +import org.openide.text.CloneableEditorSupport.Pane;
13.18 import org.openide.util.Lookup;
13.19 +import org.openide.windows.CloneableTopComponent;
13.20 +import org.openide.windows.Mode;
13.21 import org.openide.windows.TopComponent;
13.22 +import org.openide.windows.WindowManager;
13.23
13.24 /** Factory class for handling multi views.
13.25 *
13.26 * @author Dafe Simonek, Milos Kleint
13.27 */
13.28 -public final class MultiViews {
13.29 + public final class MultiViews {
13.30
13.31 /** Factory class, no instances. */
13.32 private MultiViews() {
13.33 }
13.34
13.35 /**
13.36 - * For advanced manupulation with Multiview component, the handler can be requested
13.37 + * For advanced manipulation with Multiview component, the handler can be requested
13.38 * @return handle that one can use for manipulation with multiview component.
13.39 */
13.40 public static MultiViewHandler findMultiViewHandler(TopComponent tc) {
13.41 @@ -77,5 +83,49 @@
13.42 }
13.43 return null;
13.44 }
13.45 -
13.46 +
13.47 + /** Factory method to create multiview for a given mime type. The list
13.48 + * of {@link MultiViewElement}s to display is taken from {@link MimeLookup#getLookup}.
13.49 + * The <code>context</code> parameter has to be Serializable, so the top component
13.50 + * can be persisted and later, when deserialized, it can again recreate the
13.51 + * {@link Lookup}. Suitable candidate for an object that implements both
13.52 + * {@link Serializable} as well as {@link org.openide.util.Lookup.Provider} is
13.53 + * <a href="@org-openide-loaders@/org/openide/loaders/DataObject.html">DataObject</a>.
13.54 + * To register your elements into particular mime type see {@link Registration}.
13.55 + *
13.56 + * @param context lookup provider representing the object to displayed in the multiview
13.57 + * @param mimeType the mime type to seek for elements in
13.58 + * @return multiview component
13.59 + * @since 1.22
13.60 + */
13.61 + public static <T extends Serializable & Lookup.Provider> TopComponent createMultiView(
13.62 + String mimeType, T context
13.63 + ) {
13.64 + MultiViewTopComponent tc = new MultiViewTopComponent();
13.65 + tc.setMimeLookup(mimeType, context);
13.66 + return tc;
13.67 + }
13.68 +
13.69 + /** Factory method to create cloneable multiview for a given mime type.
13.70 + * The way to obtain individual elements is the same as in
13.71 + * {@link #createMultiView}. By default the returned component is put
13.72 + * into "editor" mode, if it exists.
13.73 + *
13.74 + * @param context lookup representing the object to be displayed in the multiview
13.75 + * @param mimeType the mime type to seek for elements in
13.76 + * @return cloneable multiview component also implementing {@link Pane} interface
13.77 + * @since 1.22
13.78 + */
13.79 + public static <T extends Serializable & Lookup.Provider> CloneableTopComponent createCloneableMultiView(
13.80 + String mimeType, T context
13.81 + ) {
13.82 + MultiViewCloneableTopComponent tc = new MultiViewCloneableTopComponent();
13.83 + tc.setMimeLookup(mimeType, context);
13.84 + // dock into editor mode if possible.
13.85 + Mode editorMode = WindowManager.getDefault().findMode(CloneableEditorSupport.EDITOR_MODE);
13.86 + if (editorMode != null) {
13.87 + editorMode.dockInto(tc);
13.88 + }
13.89 + return tc;
13.90 + }
13.91 }
14.1 --- a/core.multiview/src/org/netbeans/core/api/multiview/package.html Wed May 25 16:24:45 2011 +0200
14.2 +++ b/core.multiview/src/org/netbeans/core/api/multiview/package.html Wed May 25 16:50:33 2011 +0200
14.3 @@ -43,7 +43,8 @@
14.4 -->
14.5 </head>
14.6 <body>
14.7 -MultiView API lets the developers manipulate existing multiview
14.8 +MultiView API lets the developers create new multiview components
14.9 +(without specifying their content), manipulate existing multiview
14.10 components, eg. examine what is inside the component, request focus for
14.11 one of the views etc.<br>
14.12 This API allows to access the multiview component's content.<p>
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2 +++ b/core.multiview/src/org/netbeans/core/multiview/ContextAwareDescription.java Wed May 25 16:50:33 2011 +0200
15.3 @@ -0,0 +1,53 @@
15.4 +/*
15.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
15.6 + *
15.7 + * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
15.8 + *
15.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
15.10 + * Other names may be trademarks of their respective owners.
15.11 + *
15.12 + * The contents of this file are subject to the terms of either the GNU
15.13 + * General Public License Version 2 only ("GPL") or the Common
15.14 + * Development and Distribution License("CDDL") (collectively, the
15.15 + * "License"). You may not use this file except in compliance with the
15.16 + * License. You can obtain a copy of the License at
15.17 + * http://www.netbeans.org/cddl-gplv2.html
15.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
15.19 + * specific language governing permissions and limitations under the
15.20 + * License. When distributing the software, include this License Header
15.21 + * Notice in each file and include the License file at
15.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
15.23 + * particular file as subject to the "Classpath" exception as provided
15.24 + * by Oracle in the GPL Version 2 section of the License file that
15.25 + * accompanied this code. If applicable, add the following below the
15.26 + * License Header, with the fields enclosed by brackets [] replaced by
15.27 + * your own identifying information:
15.28 + * "Portions Copyrighted [year] [name of copyright owner]"
15.29 + *
15.30 + * If you wish your version of this file to be governed by only the CDDL
15.31 + * or only the GPL Version 2, indicate your decision by adding
15.32 + * "[Contributor] elects to include this software in this distribution
15.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
15.34 + * single choice of license, a recipient has the option to distribute
15.35 + * your version of this file under either the CDDL, the GPL Version 2 or
15.36 + * to extend the choice of license to its licensees as provided above.
15.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
15.38 + * Version 2 license, then the option applies only if the new code is
15.39 + * made subject to such option by the copyright holder.
15.40 + *
15.41 + * Contributor(s):
15.42 + *
15.43 + * Portions Copyrighted 2011 Sun Microsystems, Inc.
15.44 + */
15.45 +package org.netbeans.core.multiview;
15.46 +
15.47 +import org.netbeans.core.spi.multiview.MultiViewDescription;
15.48 +import org.openide.util.Lookup;
15.49 +
15.50 +/** Possibly part of an API in future.
15.51 + *
15.52 + * @author Jaroslav Tulach <jtulach@netbeans.org>
15.53 + */
15.54 +public interface ContextAwareDescription extends MultiViewDescription {
15.55 + public ContextAwareDescription createContextAwareDescription(Lookup context);
15.56 +}
16.1 --- a/core.multiview/src/org/netbeans/core/multiview/MultiViewCloneableTopComponent.java Wed May 25 16:24:45 2011 +0200
16.2 +++ b/core.multiview/src/org/netbeans/core/multiview/MultiViewCloneableTopComponent.java Wed May 25 16:50:33 2011 +0200
16.3 @@ -48,7 +48,6 @@
16.4 import java.util.Collection;
16.5 import java.util.Iterator;
16.6 import java.util.Map;
16.7 -import java.util.logging.Level;
16.8 import java.util.logging.Logger;
16.9 import javax.swing.Action;
16.10 import javax.swing.SwingUtilities;
16.11 @@ -61,13 +60,14 @@
16.12 import org.openide.awt.UndoRedo;
16.13 import org.openide.text.CloneableEditorSupport;
16.14 import org.openide.util.HelpCtx;
16.15 +import org.openide.util.Lookup;
16.16 import org.openide.windows.CloneableTopComponent;
16.17 import org.openide.windows.TopComponent;
16.18
16.19
16.20 /** Special subclass of TopComponent which shows and handles set of
16.21 * MultiViewElements, shows them in switchable toggle buttons style, along
16.22 - * with toolbsrs af actions asociated with individual view elements.
16.23 + * with toolbars and actions associated with individual view elements.
16.24 *
16.25 *
16.26 * @author Dafe Simonek, Milos Kleint
16.27 @@ -92,6 +92,9 @@
16.28 // setFocusable(false);
16.29 }
16.30
16.31 + public <T extends Serializable & Lookup.Provider> void setMimeLookup(String mimeType, T context) {
16.32 + peer.setMimeLookup(mimeType, context);
16.33 + }
16.34
16.35 public void setMultiViewDescriptions(MultiViewDescription[] descriptions, MultiViewDescription defaultDesc) {
16.36 peer.setMultiViewDescriptions(descriptions, defaultDesc);
16.37 @@ -183,8 +186,15 @@
16.38 protected String preferredID() {
16.39 return peer.preferredID();
16.40 }
16.41 -
16.42 -
16.43 +
16.44 + @Override
16.45 + protected CloneableTopComponent createClonedObject() {
16.46 + MultiViewCloneableTopComponent tc = new MultiViewCloneableTopComponent();
16.47 + tc.setMultiViewDescriptions(peer.model.getDescriptions(), peer.model.getActiveDescription());;
16.48 + tc.setCloseOperationHandler(peer.closeHandler);
16.49 + tc.peer.copyMimeContext(peer);
16.50 + return tc;
16.51 + }
16.52
16.53 /** Serialize this top component.
16.54 * Subclasses wishing to store state must call the super method, then write to the stream.
16.55 @@ -251,7 +261,7 @@
16.56
16.57 MultiViewDescription[] descs = peer.model.getDescriptions();
16.58 for (MultiViewDescription desc : descs) {
16.59 - if (desc instanceof SourceViewMarker) {
16.60 + if (isSourceView(desc)) {
16.61 el = peer.model.getElementForDescription(desc);
16.62 if (el.getVisualRepresentation() instanceof CloneableEditorSupport.Pane) {
16.63 return el;
16.64 @@ -324,7 +334,17 @@
16.65 MultiViewElementCallback call = peer.getModel().getCallbackForElement(paneEl);
16.66 call.requestVisible();
16.67 }
16.68 - }
16.69 + }
16.70 +
16.71 + static boolean isSourceView(MultiViewDescription desc) {
16.72 + if (desc instanceof SourceViewMarker) {
16.73 + return true;
16.74 + }
16.75 + if (desc instanceof SourceCheckDescription) {
16.76 + return ((SourceCheckDescription)desc).isSourceView();
16.77 + }
16.78 + return false;
16.79 + }
16.80
16.81
16.82 /**
17.1 --- a/core.multiview/src/org/netbeans/core/multiview/MultiViewPeer.java Wed May 25 16:24:45 2011 +0200
17.2 +++ b/core.multiview/src/org/netbeans/core/multiview/MultiViewPeer.java Wed May 25 16:50:33 2011 +0200
17.3 @@ -52,6 +52,7 @@
17.4 import java.io.ObjectOutput;
17.5 import java.io.Serializable;
17.6 import java.util.ArrayList;
17.7 +import java.util.Arrays;
17.8 import java.util.Collection;
17.9 import java.util.HashMap;
17.10 import java.util.Iterator;
17.11 @@ -89,18 +90,19 @@
17.12
17.13 /** Special subclass of TopComponent which shows and handles set of
17.14 * MultiViewElements, shows them in switchable toggle buttons style, along
17.15 - * with toolbsrs af actions asociated with individual view elements.
17.16 + * with toolbars of actions associated with individual view elements.
17.17 *
17.18 *
17.19 * @author Dafe Simonek, Milos Kleint
17.20 */
17.21 -
17.22 -
17.23 public final class MultiViewPeer {
17.24
17.25 static final String MULTIVIEW_ID = "MultiView-"; //NOI18N
17.26
17.27 private static final String TOOLBAR_VISIBLE_PROP = /* org.netbeans.api.editor.settings.SimpleValueNames.TOOLBAR_VISIBLE_PROP */ "toolbarVisible"; // NOI18N
17.28 +
17.29 + private Lookup.Provider context;
17.30 + private String mimeType;
17.31
17.32 MultiViewModel model;
17.33 TabsComponent tabs;
17.34 @@ -132,10 +134,38 @@
17.35 delegateUndoRedo = new DelegateUndoRedo();
17.36 }
17.37
17.38 -
17.39 + void copyMimeContext(MultiViewPeer other) {
17.40 + this.context = other.context;
17.41 + this.mimeType = other.mimeType;
17.42 + }
17.43 +
17.44 + /** @param context context needs to be also serializable */
17.45 + public void setMimeLookup(String mimeType, Lookup.Provider context) {
17.46 + this.context = context;
17.47 + this.mimeType = mimeType;
17.48 +
17.49 + List<MultiViewDescription> arr = new ArrayList<MultiViewDescription>();
17.50 + final Lookup lkp = MimeLookup.getLookup(mimeType);
17.51 + for (ContextAwareDescription d : lkp.lookupAll(ContextAwareDescription.class)) {
17.52 + d = d.createContextAwareDescription(context.getLookup());
17.53 + arr.add(d);
17.54 + }
17.55 + if (model != null) {
17.56 + model.removeElementSelectionListener(selListener);
17.57 + }
17.58 + model = new MultiViewModel(arr.toArray(new MultiViewDescription[0]), arr.get(0), factory);
17.59 + model.addElementSelectionListener(selListener);
17.60 + tabs.setModel(model);
17.61 + CloseOperationHandler h = lkp.lookup(CloseOperationHandler.class);
17.62 + if (h == null) {
17.63 + h = SpiAccessor.DEFAULT.createDefaultCloseHandler();
17.64 + }
17.65 + closeHandler = h;
17.66 + }
17.67
17.68
17.69 public void setMultiViewDescriptions(MultiViewDescription[] descriptions, MultiViewDescription defaultDesc) {
17.70 + assert context == null;
17.71 if (model != null) {
17.72 model.removeElementSelectionListener(selListener);
17.73 }
17.74 @@ -145,6 +175,7 @@
17.75 }
17.76
17.77 public void setCloseOperationHandler(CloseOperationHandler handler) {
17.78 + assert context == null;
17.79 closeHandler = handler;
17.80 }
17.81
17.82 @@ -229,12 +260,16 @@
17.83 jc.setOpaque(false);
17.84 tabs.setInnerToolBar(jc);
17.85 tabs.setToolbarBarVisible(isToolbarVisible());
17.86 - editorSettingsPreferences.addPreferenceChangeListener(editorSettingsListener);
17.87 + if (editorSettingsPreferences != null) {
17.88 + editorSettingsPreferences.addPreferenceChangeListener(editorSettingsListener);
17.89 + }
17.90 }
17.91
17.92 void peerComponentHidden() {
17.93 model.getActiveElement().componentHidden();
17.94 - editorSettingsPreferences.removePreferenceChangeListener(editorSettingsListener);
17.95 + if (editorSettingsPreferences != null) {
17.96 + editorSettingsPreferences.removePreferenceChangeListener(editorSettingsListener);
17.97 + }
17.98 }
17.99
17.100 void peerComponentDeactivated() {
17.101 @@ -382,7 +417,7 @@
17.102 MultiViewDescription[] descs = model.getDescriptions();
17.103 int type = TopComponent.PERSISTENCE_NEVER;
17.104 for (int i = 0; i < descs.length; i++) {
17.105 - if (!(descs[i] instanceof Serializable)) {
17.106 + if (context == null && !(descs[i] instanceof Serializable)) {
17.107 Logger.getLogger(MultiViewTopComponent.class.getName()).warning(
17.108 "The MultiviewDescription instance " + descs[i].getClass() + " is not serializable. Cannot persist TopComponent.");
17.109 type = TopComponent.PERSISTENCE_NEVER;
17.110 @@ -421,20 +456,32 @@
17.111 * @param out the stream to serialize to
17.112 */
17.113 void peerWriteExternal (ObjectOutput out) throws IOException {
17.114 - if (closeHandler != null) {
17.115 - if (closeHandler instanceof Serializable) {
17.116 - out.writeObject(closeHandler);
17.117 - } else {
17.118 - //TODO some warning to the SPI programmer
17.119 - Logger.getAnonymousLogger().info(
17.120 - "The CloseOperationHandler isn not serializable. MultiView component id=" + preferredID());
17.121 + boolean fromMime;
17.122 + if (context != null) {
17.123 + out.writeObject(mimeType);
17.124 + out.writeObject(context);
17.125 + fromMime = true;
17.126 + } else {
17.127 + if (closeHandler != null) {
17.128 + if (closeHandler instanceof Serializable) {
17.129 + out.writeObject(closeHandler);
17.130 + } else {
17.131 + //TODO some warning to the SPI programmer
17.132 + Logger.getAnonymousLogger().info(
17.133 + "The CloseOperationHandler isn not serializable. MultiView component id=" + preferredID());
17.134 + }
17.135 }
17.136 + fromMime = false;
17.137 }
17.138 MultiViewDescription[] descs = model.getDescriptions();
17.139 MultiViewDescription curr = model.getActiveDescription();
17.140 int currIndex = 0;
17.141 for (int i = 0; i < descs.length; i++) {
17.142 - out.writeObject(descs[i]);
17.143 + if (!fromMime) {
17.144 + out.writeObject(descs[i]);
17.145 + } else {
17.146 + out.writeObject(descs[i].preferredID());
17.147 + }
17.148 if (descs[i].getPersistenceType() != TopComponent.PERSISTENCE_NEVER) {
17.149 // only those requeTopsted and previously created elements are serialized.
17.150 MultiViewElement elem = model.getElementForDescription(descs[i], false);
17.151 @@ -460,13 +507,32 @@
17.152 int current = 0;
17.153 CloseOperationHandler close = null;
17.154 try {
17.155 + int counting = 0;
17.156 + MultiViewDescription lastDescription = null;
17.157 while (true) {
17.158 Object obj = in.readObject();
17.159 + if ((obj instanceof String) && counting++ == 0) {
17.160 + Lookup.Provider lp = (Lookup.Provider)in.readObject();
17.161 + setMimeLookup((String)obj, lp);
17.162 + descList.addAll(Arrays.asList(model.getDescriptions()));
17.163 + continue;
17.164 + }
17.165 if (obj instanceof MultiViewDescription) {
17.166 - descList.add((MultiViewDescription)obj);
17.167 + lastDescription = (MultiViewDescription)obj;
17.168 + descList.add(lastDescription);
17.169 + }
17.170 + else if (obj instanceof String) {
17.171 + for (MultiViewDescription md : descList) {
17.172 + if (md.preferredID().equals(obj)) {
17.173 + lastDescription = md;
17.174 + break;
17.175 + }
17.176 + }
17.177 }
17.178 else if (obj instanceof MultiViewElement) {
17.179 - map.put(descList.get(descList.size() - 1), (MultiViewElement)obj);
17.180 + assert lastDescription != null;
17.181 + map.put(lastDescription, (MultiViewElement)obj);
17.182 + lastDescription = null;
17.183 }
17.184 else if (obj instanceof Integer) {
17.185 Integer integ = (Integer)obj;
17.186 @@ -478,12 +544,14 @@
17.187 }
17.188 }
17.189 } catch (IOException exc) {
17.190 - //#121119 try preventing model corruption when deserialization of client code fails.
17.191 - if (close == null) {
17.192 + //#121119 try preventing model corruption when deserialization of client code fails.
17.193 + if (context == null) {
17.194 + if (close == null) {
17.195 //TODO some warning to the SPI programmer
17.196 - close = SpiAccessor.DEFAULT.createDefaultCloseHandler();
17.197 + close = SpiAccessor.DEFAULT.createDefaultCloseHandler();
17.198 + }
17.199 + setCloseOperationHandler(close);
17.200 }
17.201 - setCloseOperationHandler(close);
17.202 if (descList.size() > 0) {
17.203 MultiViewDescription[] descs = new MultiViewDescription[descList.size()];
17.204 descs = descList.toArray(descs);
17.205 @@ -497,19 +565,20 @@
17.206
17.207 throw exc;
17.208 }
17.209 - if (close == null) {
17.210 - //TODO some warning to the SPI programmer
17.211 - close = SpiAccessor.DEFAULT.createDefaultCloseHandler();
17.212 + if (context == null) {
17.213 + if (close == null) {
17.214 + //TODO some warning to the SPI programmer
17.215 + close = SpiAccessor.DEFAULT.createDefaultCloseHandler();
17.216 + }
17.217 + setCloseOperationHandler(close);
17.218 }
17.219 - setCloseOperationHandler(close);
17.220 // now that we've read everything, we should set it correctly.
17.221 MultiViewDescription[] descs = new MultiViewDescription[descList.size()];
17.222 descs = descList.toArray(descs);
17.223 MultiViewDescription currDesc = descs[current];
17.224 setDeserializedMultiViewDescriptions(descs, currDesc, map);
17.225 }
17.226 -
17.227 -
17.228 +
17.229 private Action[] getDefaultTCActions() {
17.230 //TODO for each suppoerted peer have one entry..
17.231 if (peer instanceof MultiViewTopComponent) {
17.232 @@ -577,14 +646,20 @@
17.233 public void updateName() {
17.234 // is called before setMultiViewDescriptions() need to check for null.
17.235 if (model != null) {
17.236 - MultiViewElement el = model.getActiveElement();
17.237 - if (el.getVisualRepresentation() instanceof Pane) {
17.238 - Pane pane = (Pane)el.getVisualRepresentation();
17.239 - pane.updateName();
17.240 - peer.setDisplayName(pane.getComponent().getDisplayName());
17.241 + for (MultiViewDescription mvd : model.getDescriptions()) {
17.242 + MultiViewElement el = model.getElementForDescription(
17.243 + mvd, MultiViewCloneableTopComponent.isSourceView(mvd)
17.244 + );
17.245 + if (el == null) {
17.246 + continue;
17.247 + }
17.248 + if (el.getVisualRepresentation() instanceof Pane) {
17.249 + Pane pane = (Pane)el.getVisualRepresentation();
17.250 + pane.updateName();
17.251 + peer.setDisplayName(pane.getComponent().getDisplayName());
17.252 + }
17.253 }
17.254 }
17.255 - //TODO
17.256 }
17.257
17.258 public Lookup getLookup() {
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
18.2 +++ b/core.multiview/src/org/netbeans/core/multiview/MultiViewProcessor.java Wed May 25 16:50:33 2011 +0200
18.3 @@ -0,0 +1,187 @@
18.4 +/*
18.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
18.6 + *
18.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
18.8 + *
18.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
18.10 + * Other names may be trademarks of their respective owners.
18.11 + *
18.12 + * The contents of this file are subject to the terms of either the GNU
18.13 + * General Public License Version 2 only ("GPL") or the Common
18.14 + * Development and Distribution License("CDDL") (collectively, the
18.15 + * "License"). You may not use this file except in compliance with the
18.16 + * License. You can obtain a copy of the License at
18.17 + * http://www.netbeans.org/cddl-gplv2.html
18.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
18.19 + * specific language governing permissions and limitations under the
18.20 + * License. When distributing the software, include this License Header
18.21 + * Notice in each file and include the License file at
18.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
18.23 + * particular file as subject to the "Classpath" exception as provided
18.24 + * by Oracle in the GPL Version 2 section of the License file that
18.25 + * accompanied this code. If applicable, add the following below the
18.26 + * License Header, with the fields enclosed by brackets [] replaced by
18.27 + * your own identifying information:
18.28 + * "Portions Copyrighted [year] [name of copyright owner]"
18.29 + *
18.30 + * If you wish your version of this file to be governed by only the CDDL
18.31 + * or only the GPL Version 2, indicate your decision by adding
18.32 + * "[Contributor] elects to include this software in this distribution
18.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
18.34 + * single choice of license, a recipient has the option to distribute
18.35 + * your version of this file under either the CDDL, the GPL Version 2 or
18.36 + * to extend the choice of license to its licensees as provided above.
18.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
18.38 + * Version 2 license, then the option applies only if the new code is
18.39 + * made subject to such option by the copyright holder.
18.40 + *
18.41 + * Contributor(s):
18.42 + *
18.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
18.44 + */
18.45 +
18.46 +package org.netbeans.core.multiview;
18.47 +
18.48 +import java.util.Arrays;
18.49 +import java.util.HashSet;
18.50 +import java.util.List;
18.51 +import java.util.Set;
18.52 +import javax.annotation.processing.Processor;
18.53 +import javax.annotation.processing.RoundEnvironment;
18.54 +import javax.annotation.processing.SupportedSourceVersion;
18.55 +import javax.lang.model.SourceVersion;
18.56 +import javax.lang.model.element.Element;
18.57 +import javax.lang.model.element.ElementKind;
18.58 +import javax.lang.model.element.ExecutableElement;
18.59 +import javax.lang.model.element.Modifier;
18.60 +import javax.lang.model.element.TypeElement;
18.61 +import javax.lang.model.element.VariableElement;
18.62 +import javax.lang.model.type.TypeMirror;
18.63 +import javax.lang.model.util.ElementFilter;
18.64 +import org.netbeans.core.spi.multiview.MultiViewElement;
18.65 +import org.netbeans.core.spi.multiview.MultiViewFactory;
18.66 +import org.openide.filesystems.annotations.LayerBuilder;
18.67 +import org.openide.filesystems.annotations.LayerGeneratingProcessor;
18.68 +import org.openide.filesystems.annotations.LayerGenerationException;
18.69 +import org.openide.text.CloneableEditorSupport;
18.70 +import org.openide.util.Lookup;
18.71 +import org.openide.util.lookup.ServiceProvider;
18.72 +import org.openide.windows.TopComponent;
18.73 +
18.74 +/**
18.75 + * Register {@link MultiViewElement}s for given mime types.
18.76 + *
18.77 + * @author Jaroslav Tulach
18.78 + */
18.79 +@ServiceProvider(service=Processor.class)
18.80 +@SupportedSourceVersion(SourceVersion.RELEASE_6)
18.81 +public class MultiViewProcessor extends LayerGeneratingProcessor {
18.82 + public @Override Set<String> getSupportedAnnotationTypes() {
18.83 + return new HashSet<String>(Arrays.asList(
18.84 + MultiViewElement.Registration.class.getCanonicalName()
18.85 + ));
18.86 + }
18.87 +
18.88 + @Override
18.89 + protected boolean handleProcess(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) throws LayerGenerationException {
18.90 + if (roundEnv.processingOver()) {
18.91 + return false;
18.92 + }
18.93 + TypeMirror pane = null;
18.94 + TypeElement typeElement = processingEnv.getElementUtils().getTypeElement(CloneableEditorSupport.Pane.class.getCanonicalName());
18.95 + if(typeElement != null) {
18.96 + pane = typeElement.asType();
18.97 + }
18.98 +
18.99 + for (Element e : roundEnv.getElementsAnnotatedWith(MultiViewElement.Registration.class)) {
18.100 + MultiViewElement.Registration mvr = e.getAnnotation(MultiViewElement.Registration.class);
18.101 + if (mvr.mimeType().length == 0) {
18.102 + throw new LayerGenerationException("You must specify mimeType", e);
18.103 + }
18.104 + TypeMirror[] exprType = new TypeMirror[1];
18.105 + String[] binAndMethodNames = findDefinition(e, exprType);
18.106 + String fileBaseName = binAndMethodNames[0].replace('.', '-');
18.107 + if (binAndMethodNames[1] != null) {
18.108 + fileBaseName += "-" + binAndMethodNames[1];
18.109 + }
18.110 + for (String type : mvr.mimeType()) {
18.111 + LayerBuilder.File f = layer(e).file("Editors/" + (type.equals("") ? "" : type + '/') + fileBaseName + ".instance");
18.112 + f.methodvalue("instanceCreate", MultiViewFactory.class.getName(), "createMultiViewDescription");
18.113 + f.stringvalue("instanceClass", ContextAwareDescription.class.getName());
18.114 + f.stringvalue("class", binAndMethodNames[0]);
18.115 + f.bundlevalue("displayName", mvr.displayName());
18.116 + f.stringvalue("iconBase", mvr.iconBase());
18.117 + f.stringvalue("preferredID", mvr.preferredID());
18.118 + f.intvalue("persistenceType", mvr.persistenceType());
18.119 + f.position(mvr.position());
18.120 + if (binAndMethodNames[1] != null) {
18.121 + f.stringvalue("method", binAndMethodNames[1]);
18.122 + }
18.123 + if (pane != null && processingEnv.getTypeUtils().isAssignable(exprType[0], pane)) {
18.124 + f.boolvalue("sourceview", true);
18.125 + }
18.126 + f.write();
18.127 + }
18.128 + }
18.129 + return true;
18.130 + }
18.131 +
18.132 + private String[] findDefinition(Element e, TypeMirror[] type) throws LayerGenerationException {
18.133 + final TypeMirror lkp = processingEnv.getElementUtils().getTypeElement(Lookup.class.getCanonicalName()).asType();
18.134 + final TypeMirror mve = processingEnv.getElementUtils().getTypeElement(MultiViewElement.class.getName()).asType();
18.135 + if (e.getKind() == ElementKind.CLASS) {
18.136 + TypeElement clazz = (TypeElement) e;
18.137 + if (!processingEnv.getTypeUtils().isAssignable(clazz.asType(), mve)) {
18.138 + throw new LayerGenerationException("Not assignable to " + mve, e);
18.139 + }
18.140 + int constructorCount = 0;
18.141 + CONSTRUCTOR: for (ExecutableElement constructor : ElementFilter.constructorsIn(clazz.getEnclosedElements())) {
18.142 + if (!constructor.getModifiers().contains(Modifier.PUBLIC)) {
18.143 + continue;
18.144 + }
18.145 + List<? extends VariableElement> params = constructor.getParameters();
18.146 + if (params.size() > 1) {
18.147 + continue;
18.148 + }
18.149 + for (VariableElement param : params) {
18.150 + if (!param.asType().equals(lkp)) {
18.151 + continue CONSTRUCTOR;
18.152 + }
18.153 + }
18.154 + }
18.155 + if (!clazz.getModifiers().contains(Modifier.PUBLIC)) {
18.156 + throw new LayerGenerationException("Class must be public", e);
18.157 + }
18.158 + type[0] = e.asType();
18.159 + return new String[] {processingEnv.getElementUtils().getBinaryName(clazz).toString(), null};
18.160 + } else {
18.161 + ExecutableElement meth = (ExecutableElement) e;
18.162 + if (!processingEnv.getTypeUtils().isAssignable(meth.getReturnType(), mve)) {
18.163 + throw new LayerGenerationException("Not assignable to " + mve, e);
18.164 + }
18.165 + if (!meth.getModifiers().contains(Modifier.PUBLIC)) {
18.166 + throw new LayerGenerationException("Method must be public", e);
18.167 + }
18.168 + if (!meth.getModifiers().contains(Modifier.STATIC)) {
18.169 + throw new LayerGenerationException("Method must be static", e);
18.170 + }
18.171 + List<? extends VariableElement> params = meth.getParameters();
18.172 + if (params.size() > 1) {
18.173 + throw new LayerGenerationException("Method must take at most one parameter", e);
18.174 + }
18.175 + for (VariableElement param : params) {
18.176 + if (!param.asType().equals(lkp)) {
18.177 + throw new LayerGenerationException("Method parameters may be either Lookup or Project", e);
18.178 + }
18.179 + }
18.180 + if (!meth.getEnclosingElement().getModifiers().contains(Modifier.PUBLIC)) {
18.181 + throw new LayerGenerationException("Class must be public", e);
18.182 + }
18.183 + type[0] = meth.getReturnType();
18.184 + return new String[] {
18.185 + processingEnv.getElementUtils().getBinaryName((TypeElement) meth.getEnclosingElement()).toString(),
18.186 + meth.getSimpleName().toString()};
18.187 + }
18.188 + }
18.189 +
18.190 +}
19.1 --- a/core.multiview/src/org/netbeans/core/multiview/MultiViewTopComponent.java Wed May 25 16:24:45 2011 +0200
19.2 +++ b/core.multiview/src/org/netbeans/core/multiview/MultiViewTopComponent.java Wed May 25 16:50:33 2011 +0200
19.3 @@ -53,12 +53,13 @@
19.4 import org.netbeans.core.spi.multiview.MultiViewElementCallback;
19.5 import org.openide.awt.UndoRedo;
19.6 import org.openide.util.HelpCtx;
19.7 +import org.openide.util.Lookup;
19.8 import org.openide.windows.TopComponent;
19.9
19.10
19.11 /** Special subclass of TopComponent which shows and handles set of
19.12 * MultiViewElements, shows them in switchable toggle buttons style, along
19.13 - * with toolbsrs af actions asociated with individual view elements.
19.14 + * with toolbars and actions associated with individual view elements.
19.15 *
19.16 *
19.17 * @author Dafe Simonek, Milos Kleint
19.18 @@ -82,6 +83,9 @@
19.19 setFocusCycleRoot(false);
19.20 }
19.21
19.22 + public <T extends Serializable & Lookup.Provider> void setMimeLookup(String mimeType, T context) {
19.23 + peer.setMimeLookup(mimeType, context);
19.24 + }
19.25
19.26 public void setMultiViewDescriptions(MultiViewDescription[] descriptions, MultiViewDescription defaultDesc) {
19.27 peer.setMultiViewDescriptions(descriptions, defaultDesc);
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
20.2 +++ b/core.multiview/src/org/netbeans/core/multiview/SourceCheckDescription.java Wed May 25 16:50:33 2011 +0200
20.3 @@ -0,0 +1,55 @@
20.4 +/*
20.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
20.6 + *
20.7 + * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
20.8 + *
20.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
20.10 + * Other names may be trademarks of their respective owners.
20.11 + *
20.12 + * The contents of this file are subject to the terms of either the GNU
20.13 + * General Public License Version 2 only ("GPL") or the Common
20.14 + * Development and Distribution License("CDDL") (collectively, the
20.15 + * "License"). You may not use this file except in compliance with the
20.16 + * License. You can obtain a copy of the License at
20.17 + * http://www.netbeans.org/cddl-gplv2.html
20.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
20.19 + * specific language governing permissions and limitations under the
20.20 + * License. When distributing the software, include this License Header
20.21 + * Notice in each file and include the License file at
20.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20.23 + * particular file as subject to the "Classpath" exception as provided
20.24 + * by Oracle in the GPL Version 2 section of the License file that
20.25 + * accompanied this code. If applicable, add the following below the
20.26 + * License Header, with the fields enclosed by brackets [] replaced by
20.27 + * your own identifying information:
20.28 + * "Portions Copyrighted [year] [name of copyright owner]"
20.29 + *
20.30 + * If you wish your version of this file to be governed by only the CDDL
20.31 + * or only the GPL Version 2, indicate your decision by adding
20.32 + * "[Contributor] elects to include this software in this distribution
20.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
20.34 + * single choice of license, a recipient has the option to distribute
20.35 + * your version of this file under either the CDDL, the GPL Version 2 or
20.36 + * to extend the choice of license to its licensees as provided above.
20.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
20.38 + * Version 2 license, then the option applies only if the new code is
20.39 + * made subject to such option by the copyright holder.
20.40 + *
20.41 + * Contributor(s):
20.42 + *
20.43 + * Portions Copyrighted 2011 Sun Microsystems, Inc.
20.44 + */
20.45 +package org.netbeans.core.multiview;
20.46 +
20.47 +import org.netbeans.core.spi.multiview.MultiViewDescription;
20.48 +import org.netbeans.core.spi.multiview.SourceViewMarker;
20.49 +
20.50 +/** More dynamic version of {@link SourceViewMarker}. Possibly candidate for
20.51 + * some future API.
20.52 + *
20.53 + * @author Jaroslav Tulach <jtulach@netbeans.org>
20.54 + */
20.55 +public interface SourceCheckDescription extends MultiViewDescription {
20.56 + /** @return true if this description likely represents source view */
20.57 + public boolean isSourceView();
20.58 +}
21.1 --- a/core.multiview/src/org/netbeans/core/spi/multiview/CloseOperationHandler.java Wed May 25 16:24:45 2011 +0200
21.2 +++ b/core.multiview/src/org/netbeans/core/spi/multiview/CloseOperationHandler.java Wed May 25 16:50:33 2011 +0200
21.3 @@ -59,7 +59,7 @@
21.4 * the decision.
21.5 * @param elements {@link org.netbeans.core.spi.multiview.CloseOperationState} instances of {@link org.netbeans.core.spi.multiview.MultiViewElement}s that cannot be
21.6 * closed and require resolution.
21.7 - * @returns true if component can be close, false if it shall remain opened.
21.8 + * @return true if component can be close, false if it shall remain opened.
21.9 */
21.10 boolean resolveCloseOperation(CloseOperationState[] elements);
21.11
22.1 --- a/core.multiview/src/org/netbeans/core/spi/multiview/MultiViewCloneableEditor.java Wed May 25 16:24:45 2011 +0200
22.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
22.3 @@ -1,174 +0,0 @@
22.4 -/*
22.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
22.6 - *
22.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
22.8 - *
22.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
22.10 - * Other names may be trademarks of their respective owners.
22.11 - *
22.12 - * The contents of this file are subject to the terms of either the GNU
22.13 - * General Public License Version 2 only ("GPL") or the Common
22.14 - * Development and Distribution License("CDDL") (collectively, the
22.15 - * "License"). You may not use this file except in compliance with the
22.16 - * License. You can obtain a copy of the License at
22.17 - * http://www.netbeans.org/cddl-gplv2.html
22.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
22.19 - * specific language governing permissions and limitations under the
22.20 - * License. When distributing the software, include this License Header
22.21 - * Notice in each file and include the License file at
22.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
22.23 - * particular file as subject to the "Classpath" exception as provided
22.24 - * by Oracle in the GPL Version 2 section of the License file that
22.25 - * accompanied this code. If applicable, add the following below the
22.26 - * License Header, with the fields enclosed by brackets [] replaced by
22.27 - * your own identifying information:
22.28 - * "Portions Copyrighted [year] [name of copyright owner]"
22.29 - *
22.30 - * Contributor(s):
22.31 - *
22.32 - * The Original Software is NetBeans. The Initial Developer of the Original
22.33 - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
22.34 - * Microsystems, Inc. All Rights Reserved.
22.35 - *
22.36 - * If you wish your version of this file to be governed by only the CDDL
22.37 - * or only the GPL Version 2, indicate your decision by adding
22.38 - * "[Contributor] elects to include this software in this distribution
22.39 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
22.40 - * single choice of license, a recipient has the option to distribute
22.41 - * your version of this file under either the CDDL, the GPL Version 2 or
22.42 - * to extend the choice of license to its licensees as provided above.
22.43 - * However, if you add GPL Version 2 code and therefore, elected the GPL
22.44 - * Version 2 license, then the option applies only if the new code is
22.45 - * made subject to such option by the copyright holder.
22.46 - */
22.47 -
22.48 -package org.netbeans.core.spi.multiview;
22.49 -
22.50 -import javax.swing.JComponent;
22.51 -import javax.swing.JToolBar;
22.52 -import javax.swing.text.Document;
22.53 -import org.openide.text.CloneableEditor;
22.54 -import org.openide.text.CloneableEditorSupport;
22.55 -import org.openide.text.NbDocument;
22.56 -
22.57 -/**
22.58 - * @author mkleint
22.59 - */
22.60 -abstract class MultiViewCloneableEditor extends CloneableEditor implements MultiViewElement {
22.61 -
22.62 - private static final long serialVersionUID =-3126744316644172415L;
22.63 -
22.64 - private transient MultiViewElementCallback multiViewObserver;
22.65 - private transient JToolBar bar;
22.66 -
22.67 - /** Creates a new instance of MultiViewClonableEditor */
22.68 - public MultiViewCloneableEditor() {
22.69 - this(null);
22.70 - }
22.71 -
22.72 - public MultiViewCloneableEditor(CloneableEditorSupport support) {
22.73 - super(support);
22.74 - }
22.75 -
22.76 - public JComponent getToolbarRepresentation() {
22.77 - Document doc = getEditorPane().getDocument();
22.78 - if (doc instanceof NbDocument.CustomToolbar) {
22.79 - if (bar == null) {
22.80 - bar = ((NbDocument.CustomToolbar)doc).createToolbar(getEditorPane());
22.81 - }
22.82 - return bar;
22.83 - }
22.84 - return null;
22.85 - }
22.86 -
22.87 - public javax.swing.JComponent getVisualRepresentation() {
22.88 - return this;
22.89 - }
22.90 -
22.91 - public final void setMultiViewCallback(MultiViewElementCallback callback) {
22.92 - multiViewObserver = callback;
22.93 - }
22.94 -
22.95 - protected final MultiViewElementCallback getElementObserver() {
22.96 - return multiViewObserver;
22.97 - }
22.98 -
22.99 - public void componentActivated() {
22.100 - super.componentActivated();
22.101 - }
22.102 -
22.103 - public void componentClosed() {
22.104 - super.componentClosed();
22.105 - }
22.106 -
22.107 - public void componentDeactivated() {
22.108 - super.componentDeactivated();
22.109 - }
22.110 -
22.111 - public void componentHidden() {
22.112 - super.componentHidden();
22.113 - }
22.114 -
22.115 - public void componentOpened() {
22.116 - super.componentOpened();
22.117 - }
22.118 -
22.119 - public void componentShowing() {
22.120 - if (multiViewObserver != null) {
22.121 - updateName();
22.122 - }
22.123 - super.componentShowing();
22.124 - }
22.125 -
22.126 - public javax.swing.Action[] getActions() {
22.127 - return super.getActions();
22.128 - }
22.129 -
22.130 - public org.openide.util.Lookup getLookup() {
22.131 - return super.getLookup();
22.132 - }
22.133 -
22.134 - public String preferredID() {
22.135 - return super.preferredID();
22.136 - }
22.137 -
22.138 -
22.139 - public void requestVisible() {
22.140 - if (multiViewObserver != null) {
22.141 - multiViewObserver.requestVisible();
22.142 - } else {
22.143 - super.requestVisible();
22.144 - }
22.145 - }
22.146 -
22.147 - public void requestActive() {
22.148 - if (multiViewObserver != null) {
22.149 - multiViewObserver.requestActive();
22.150 - } else {
22.151 - super.requestActive();
22.152 - }
22.153 - }
22.154 -
22.155 -
22.156 - public void updateName() {
22.157 - super.updateName();
22.158 - if (multiViewObserver != null) {
22.159 - multiViewObserver.updateTitle(getDisplayName());
22.160 - }
22.161 - }
22.162 -
22.163 - public void open() {
22.164 - if (multiViewObserver != null) {
22.165 - multiViewObserver.requestVisible();
22.166 - } else {
22.167 - super.open();
22.168 - }
22.169 -
22.170 - }
22.171 -
22.172 - public CloseOperationState canCloseElement() {
22.173 - throw new IllegalStateException("Not implemented yet.");
22.174 -// return CloseOperationState.STATE_OK;
22.175 - }
22.176 -
22.177 -}
23.1 --- a/core.multiview/src/org/netbeans/core/spi/multiview/MultiViewElement.java Wed May 25 16:24:45 2011 +0200
23.2 +++ b/core.multiview/src/org/netbeans/core/spi/multiview/MultiViewElement.java Wed May 25 16:50:33 2011 +0200
23.3 @@ -44,8 +44,14 @@
23.4
23.5 package org.netbeans.core.spi.multiview;
23.6
23.7 +import java.lang.annotation.ElementType;
23.8 +import java.lang.annotation.Retention;
23.9 +import java.lang.annotation.RetentionPolicy;
23.10 +import java.lang.annotation.Target;
23.11 import javax.swing.Action;
23.12 import javax.swing.JComponent;
23.13 +import org.netbeans.api.editor.mimelookup.MimeLookup;
23.14 +import org.netbeans.core.api.multiview.MultiViews;
23.15 import org.openide.awt.UndoRedo;
23.16 import org.openide.util.Lookup;
23.17
23.18 @@ -165,4 +171,59 @@
23.19 CloseOperationState canCloseElement();
23.20
23.21
23.22 + /** Registers a {@link MultiViewElement}, so it is available in
23.23 + * {@link MimeLookup} and can be found and located by
23.24 + * {@link MultiViews#createCloneableMultiView}
23.25 + * and
23.26 + * {@link MultiViews#createMultiView}
23.27 + * factory methods.
23.28 + * <p>
23.29 + * The element class may have default constructor or a constructor that
23.30 + * takes {@link Lookup} as an argument.
23.31 + */
23.32 + @Target({ ElementType.TYPE, ElementType.METHOD })
23.33 + @Retention(RetentionPolicy.SOURCE)
23.34 + public @interface Registration {
23.35 + /** Mime type this registration is associated with.
23.36 + *
23.37 + * @return array of mime types like "text/java", "text", etc.
23.38 + */
23.39 + public String[] mimeType();
23.40 +
23.41 + /** Gets persistence type of multi view element, the TopComponent will decide
23.42 + * on it's own persistenceType based on the sum of all it's elements.
23.43 + * {@link org.openide.windows.TopComponent#PERSISTENCE_ALWAYS} has higher priority than {@link org.openide.windows.TopComponent#PERSISTENCE_ONLY_OPENED}
23.44 + * and {@link org.openide.windows.TopComponent#PERSISTENCE_NEVER} has lowest priority.
23.45 + * The {@link org.openide.windows.TopComponent} will be stored only if at least one element requesting persistence
23.46 + * was made visible.
23.47 + */
23.48 + public int persistenceType();
23.49 +
23.50 + /**
23.51 + * Gets localized display name of multi view element. Will be placed on the Element's toggle button.
23.52 + *@return localized display name
23.53 + */
23.54 + public String displayName();
23.55 +
23.56 + /**
23.57 + * Icon for the MultiViewDescription's multiview component. Will be shown as TopComponent's icon
23.58 + * when this element is selected.
23.59 + * @return the icon of multi view element
23.60 + */
23.61 + public String iconBase();
23.62 +
23.63 + /**
23.64 + * A Description's contribution
23.65 + * to unique {@link org.openide.windows.TopComponent}'s Id returned by <code>getID</code>. Returned value is used as starting
23.66 + * value for creating unique {@link org.openide.windows.TopComponent} ID for whole enclosing multi view
23.67 + * component.
23.68 + * Value should be preferably unique, but need not be.
23.69 + */
23.70 + public String preferredID();
23.71 +
23.72 + /** Position of this element amoung the list of other elements.
23.73 + * @return integer value
23.74 + */
23.75 + public int position() default Integer.MAX_VALUE;
23.76 + }
23.77 }
24.1 --- a/core.multiview/src/org/netbeans/core/spi/multiview/MultiViewFactory.java Wed May 25 16:24:45 2011 +0200
24.2 +++ b/core.multiview/src/org/netbeans/core/spi/multiview/MultiViewFactory.java Wed May 25 16:50:33 2011 +0200
24.3 @@ -44,16 +44,29 @@
24.4
24.5 package org.netbeans.core.spi.multiview;
24.6
24.7 +import java.awt.Image;
24.8 +import java.awt.event.ActionEvent;
24.9 import java.io.Serializable;
24.10 -import java.util.ArrayList;
24.11 -import java.util.Collection;
24.12 +import java.lang.reflect.Constructor;
24.13 +import java.lang.reflect.Method;
24.14 +import java.util.Iterator;
24.15 +import java.util.LinkedHashMap;
24.16 +import java.util.Map;
24.17 import javax.swing.AbstractAction;
24.18 import javax.swing.Action;
24.19 import javax.swing.JComponent;
24.20 import javax.swing.JPanel;
24.21 +import org.netbeans.core.api.multiview.MultiViews;
24.22 +import org.netbeans.core.multiview.ContextAwareDescription;
24.23 import org.netbeans.core.multiview.MultiViewCloneableTopComponent;
24.24 import org.netbeans.core.multiview.MultiViewTopComponent;
24.25 +import org.netbeans.core.multiview.SourceCheckDescription;
24.26 +import org.openide.DialogDisplayer;
24.27 +import org.openide.NotifyDescriptor;
24.28 +import org.openide.util.HelpCtx;
24.29 +import org.openide.util.ImageUtilities;
24.30 import org.openide.util.Lookup;
24.31 +import org.openide.util.NbBundle.Messages;
24.32 import org.openide.windows.CloneableTopComponent;
24.33 import org.openide.windows.TopComponent;
24.34
24.35 @@ -84,6 +97,10 @@
24.36 * multi views.
24.37 * PLEASE NOTE: a non-cloneable TopComponent is not able to embed editors aka subclasses of CloneableEditor correctly.
24.38 * Use createCloneableMultiView() method in such a case.
24.39 + * <p>
24.40 + * Please see {@link MultiViews#createMultiView} for loosely coupled variant
24.41 + * of this method which may be more suitable for modular environment.
24.42 + *
24.43 * @param descriptions array of descriptions of tabs in the multiview.
24.44 * @param defaultDesc the initial selection, one of the descriptions array values.
24.45 */
24.46 @@ -95,6 +112,10 @@
24.47 * multi views.
24.48 * PLEASE NOTE: a non-cloneable TopComponent is not able to embed editors aka subclasses of CloneableEditor correctly.
24.49 * Use createCloneableMultiView() method in such a case.
24.50 + * <p>
24.51 + * Please see {@link MultiViews#createMultiView} for loosely coupled variant
24.52 + * of this method which may be more suitable for modular environment.
24.53 + *
24.54 * @param descriptions array of descriptions of tabs in the multiview.
24.55 * @param defaultDesc the initial selection, one of the descriptions array values.
24.56 * @param closeHandler handles closing of the multiview component, useful when any of the embedded elements can be in modified state and closing would cause a dataloss..
24.57 @@ -110,7 +131,12 @@
24.58 }
24.59
24.60 /** Creates and returns new instance of cloneable top component with
24.61 - * multi views
24.62 + * multi views.
24.63 + * <p>
24.64 + * Please see {@link MultiViews#createCloneableMultiView} for loosely coupled variant
24.65 + * of this method which may be more suitable for modular environment.
24.66 + *
24.67 + *
24.68 * @param descriptions array of descriptions of tabs in the multiview.
24.69 * @param defaultDesc the initial selection, one of the descriptions array values.
24.70 */
24.71 @@ -120,6 +146,10 @@
24.72
24.73 /** Creates and returns new instance of cloneable top component with
24.74 * multi views.
24.75 + * <p>
24.76 + * Please see {@link MultiViews#createCloneableMultiView} for loosely coupled variant
24.77 + * of this method which may be more suitable for modular environment.
24.78 + *
24.79 * @param descriptions array of descriptions of tabs in the multiview.
24.80 * @param defaultDesc the initial selection, one of the descriptions array values.
24.81 * @param closeHandler handles closing of the multiview component, useful when any of the embedded elements can be in modified state and closing would cause a dataloss..
24.82 @@ -146,7 +176,15 @@
24.83 /**
24.84 * Utility method for MultiViewElements to create a CloseOperationState instance
24.85 * that warns about possible data loss. Corrective actions can be defined.
24.86 - * @param warningId an id that idenfifies the problem,
24.87 + * <p>
24.88 + * There is a default implementation of {@link CloseOperationHandler}. It
24.89 + * uses <code>warningId</code> of all elements with unsafe close state to
24.90 + * select the unique ones. These unique elements are then presented in a
24.91 + * question box and user can decide to save or discard them. The user
24.92 + * friendly message in such dialog is taken from
24.93 + * <code>proceedAction.getValue(Action.LONG_DESCRIPTION)</code>, if present.
24.94 + *
24.95 + * @param warningId an id that identifies the problem,
24.96 * the CloseOperationHandler used in the component should know about the warning's meaning and handle appropriately
24.97 * @param proceedAction will be performed when the CloseOperationHandler decides that closing the component is ok and changes are to be saved.
24.98 * @param discardAction will be performed when the CloseOperationHandler decides that the nonsaved data shall be discarded
24.99 @@ -163,6 +201,9 @@
24.100 return new DefaultCloseHandler();
24.101 }
24.102
24.103 + static MultiViewDescription createMultiViewDescription(Map map) {
24.104 + return new MapMVD(map, null);
24.105 + }
24.106
24.107 private static final class Blank implements MultiViewElement, Serializable {
24.108
24.109 @@ -228,74 +269,87 @@
24.110 private static final class DefaultCloseHandler implements CloseOperationHandler, Serializable {
24.111 private static final long serialVersionUID =-3126744916624172427L;
24.112
24.113 + @Override
24.114 + @Messages({
24.115 + "CTL_Save=Save",
24.116 + "CTL_Discard=&Discard"
24.117 + })
24.118 public boolean resolveCloseOperation(CloseOperationState[] elements) {
24.119 + Iterator<CloseOperationState> it;
24.120 if (elements != null) {
24.121 boolean canBeClosed = true;
24.122 - Collection badOnes = new ArrayList();
24.123 + Map<String,CloseOperationState> badOnes = new LinkedHashMap<String, CloseOperationState>();
24.124 for (int i = 0; i < elements.length; i++) {
24.125 if (!elements[i].canClose()) {
24.126 - badOnes.add(elements[i]);
24.127 + badOnes.put(elements[i].getCloseWarningID(), elements[i]);
24.128 canBeClosed = false;
24.129 }
24.130 }
24.131 if (!canBeClosed) {
24.132 - //TODO SHOW dialog here.
24.133 - throw new IllegalStateException("Cannot close component. Some of the elements require close operation handling. See MultiViewFactory.createMultiView()");
24.134 -// Object[] options = new Object[] {
24.135 -// new JButton("Proceed"),
24.136 -// new JButton("Discard"),
24.137 -// new JButton("Cancel")
24.138 -// };
24.139 -// NotifyDescriptor desc = new NotifyDescriptor(createPanel(badOnes), "Cannot close component.",
24.140 -// NotifyDescriptor.DEFAULT_OPTION, NotifyDescriptor.WARNING_MESSAGE,
24.141 -// options, options[0]);
24.142 -// Object retVal = DialogDisplayer.getDefault().notify(desc);
24.143 -// if (retVal == options[0]) {
24.144 -// // do proceed.
24.145 -// Iterator it = badOnes.iterator();
24.146 -// while (it.hasNext()) {
24.147 -// Action act = ((CloseOperationState)it.next()).getProceedAction();
24.148 -// if (act != null) {
24.149 -// act.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "proceed"));
24.150 -// }
24.151 -// }
24.152 -// } else if (retVal == options[1]) {
24.153 -// // do discard
24.154 -// Iterator it = badOnes.iterator();
24.155 -// while (it.hasNext()) {
24.156 -// Action act = ((CloseOperationState)it.next()).getDiscardAction();
24.157 -// if (act != null) {
24.158 -// act.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "discard"));
24.159 -// }
24.160 -// }
24.161 -// } else {
24.162 -// // was cancel..
24.163 -// return false;
24.164 -// }
24.165 + NotifyDescriptor desc = new NotifyDescriptor.Confirmation(
24.166 + createPanel(badOnes), NotifyDescriptor.YES_NO_CANCEL_OPTION
24.167 + );
24.168 + Object[] choose = { Bundle.CTL_Save(), Bundle.CTL_Discard(), NotifyDescriptor.CANCEL_OPTION };
24.169 + desc.setOptions(choose);
24.170 + Object retVal = DialogDisplayer.getDefault().notify(desc);
24.171 + if (retVal == choose[0]) {
24.172 + // do proceed.
24.173 + it = badOnes.values().iterator();
24.174 + while (it.hasNext()) {
24.175 + Action act = ((CloseOperationState)it.next()).getProceedAction();
24.176 + if (act != null) {
24.177 + act.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "proceed"));
24.178 + }
24.179 + }
24.180 + } else if (retVal == choose[1]) {
24.181 + // do discard
24.182 + it = badOnes.values().iterator();
24.183 + while (it.hasNext()) {
24.184 + Action act = ((CloseOperationState)it.next()).getDiscardAction();
24.185 + if (act != null) {
24.186 + act.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "discard"));
24.187 + }
24.188 + }
24.189 + } else {
24.190 + // was cancel..
24.191 + return false;
24.192 + }
24.193 }
24.194 }
24.195 return true;
24.196 }
24.197
24.198 -// private JPanel createPanel(Collection elems) {
24.199 -// JPanel panel = new JPanel();
24.200 -// panel.setLayout(new BorderLayout());
24.201 -// JLabel lbl = new JLabel("Cannot safely close component for following reasons:");
24.202 -// panel.add(lbl, BorderLayout.NORTH);
24.203 -// JScrollPane pane = new JScrollPane();
24.204 -// String[] warnings = new String[elems.size()];
24.205 -// int index = 0;
24.206 -// Iterator it = elems.iterator();
24.207 -// while (it.hasNext()) {
24.208 -// CloseOperationState state = (CloseOperationState)it.next();
24.209 -// warnings[index] = state.getCloseWarningMessage();
24.210 -// index = index + 1;
24.211 -// }
24.212 -// JList list = new JList(warnings);
24.213 -// pane.setViewportView(list);
24.214 -// panel.add(pane);
24.215 -// return panel;
24.216 -// }
24.217 + private Object createPanel(Map<String,CloseOperationState> elems) {
24.218 + if (elems.size() == 1) {
24.219 + return findDescription(elems.values().iterator().next());
24.220 + }
24.221 +
24.222 + StringBuilder sb = new StringBuilder();
24.223 + Iterator it = elems.values().iterator();
24.224 + while (it.hasNext()) {
24.225 + CloseOperationState state = (CloseOperationState)it.next();
24.226 + if (sb.length() > 0) {
24.227 + sb.append(" ");
24.228 + }
24.229 + sb.append(findDescription(state));
24.230 + }
24.231 + return sb;
24.232 + }
24.233 +
24.234 + private Object findDescription(final CloseOperationState e) {
24.235 + final Action a = e.getProceedAction();
24.236 + Object msg = a.getValue(Action.LONG_DESCRIPTION);
24.237 + if (msg == null) {
24.238 + msg = a.getValue(Action.SHORT_DESCRIPTION);
24.239 + }
24.240 + if (msg == null) {
24.241 + msg = a.getValue(Action.NAME);
24.242 + }
24.243 + if (msg == null) {
24.244 + msg = e.getCloseWarningID();
24.245 + }
24.246 + return msg;
24.247 + }
24.248 }
24.249
24.250 /**
24.251 @@ -308,5 +362,98 @@
24.252 }
24.253
24.254 }
24.255 -
24.256 +
24.257 + /** default MultiViewDescription */
24.258 + private static final class MapMVD implements
24.259 + MultiViewDescription, ContextAwareDescription , SourceCheckDescription {
24.260 + private final Map map;
24.261 + private final Lookup context;
24.262 + public MapMVD(Map map, Lookup context) {
24.263 + this.map = map;
24.264 + this.context = context;
24.265 + }
24.266 +
24.267 + private <T> T get(String attr, Class<T> type) {
24.268 + Object obj = map.get(attr); // NOI18N
24.269 + if (obj == null) {
24.270 + throw new NullPointerException(attr + " attribute not specified");
24.271 + }
24.272 + if (type.isInstance(obj)) {
24.273 + return type.cast(obj);
24.274 + }
24.275 + throw new IllegalArgumentException(attr + " not of type " + type + " but " + obj);
24.276 + }
24.277 +
24.278 +
24.279 + @Override
24.280 + public int getPersistenceType() {
24.281 + return get("persistenceType", Integer.class);
24.282 + }
24.283 +
24.284 + @Override
24.285 + public String getDisplayName() {
24.286 + return get("displayName", String.class);
24.287 + }
24.288 +
24.289 + @Override
24.290 + public Image getIcon() {
24.291 + String base = get("iconBase", String.class); // NOI18N
24.292 + return ImageUtilities.loadImage(base, true);
24.293 + }
24.294 +
24.295 + @Override
24.296 + public HelpCtx getHelpCtx() {
24.297 + return HelpCtx.DEFAULT_HELP;
24.298 + }
24.299 +
24.300 + @Override
24.301 + public String preferredID() {
24.302 + return get("preferredID", String.class); // NOI18N
24.303 + }
24.304 +
24.305 + @Override
24.306 + public MultiViewElement createElement() {
24.307 + String name = get("class", String.class); // NOI18N
24.308 + String method = (String)map.get("method"); // NOI18N
24.309 + try {
24.310 + ClassLoader cl = Lookup.getDefault().lookup(ClassLoader.class);
24.311 + if (cl == null) {
24.312 + cl = Thread.currentThread().getContextClassLoader();
24.313 + }
24.314 + if (cl == null) {
24.315 + cl = MultiViewFactory.class.getClassLoader();
24.316 + }
24.317 + Class<?> clazz = Class.forName(name, true, cl);
24.318 + if (method == null) {
24.319 + try {
24.320 + Constructor<?> lookupC = clazz.getConstructor(Lookup.class);
24.321 + return (MultiViewElement)lookupC.newInstance(context);
24.322 + } catch (Exception ex) {
24.323 + Constructor<?> defC = clazz.getConstructor();
24.324 + return (MultiViewElement)defC.newInstance();
24.325 + }
24.326 + } else {
24.327 + try {
24.328 + Method m = clazz.getMethod(method, Lookup.class);
24.329 + return (MultiViewElement) m.invoke(null, context);
24.330 + } catch (Exception ex) {
24.331 + Method m = clazz.getMethod(method);
24.332 + return (MultiViewElement) m.invoke(null);
24.333 + }
24.334 + }
24.335 + } catch (Exception ex) {
24.336 + throw new IllegalStateException("Cannot instantiate " + name, ex);
24.337 + }
24.338 + }
24.339 +
24.340 + @Override
24.341 + public ContextAwareDescription createContextAwareDescription(Lookup context) {
24.342 + return new MapMVD(map, context);
24.343 + }
24.344 +
24.345 + @Override
24.346 + public boolean isSourceView() {
24.347 + return Boolean.TRUE.equals(map.get("sourceview")); // NOI18N
24.348 + }
24.349 + }
24.350 }
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
25.2 +++ b/core.multiview/src/org/netbeans/core/spi/multiview/text/MultiViewCloneableEditor.java Wed May 25 16:50:33 2011 +0200
25.3 @@ -0,0 +1,241 @@
25.4 +/*
25.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
25.6 + *
25.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
25.8 + *
25.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
25.10 + * Other names may be trademarks of their respective owners.
25.11 + *
25.12 + * The contents of this file are subject to the terms of either the GNU
25.13 + * General Public License Version 2 only ("GPL") or the Common
25.14 + * Development and Distribution License("CDDL") (collectively, the
25.15 + * "License"). You may not use this file except in compliance with the
25.16 + * License. You can obtain a copy of the License at
25.17 + * http://www.netbeans.org/cddl-gplv2.html
25.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
25.19 + * specific language governing permissions and limitations under the
25.20 + * License. When distributing the software, include this License Header
25.21 + * Notice in each file and include the License file at
25.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
25.23 + * particular file as subject to the "Classpath" exception as provided
25.24 + * by Oracle in the GPL Version 2 section of the License file that
25.25 + * accompanied this code. If applicable, add the following below the
25.26 + * License Header, with the fields enclosed by brackets [] replaced by
25.27 + * your own identifying information:
25.28 + * "Portions Copyrighted [year] [name of copyright owner]"
25.29 + *
25.30 + * Contributor(s):
25.31 + *
25.32 + * The Original Software is NetBeans. The Initial Developer of the Original
25.33 + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
25.34 + * Microsystems, Inc. All Rights Reserved.
25.35 + *
25.36 + * If you wish your version of this file to be governed by only the CDDL
25.37 + * or only the GPL Version 2, indicate your decision by adding
25.38 + * "[Contributor] elects to include this software in this distribution
25.39 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
25.40 + * single choice of license, a recipient has the option to distribute
25.41 + * your version of this file under either the CDDL, the GPL Version 2 or
25.42 + * to extend the choice of license to its licensees as provided above.
25.43 + * However, if you add GPL Version 2 code and therefore, elected the GPL
25.44 + * Version 2 license, then the option applies only if the new code is
25.45 + * made subject to such option by the copyright holder.
25.46 + */
25.47 +
25.48 +package org.netbeans.core.spi.multiview.text;
25.49 +
25.50 +import java.awt.event.ActionEvent;
25.51 +import java.io.IOException;
25.52 +import java.util.Enumeration;
25.53 +import javax.swing.AbstractAction;
25.54 +import javax.swing.Action;
25.55 +import javax.swing.JComponent;
25.56 +import javax.swing.JToolBar;
25.57 +import javax.swing.text.Document;
25.58 +import org.netbeans.api.actions.Savable;
25.59 +import org.netbeans.core.spi.multiview.CloseOperationState;
25.60 +import org.netbeans.core.spi.multiview.MultiViewElement;
25.61 +import org.netbeans.core.spi.multiview.MultiViewElementCallback;
25.62 +import org.netbeans.core.spi.multiview.MultiViewFactory;
25.63 +import org.openide.text.CloneableEditor;
25.64 +import org.openide.text.CloneableEditorSupport;
25.65 +import org.openide.text.NbDocument;
25.66 +import org.openide.util.Exceptions;
25.67 +import org.openide.util.NbBundle.Messages;
25.68 +import org.openide.windows.TopComponent;
25.69 +
25.70 +/**
25.71 + * @author mkleint
25.72 + */
25.73 +class MultiViewCloneableEditor extends CloneableEditor implements MultiViewElement {
25.74 + private static final long serialVersionUID =-3126744316644172415L;
25.75 +
25.76 + private transient MultiViewElementCallback multiViewObserver;
25.77 + private transient JToolBar bar;
25.78 +
25.79 + public MultiViewCloneableEditor() {
25.80 + super();
25.81 + }
25.82 +
25.83 + public MultiViewCloneableEditor(CloneableEditorSupport support) {
25.84 + super(support, true);
25.85 + initializeBySupport();
25.86 + }
25.87 +
25.88 + @Override
25.89 + public JComponent getToolbarRepresentation() {
25.90 + Document doc = getEditorPane().getDocument();
25.91 + if (doc instanceof NbDocument.CustomToolbar) {
25.92 + if (bar == null) {
25.93 + bar = ((NbDocument.CustomToolbar)doc).createToolbar(getEditorPane());
25.94 + }
25.95 + }
25.96 + if (bar == null) {
25.97 + bar = new JToolBar();
25.98 + }
25.99 + return bar;
25.100 + }
25.101 +
25.102 + @Override
25.103 + public javax.swing.JComponent getVisualRepresentation() {
25.104 + return this;
25.105 + }
25.106 +
25.107 + @Override
25.108 + public final void setMultiViewCallback(MultiViewElementCallback callback) {
25.109 + multiViewObserver = callback;
25.110 + }
25.111 +
25.112 + protected final MultiViewElementCallback getElementObserver() {
25.113 + return multiViewObserver;
25.114 + }
25.115 +
25.116 + @Override
25.117 + public void componentActivated() {
25.118 + super.componentActivated();
25.119 + }
25.120 +
25.121 + @Override
25.122 + public void componentClosed() {
25.123 + super.componentClosed();
25.124 + }
25.125 +
25.126 + @Override
25.127 + public void componentDeactivated() {
25.128 + super.componentDeactivated();
25.129 + }
25.130 +
25.131 + @Override
25.132 + public void componentHidden() {
25.133 + super.componentHidden();
25.134 + }
25.135 +
25.136 + @Override
25.137 + public void componentOpened() {
25.138 + super.componentOpened();
25.139 + }
25.140 +
25.141 + @Override
25.142 + public void componentShowing() {
25.143 + if (multiViewObserver != null) {
25.144 + updateName();
25.145 + }
25.146 + super.componentShowing();
25.147 + }
25.148 +
25.149 + @Override
25.150 + public javax.swing.Action[] getActions() {
25.151 + return super.getActions();
25.152 + }
25.153 +
25.154 + @Override
25.155 + public org.openide.util.Lookup getLookup() {
25.156 + return super.getLookup();
25.157 + }
25.158 +
25.159 + @Override
25.160 + public String preferredID() {
25.161 + return super.preferredID();
25.162 + }
25.163 +
25.164 +
25.165 + @Override
25.166 + public void requestVisible() {
25.167 + if (multiViewObserver != null) {
25.168 + multiViewObserver.requestVisible();
25.169 + } else {
25.170 + super.requestVisible();
25.171 + }
25.172 + }
25.173 +
25.174 + @Override
25.175 + public void requestActive() {
25.176 + if (multiViewObserver != null) {
25.177 + multiViewObserver.requestActive();
25.178 + } else {
25.179 + super.requestActive();
25.180 + }
25.181 + }
25.182 +
25.183 +
25.184 + @Override
25.185 + public void updateName() {
25.186 + super.updateName();
25.187 + if (multiViewObserver != null) {
25.188 + TopComponent tc = multiViewObserver.getTopComponent();
25.189 + tc.setHtmlDisplayName(getHtmlDisplayName());
25.190 + tc.setDisplayName(getDisplayName());
25.191 + tc.setName(getName());
25.192 + tc.setToolTipText(getToolTipText());
25.193 + }
25.194 + }
25.195 +
25.196 + @Override
25.197 + public void open() {
25.198 + if (multiViewObserver != null) {
25.199 + multiViewObserver.requestVisible();
25.200 + } else {
25.201 + super.open();
25.202 + }
25.203 +
25.204 + }
25.205 +
25.206 + @Override
25.207 + protected boolean closeLast() {
25.208 + return super.closeLast(false);
25.209 + }
25.210 +
25.211 + @Messages({
25.212 + "MSG_SaveModified=File {0} is modified. Save?"
25.213 + })
25.214 + @Override
25.215 + public CloseOperationState canCloseElement() {
25.216 + final CloneableEditorSupport sup = getLookup().lookup(CloneableEditorSupport.class);
25.217 + Enumeration en = getReference().getComponents();
25.218 + if (en.hasMoreElements()) {
25.219 + en.nextElement();
25.220 + if (en.hasMoreElements()) {
25.221 + // at least two is OK
25.222 + return CloseOperationState.STATE_OK;
25.223 + }
25.224 + }
25.225 +
25.226 + Savable sav = getLookup().lookup(Savable.class);
25.227 + if (sav != null) {
25.228 + AbstractAction save = new AbstractAction() {
25.229 + @Override
25.230 + public void actionPerformed(ActionEvent e) {
25.231 + try {
25.232 + sup.saveDocument();
25.233 + } catch (IOException ex) {
25.234 + Exceptions.printStackTrace(ex);
25.235 + }
25.236 + }
25.237 + };
25.238 + save.putValue(Action.LONG_DESCRIPTION, Bundle.MSG_SaveModified(sav));
25.239 + return MultiViewFactory.createUnsafeCloseState("editor", save, null);
25.240 + }
25.241 + return CloseOperationState.STATE_OK;
25.242 + }
25.243 +
25.244 +}
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
26.2 +++ b/core.multiview/src/org/netbeans/core/spi/multiview/text/MultiViewEditorElement.java Wed May 25 16:50:33 2011 +0200
26.3 @@ -0,0 +1,186 @@
26.4 +/*
26.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
26.6 + *
26.7 + * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
26.8 + *
26.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
26.10 + * Other names may be trademarks of their respective owners.
26.11 + *
26.12 + * The contents of this file are subject to the terms of either the GNU
26.13 + * General Public License Version 2 only ("GPL") or the Common
26.14 + * Development and Distribution License("CDDL") (collectively, the
26.15 + * "License"). You may not use this file except in compliance with the
26.16 + * License. You can obtain a copy of the License at
26.17 + * http://www.netbeans.org/cddl-gplv2.html
26.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
26.19 + * specific language governing permissions and limitations under the
26.20 + * License. When distributing the software, include this License Header
26.21 + * Notice in each file and include the License file at
26.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
26.23 + * particular file as subject to the "Classpath" exception as provided
26.24 + * by Oracle in the GPL Version 2 section of the License file that
26.25 + * accompanied this code. If applicable, add the following below the
26.26 + * License Header, with the fields enclosed by brackets [] replaced by
26.27 + * your own identifying information:
26.28 + * "Portions Copyrighted [year] [name of copyright owner]"
26.29 + *
26.30 + * If you wish your version of this file to be governed by only the CDDL
26.31 + * or only the GPL Version 2, indicate your decision by adding
26.32 + * "[Contributor] elects to include this software in this distribution
26.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
26.34 + * single choice of license, a recipient has the option to distribute
26.35 + * your version of this file under either the CDDL, the GPL Version 2 or
26.36 + * to extend the choice of license to its licensees as provided above.
26.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
26.38 + * Version 2 license, then the option applies only if the new code is
26.39 + * made subject to such option by the copyright holder.
26.40 + *
26.41 + * Contributor(s):
26.42 + *
26.43 + * Portions Copyrighted 2011 Sun Microsystems, Inc.
26.44 + */
26.45 +package org.netbeans.core.spi.multiview.text;
26.46 +
26.47 +import java.io.Serializable;
26.48 +import javax.swing.Action;
26.49 +import javax.swing.JComponent;
26.50 +import javax.swing.JEditorPane;
26.51 +import org.netbeans.core.api.multiview.MultiViews;
26.52 +import org.netbeans.core.spi.multiview.CloseOperationState;
26.53 +import org.netbeans.core.spi.multiview.MultiViewElement;
26.54 +import org.netbeans.core.spi.multiview.MultiViewElement.Registration;
26.55 +import org.netbeans.core.spi.multiview.MultiViewElementCallback;
26.56 +import org.openide.awt.UndoRedo;
26.57 +import org.openide.text.CloneableEditorSupport;
26.58 +import org.openide.util.Lookup;
26.59 +import org.openide.windows.CloneableTopComponent;
26.60 +
26.61 +/** Standard {@link MultiViewElement} to integrate editor with
26.62 + * {@link MultiViews}. It can be used directly via a factory method:
26.63 + * <pre>
26.64 + <code>@</code>MultiViewElement.Registration(
26.65 + displayName = "#BUNDLE_KEY",
26.66 + iconBase = "path/to/some-icon.png",
26.67 + mimeType = "text/yourmime",
26.68 + persistenceType = TopComponent.PERSISTENCE_ONLY_OPENED,
26.69 + preferredID = "yourId",
26.70 + position = 1000
26.71 + )
26.72 + public static MultiViewEditorElement createEditor(Lookup lkp) {
26.73 + return new MultiViewEditorElement(lkp);
26.74 + }</pre>
26.75 + * Or one can subclass the class, override some methods (it is recommended
26.76 + * to continue to call super implementation) and register the
26.77 + * subclass.
26.78 + *
26.79 + * @author Jaroslav Tulach <jtulach@netbeans.org>
26.80 + * @since 1.24
26.81 + */
26.82 +public class MultiViewEditorElement implements
26.83 +MultiViewElement, CloneableEditorSupport.Pane, Serializable {
26.84 + static final long serialVersionUID = 430840231840923L;
26.85 +
26.86 + private MultiViewCloneableEditor editor;
26.87 +
26.88 + /** Constructor suitable for use with {@link Registration} annotation.
26.89 + * The {@link Lookup} parameter is expected to contain
26.90 + * {@link CloneableEditorSupport}, otherwise it yields an exception
26.91 + *
26.92 + * @param lookup context for the editor. Should contain instance of {@link CloneableEditorSupport}
26.93 + * class
26.94 + * @throws IllegalArgumentException if {@link CloneableEditorSupport} is not present
26.95 + * in provided {@link Lookup}
26.96 + */
26.97 + public MultiViewEditorElement(Lookup lookup) {
26.98 + CloneableEditorSupport sup = lookup.lookup(CloneableEditorSupport.class);
26.99 + if (sup == null) {
26.100 + throw new IllegalArgumentException("We expect CloneableEditorSupport in " + lookup);
26.101 + }
26.102 + editor = new MultiViewCloneableEditor(sup);
26.103 + }
26.104 +
26.105 + @Override
26.106 + public JComponent getVisualRepresentation() {
26.107 + return editor.getVisualRepresentation();
26.108 + }
26.109 +
26.110 + @Override
26.111 + public JComponent getToolbarRepresentation() {
26.112 + return editor.getToolbarRepresentation();
26.113 + }
26.114 +
26.115 + @Override
26.116 + public Action[] getActions() {
26.117 + return editor.getActions();
26.118 + }
26.119 +
26.120 + @Override
26.121 + public Lookup getLookup() {
26.122 + return editor.getLookup();
26.123 + }
26.124 +
26.125 + @Override
26.126 + public void componentOpened() {
26.127 + editor.componentOpened();
26.128 + }
26.129 +
26.130 + @Override
26.131 + public void componentClosed() {
26.132 + editor.componentClosed();
26.133 + }
26.134 +
26.135 + @Override
26.136 + public void componentShowing() {
26.137 + editor.componentShowing();
26.138 + }
26.139 +
26.140 + @Override
26.141 + public void componentHidden() {
26.142 + editor.componentHidden();
26.143 + }
26.144 +
26.145 + @Override
26.146 + public void componentActivated() {
26.147 + editor.componentActivated();
26.148 + }
26.149 +
26.150 + @Override
26.151 + public void componentDeactivated() {
26.152 + editor.componentDeactivated();
26.153 + }
26.154 +
26.155 + @Override
26.156 + public UndoRedo getUndoRedo() {
26.157 + return editor.getUndoRedo();
26.158 + }
26.159 +
26.160 + @Override
26.161 + public void setMultiViewCallback(MultiViewElementCallback callback) {
26.162 + editor.setMultiViewCallback(callback);
26.163 + }
26.164 +
26.165 + @Override
26.166 + public CloseOperationState canCloseElement() {
26.167 + return editor.canCloseElement();
26.168 + }
26.169 +
26.170 + @Override
26.171 + public JEditorPane getEditorPane() {
26.172 + return editor.getEditorPane();
26.173 + }
26.174 +
26.175 + @Override
26.176 + public CloneableTopComponent getComponent() {
26.177 + return editor.getComponent();
26.178 + }
26.179 +
26.180 + @Override
26.181 + public void updateName() {
26.182 + editor.updateName();
26.183 + }
26.184 +
26.185 + @Override
26.186 + public void ensureVisible() {
26.187 + editor.ensureVisible();
26.188 + }
26.189 +}
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
27.2 +++ b/core.multiview/src/org/netbeans/core/spi/multiview/text/package.html Wed May 25 16:50:33 2011 +0200
27.3 @@ -0,0 +1,51 @@
27.4 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
27.5 +<html>
27.6 +<head>
27.7 +<!--
27.8 + - DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
27.9 + -
27.10 + - Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
27.11 + -
27.12 + - The contents of this file are subject to the terms of either the GNU
27.13 + - General Public License Version 2 only ("GPL") or the Common
27.14 + - Development and Distribution License("CDDL") (collectively, the
27.15 + - "License"). You may not use this file except in compliance with the
27.16 + - License. You can obtain a copy of the License at
27.17 + - http://www.netbeans.org/cddl-gplv2.html
27.18 + - or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
27.19 + - specific language governing permissions and limitations under the
27.20 + - License. When distributing the software, include this License Header
27.21 + - Notice in each file and include the License file at
27.22 + - nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
27.23 + - particular file as subject to the "Classpath" exception as provided
27.24 + - by Sun in the GPL Version 2 section of the License file that
27.25 + - accompanied this code. If applicable, add the following below the
27.26 + - License Header, with the fields enclosed by brackets [] replaced by
27.27 + - your own identifying information:
27.28 + - "Portions Copyrighted [year] [name of copyright owner]"
27.29 + -
27.30 + - Contributor(s):
27.31 + -
27.32 + - The Original Software is NetBeans. The Initial Developer of the Original
27.33 + - Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
27.34 + - Microsystems, Inc. All Rights Reserved.
27.35 + -
27.36 + - If you wish your version of this file to be governed by only the CDDL
27.37 + - or only the GPL Version 2, indicate your decision by adding
27.38 + - "[Contributor] elects to include this software in this distribution
27.39 + - under the [CDDL or GPL Version 2] license." If you do not indicate a
27.40 + - single choice of license, a recipient has the option to distribute
27.41 + - your version of this file under either the CDDL, the GPL Version 2 or
27.42 + - to extend the choice of license to its licensees as provided above.
27.43 + - However, if you add GPL Version 2 code and therefore, elected the GPL
27.44 + - Version 2 license, then the option applies only if the new code is
27.45 + - made subject to such option by the copyright holder.
27.46 + -->
27.47 +</head>
27.48 +<body>
27.49 + <p>
27.50 + MultiView Text provides integration between multi view
27.51 + infrastructure and common textual framework.
27.52 + </p>
27.53 +</body>
27.54 +</html>
28.1 --- a/core.multiview/test/unit/src/org/netbeans/core/multiview/MultiViewCloneableTopComponentTest.java Wed May 25 16:24:45 2011 +0200
28.2 +++ b/core.multiview/test/unit/src/org/netbeans/core/multiview/MultiViewCloneableTopComponentTest.java Wed May 25 16:50:33 2011 +0200
28.3 @@ -55,10 +55,12 @@
28.4 import java.util.Collection;
28.5 import javax.swing.Action;
28.6 import javax.swing.JEditorPane;
28.7 +import javax.swing.JPanel;
28.8 import org.netbeans.core.api.multiview.MultiViewPerspective;
28.9 import org.netbeans.core.spi.multiview.CloseOperationHandler;
28.10 import org.netbeans.core.spi.multiview.MultiViewElement;
28.11 import org.netbeans.core.spi.multiview.SourceViewMarker;
28.12 +import org.openide.text.CloneableEditor;
28.13 import org.openide.text.CloneableEditorSupport;
28.14 import org.openide.util.io.NbMarshalledObject;
28.15
28.16 @@ -161,6 +163,86 @@
28.17 assertFalse(desc3.equals(Accessor.DEFAULT.extractDescription(hand.getSelectedPerspective())));
28.18
28.19 }
28.20 + public void testUpdateNameTellsAll() throws Exception {
28.21 + class P extends CloneableEditor {
28.22 + int cnt;
28.23 + boolean used;
28.24 +
28.25 + @Override
28.26 + public void updateName() {
28.27 + cnt++;
28.28 + }
28.29 + }
28.30 + final P edit1 = new P();
28.31 + final P edit2 = new P();
28.32 + final P edit3 = new P();
28.33 +
28.34 +
28.35 + MVElem elem1 = new MVElem() {
28.36 + @Override
28.37 + public JComponent getVisualRepresentation() {
28.38 + edit1.used = true;
28.39 + return edit1;
28.40 + }
28.41 + };
28.42 + MVElem elem2 = new MVElem() {
28.43 + @Override
28.44 + public JComponent getVisualRepresentation() {
28.45 + edit2.used = true;
28.46 + return edit2;
28.47 + }
28.48 + };
28.49 + MVElem elem3 = new SourceMVElem() {
28.50 + @Override
28.51 + public JComponent getVisualRepresentation() {
28.52 + edit3.used = true;
28.53 + return edit3;
28.54 + }
28.55 + };
28.56 + MultiViewDescription desc1 = new MVDesc("desc1", null, 0, elem1);
28.57 + MultiViewDescription desc2 = new MVDesc("desc2", null, 0, elem2);
28.58 + MultiViewDescription desc3 = new SourceMVDesc("desc3", null, 0, elem3);
28.59 + MultiViewDescription[] descs = new MultiViewDescription[] { desc1, desc2, desc3 };
28.60 + CloneableTopComponent tc = MultiViewFactory.createCloneableMultiView(descs, desc1);
28.61 +
28.62 + tc.open();
28.63 + tc.requestActive();
28.64 + CloneableEditorSupport.Pane pane = (CloneableEditorSupport.Pane)tc;
28.65 +
28.66 + assertTrue("First one is used", edit1.used);
28.67 + assertFalse("Second one is not used", edit2.used);
28.68 + assertFalse("Third one is not used", edit3.used);
28.69 +
28.70 + edit1.cnt = 0;
28.71 + edit2.cnt = 0;
28.72 + edit3.cnt = 0;
28.73 + pane.updateName();
28.74 +
28.75 + assertTrue("First one is used (obviously)", edit1.used);
28.76 + assertFalse("Second one is still not used", edit2.used);
28.77 + assertTrue("Third one is now used", edit3.used);
28.78 +
28.79 + assertEquals("Update name called on first as it is used", 1, edit1.cnt);
28.80 + assertEquals("Update name called on third as it marked", 1, edit3.cnt);
28.81 + assertEquals("No call to 2nd one", 0, edit2.cnt);
28.82 +
28.83 + MultiViewHandler h = MultiViews.findMultiViewHandler(tc);
28.84 + h.requestActive(h.getPerspectives()[1]);
28.85 + h.requestVisible(h.getPerspectives()[1]);
28.86 +
28.87 + edit1.cnt = 0;
28.88 + edit2.cnt = 0;
28.89 + edit3.cnt = 0;
28.90 + pane.updateName();
28.91 +
28.92 + assertTrue("1st is used", edit1.used);
28.93 + assertTrue("2nd is used", edit2.used);
28.94 + assertTrue("3rd is now used", edit3.used);
28.95 +
28.96 + assertEquals("All updateName called: 1st", 1, edit1.cnt);
28.97 + assertEquals("All updateName called: 2nd", 1, edit2.cnt);
28.98 + assertEquals("All updateName called: 3rd", 1, edit3.cnt);
28.99 + }
28.100
28.101 private class SourceMVDesc extends MVDesc implements SourceViewMarker {
28.102 public SourceMVDesc(String name, Image img, int persType, MultiViewElement element) {
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
29.2 +++ b/core.multiview/test/unit/src/org/netbeans/core/multiview/MultiViewProcessorTest.java Wed May 25 16:50:33 2011 +0200
29.3 @@ -0,0 +1,464 @@
29.4 +/*
29.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
29.6 + *
29.7 + * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
29.8 + *
29.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
29.10 + * Other names may be trademarks of their respective owners.
29.11 + *
29.12 + * The contents of this file are subject to the terms of either the GNU
29.13 + * General Public License Version 2 only ("GPL") or the Common
29.14 + * Development and Distribution License("CDDL") (collectively, the
29.15 + * "License"). You may not use this file except in compliance with the
29.16 + * License. You can obtain a copy of the License at
29.17 + * http://www.netbeans.org/cddl-gplv2.html
29.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
29.19 + * specific language governing permissions and limitations under the
29.20 + * License. When distributing the software, include this License Header
29.21 + * Notice in each file and include the License file at
29.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
29.23 + * particular file as subject to the "Classpath" exception as provided
29.24 + * by Oracle in the GPL Version 2 section of the License file that
29.25 + * accompanied this code. If applicable, add the following below the
29.26 + * License Header, with the fields enclosed by brackets [] replaced by
29.27 + * your own identifying information:
29.28 + * "Portions Copyrighted [year] [name of copyright owner]"
29.29 + *
29.30 + * If you wish your version of this file to be governed by only the CDDL
29.31 + * or only the GPL Version 2, indicate your decision by adding
29.32 + * "[Contributor] elects to include this software in this distribution
29.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
29.34 + * single choice of license, a recipient has the option to distribute
29.35 + * your version of this file under either the CDDL, the GPL Version 2 or
29.36 + * to extend the choice of license to its licensees as provided above.
29.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
29.38 + * Version 2 license, then the option applies only if the new code is
29.39 + * made subject to such option by the copyright holder.
29.40 + *
29.41 + * Contributor(s):
29.42 + *
29.43 + * Portions Copyrighted 2011 Sun Microsystems, Inc.
29.44 + */
29.45 +package org.netbeans.core.multiview;
29.46 +
29.47 +import java.awt.Dialog;
29.48 +import java.awt.event.ActionEvent;
29.49 +import java.io.ByteArrayOutputStream;
29.50 +import java.io.Serializable;
29.51 +import java.util.Arrays;
29.52 +import java.util.HashMap;
29.53 +import java.util.Map;
29.54 +import java.util.logging.Level;
29.55 +import javax.swing.AbstractAction;
29.56 +import javax.swing.Action;
29.57 +import javax.swing.JComponent;
29.58 +import javax.swing.JEditorPane;
29.59 +import javax.swing.JPanel;
29.60 +import org.netbeans.api.editor.mimelookup.MimeLookup;
29.61 +import org.netbeans.api.editor.mimelookup.MimeRegistration;
29.62 +import org.netbeans.core.api.multiview.MultiViewHandler;
29.63 +import org.netbeans.core.api.multiview.MultiViewPerspective;
29.64 +import org.netbeans.core.api.multiview.MultiViews;
29.65 +import org.netbeans.core.spi.multiview.CloseOperationHandler;
29.66 +import org.netbeans.core.spi.multiview.CloseOperationState;
29.67 +import org.netbeans.core.spi.multiview.MultiViewDescription;
29.68 +import org.netbeans.core.spi.multiview.MultiViewElement;
29.69 +import org.netbeans.core.spi.multiview.MultiViewElementCallback;
29.70 +import org.netbeans.core.spi.multiview.MultiViewFactory;
29.71 +import org.netbeans.junit.Log;
29.72 +import org.netbeans.junit.MockServices;
29.73 +import org.netbeans.junit.NbTestCase;
29.74 +import org.openide.DialogDescriptor;
29.75 +import org.openide.DialogDisplayer;
29.76 +import org.openide.NotifyDescriptor;
29.77 +import org.openide.awt.UndoRedo;
29.78 +import org.openide.text.CloneableEditorSupport;
29.79 +import org.openide.util.Lookup;
29.80 +import org.openide.util.io.NbMarshalledObject;
29.81 +import org.openide.util.lookup.AbstractLookup;
29.82 +import org.openide.util.lookup.InstanceContent;
29.83 +import org.openide.util.test.AnnotationProcessorTestUtils;
29.84 +import org.openide.windows.CloneableTopComponent;
29.85 +import org.openide.windows.TopComponent;
29.86 +
29.87 +/**
29.88 + *
29.89 + * @author Jaroslav Tulach <jtulach@netbeans.org>
29.90 + */
29.91 +public class MultiViewProcessorTest extends NbTestCase {
29.92 +
29.93 + public MultiViewProcessorTest(String n) {
29.94 + super(n);
29.95 + }
29.96 +
29.97 + @Override
29.98 + protected void setUp() throws Exception {
29.99 + MVE.closeState = null;
29.100 + CloseH.globalElements = null;
29.101 + CloseH.retValue = null;
29.102 + DD.d = null;
29.103 + DD.ret = -1;
29.104 + MockServices.setServices(DD.class);
29.105 + }
29.106 +
29.107 + public void testMultiViewsCreate() {
29.108 + TopComponent mvc = MultiViews.createMultiView("text/figaro", new LP(Lookup.EMPTY));
29.109 + assertNotNull("MultiViewComponent created", mvc);
29.110 + mvc.open();
29.111 + mvc.requestActive();
29.112 +
29.113 + MultiViewHandler handler = MultiViews.findMultiViewHandler(mvc);
29.114 + assertNotNull("Handler found", handler);
29.115 + MultiViewPerspective[] arr = handler.getPerspectives();
29.116 + assertEquals("One perspetive found", 1, arr.length);
29.117 + assertEquals("Figaro", arr[0].getDisplayName());
29.118 +
29.119 + CloseH.retValue = true;
29.120 + MVE.closeState = MultiViewFactory.createUnsafeCloseState("warn", null, null);
29.121 + assertTrue("Closed OK", mvc.close());
29.122 + assertNotNull(CloseH.globalElements);
29.123 + assertEquals("One handle", 1, CloseH.globalElements.length);
29.124 + assertEquals("states are the same", MVE.closeState, CloseH.globalElements[0]);
29.125 + }
29.126 +
29.127 + public void testCloneableMultiViewsCreate() {
29.128 + InstanceContent ic = new InstanceContent();
29.129 + Lookup lookup = new AbstractLookup(ic);
29.130 +
29.131 + CloneableTopComponent cmv = MultiViews.createCloneableMultiView("text/context", new LP(lookup));
29.132 + assertNotNull("MultiViewComponent created", cmv);
29.133 + TopComponent mvc = cmv.cloneTopComponent();
29.134 + doCheck(mvc, ic);
29.135 +
29.136 + CntAction accept = new CntAction();
29.137 + CntAction discard = new CntAction();
29.138 + CloseH.retValue = false;
29.139 + MVE.closeState = MultiViewFactory.createUnsafeCloseState("warn", accept, discard);
29.140 + DD.ret = 2;
29.141 + mvc.open();
29.142 + assertFalse("Closed cancelled", mvc.close());
29.143 + assertEquals("No accept", 0, accept.cnt);
29.144 + assertEquals("No discard", 0, discard.cnt);
29.145 + MVE.closeState = MultiViewFactory.createUnsafeCloseState("warn", accept, discard);
29.146 + DD.ret = 1;
29.147 + DD.d = null;
29.148 + mvc.open();
29.149 + assertTrue("Changes discarded, close accepted", mvc.close());
29.150 + assertEquals("Still no accept", 0, accept.cnt);
29.151 + assertEquals("One discard", 1, discard.cnt);
29.152 + MVE.closeState = MultiViewFactory.createUnsafeCloseState("warn", accept, discard);
29.153 + DD.ret = 0;
29.154 + DD.d = null;
29.155 + mvc.open();
29.156 + assertTrue("Closed accepted OK", mvc.close());
29.157 + assertEquals("Three buttons", 3, DD.d.getOptions().length);
29.158 + assertNull("Not called, we use default handler", CloseH.globalElements);
29.159 + }
29.160 +
29.161 + public void testCloneableMultiViewsSerialize() throws Exception {
29.162 + InstanceContent ic = new InstanceContent();
29.163 + Lookup lookup = new AbstractLookup(ic);
29.164 +
29.165 + CloneableTopComponent cmv = MultiViews.createCloneableMultiView("text/context", new LP(lookup));
29.166 + assertPersistence("Always", TopComponent.PERSISTENCE_ALWAYS, cmv);
29.167 + assertNotNull("MultiViewComponent created", cmv);
29.168 + NbMarshalledObject mar = new NbMarshalledObject(cmv);
29.169 + TopComponent mvc = (TopComponent) mar.get();
29.170 + doCheck(mvc, ic);
29.171 + }
29.172 +
29.173 + private void assertPersistence(String msg, int pt, TopComponent cmv) {
29.174 + CharSequence log = Log.enable("org.netbeans.core.multiview", Level.WARNING);
29.175 + int res = cmv.getPersistenceType();
29.176 + if (log.length() > 0) {
29.177 + fail("There should be no warnings to compute getPersistenceType():\n" + log);
29.178 + }
29.179 + assertEquals(msg, pt, res);
29.180 + }
29.181 +
29.182 + private void doCheck(TopComponent mvc, InstanceContent ic) {
29.183 + assertNotNull("MultiViewComponent cloned", mvc);
29.184 + MultiViewHandler handler = MultiViews.findMultiViewHandler(mvc);
29.185 + assertNotNull("Handler found", handler);
29.186 + MultiViewPerspective[] arr = handler.getPerspectives();
29.187 + assertEquals("One perspetive found", 1, arr.length);
29.188 + assertEquals("Contextual", arr[0].getDisplayName());
29.189 +
29.190 + assertPersistence("Always", TopComponent.PERSISTENCE_ALWAYS, mvc);
29.191 +
29.192 + mvc.open();
29.193 + mvc.requestActive();
29.194 + mvc.requestVisible();
29.195 +
29.196 + handler.requestActive(arr[0]);
29.197 + assertNull("No integer now", mvc.getLookup().lookup(Integer.class));
29.198 + ic.add(1);
29.199 + assertEquals("1 now", Integer.valueOf(1), mvc.getLookup().lookup(Integer.class));
29.200 + }
29.201 +
29.202 + public void testNotSourceView() {
29.203 + int cnt = 0;
29.204 + for (MultiViewDescription d : MimeLookup.getLookup("text/context").lookupAll(MultiViewDescription.class)) {
29.205 + cnt++;
29.206 + assertFalse(
29.207 + "No view in text/context has source element",
29.208 + MultiViewCloneableTopComponent.isSourceView(d)
29.209 + );
29.210 + }
29.211 + if (cnt == 0) {
29.212 + fail("There shall be at least one description");
29.213 + }
29.214 + }
29.215 +
29.216 + public void testCompileInApt() throws Exception {
29.217 + clearWorkDir();
29.218 + String src = "\n"
29.219 + + "import org.netbeans.core.spi.multiview.MultiViewElement;\n"
29.220 + + "public class Test extends org.netbeans.core.multiview.MultiViewProcessorTest.MVE {\n"
29.221 + + "@MultiViewElement.Registration(displayName = \"Testing\","
29.222 + + "iconBase = \"none\","
29.223 + + "mimeType = \"text/ble\","
29.224 + + "persistenceType = 0,"
29.225 + + "preferredID = \"bleple\")"
29.226 + + " public static MultiViewElement create() {\n"
29.227 + + " return new Test();\n"
29.228 + + " }\n"
29.229 + + "}\n";
29.230 + AnnotationProcessorTestUtils.makeSource(getWorkDir(), "pkg.Test", src);
29.231 + ByteArrayOutputStream os = new ByteArrayOutputStream();
29.232 + boolean res = AnnotationProcessorTestUtils.runJavac(getWorkDir(), null, getWorkDir(), null, os);
29.233 + assertTrue("Compilation should succeed:\n" + os.toString(), res);
29.234 + }
29.235 +
29.236 + public void testIsSourceView() {
29.237 + int cnt = 0;
29.238 + for (MultiViewDescription d : MimeLookup.getLookup("text/plain").lookupAll(MultiViewDescription.class)) {
29.239 + cnt++;
29.240 + assertTrue(
29.241 + "All views in text/plain have source element: " + d,
29.242 + MultiViewCloneableTopComponent.isSourceView(d)
29.243 + );
29.244 + }
29.245 + if (cnt == 0) {
29.246 + fail("There shall be at least one description");
29.247 + }
29.248 + }
29.249 +
29.250 + public void testMultiViewsContextCreate() {
29.251 + InstanceContent ic = new InstanceContent();
29.252 + Lookup lookup = new AbstractLookup(ic);
29.253 +
29.254 + TopComponent mvc = MultiViews.createMultiView("text/context", new LP(lookup));
29.255 + assertNotNull("MultiViewComponent created", mvc);
29.256 + MultiViewHandler handler = MultiViews.findMultiViewHandler(mvc);
29.257 + assertNotNull("Handler found", handler);
29.258 + MultiViewPerspective[] arr = handler.getPerspectives();
29.259 + assertEquals("One perspetive found", 1, arr.length);
29.260 + assertEquals("Contextual", arr[0].getDisplayName());
29.261 +
29.262 + mvc.open();
29.263 + mvc.requestActive();
29.264 + mvc.requestVisible();
29.265 +
29.266 + handler.requestActive(arr[0]);
29.267 + assertNull("No integer now", mvc.getLookup().lookup(Integer.class));
29.268 + ic.add(1);
29.269 + assertEquals("1 now", Integer.valueOf(1), mvc.getLookup().lookup(Integer.class));
29.270 + }
29.271 +
29.272 + @MimeRegistration(mimeType="text/figaro", service=CloseOperationHandler.class)
29.273 + public static class CloseH implements CloseOperationHandler {
29.274 + static CloseOperationState[] globalElements;
29.275 + static Boolean retValue;
29.276 + @Override
29.277 + public boolean resolveCloseOperation(CloseOperationState[] elements) {
29.278 + assertNull("globalElement not specified yet", globalElements);
29.279 + assertNotNull("We know what to return", retValue);
29.280 + boolean r = retValue;
29.281 + retValue = null;
29.282 + globalElements = elements;
29.283 + return r;
29.284 + }
29.285 + }
29.286 +
29.287 + @MultiViewElement.Registration(
29.288 + displayName="org.netbeans.core.multiview.TestBundle#FIGARO",
29.289 + iconBase="none",
29.290 + mimeType="text/figaro",
29.291 + persistenceType=TopComponent.PERSISTENCE_NEVER,
29.292 + preferredID="figaro"
29.293 + )
29.294 + public static class MVE extends JPanel implements MultiViewElement {
29.295 + static CloseOperationState closeState;
29.296 +
29.297 + private JPanel toolbar = new JPanel();
29.298 +
29.299 + public MVE() {
29.300 + }
29.301 +
29.302 + @Override
29.303 + public JComponent getVisualRepresentation() {
29.304 + return this;
29.305 + }
29.306 +
29.307 + @Override
29.308 + public JComponent getToolbarRepresentation() {
29.309 + return toolbar;
29.310 + }
29.311 +
29.312 + @Override
29.313 + public Action[] getActions() {
29.314 + return new Action[0];
29.315 + }
29.316 +
29.317 + @Override
29.318 + public Lookup getLookup() {
29.319 + return Lookup.EMPTY;
29.320 + }
29.321 +
29.322 + @Override
29.323 + public void componentOpened() {
29.324 + }
29.325 +
29.326 + @Override
29.327 + public void componentClosed() {
29.328 + }
29.329 +
29.330 + @Override
29.331 + public void componentShowing() {
29.332 + }
29.333 +
29.334 + @Override
29.335 + public void componentHidden() {
29.336 + }
29.337 +
29.338 + @Override
29.339 + public void componentActivated() {
29.340 + }
29.341 +
29.342 + @Override
29.343 + public void componentDeactivated() {
29.344 + }
29.345 +
29.346 + @Override
29.347 + public UndoRedo getUndoRedo() {
29.348 + return UndoRedo.NONE;
29.349 + }
29.350 +
29.351 + @Override
29.352 + public void setMultiViewCallback(MultiViewElementCallback callback) {
29.353 + }
29.354 +
29.355 + @Override
29.356 + public CloseOperationState canCloseElement() {
29.357 + if (closeState != null) {
29.358 + return closeState;
29.359 + }
29.360 + return CloseOperationState.STATE_OK;
29.361 + }
29.362 + } // end of MVE
29.363 +
29.364 + @MultiViewElement.Registration(
29.365 + displayName="Contextual",
29.366 + iconBase="none",
29.367 + mimeType="text/context",
29.368 + persistenceType=TopComponent.PERSISTENCE_ALWAYS,
29.369 + preferredID="context"
29.370 + )
29.371 + public static CntxMVE create(Lookup lkp) {
29.372 + return new CntxMVE(lkp);
29.373 + }
29.374 + static class CntxMVE extends MVE {
29.375 + private Lookup context;
29.376 + public CntxMVE(Lookup context) {
29.377 + this.context = context;
29.378 + }
29.379 + public CntxMVE() {
29.380 + }
29.381 +
29.382 + @Override
29.383 + public Lookup getLookup() {
29.384 + return context;
29.385 + }
29.386 + } // end of CntxMVE
29.387 +
29.388 + @MultiViewElement.Registration(
29.389 + displayName="Source",
29.390 + iconBase="none",
29.391 + mimeType="text/plain",
29.392 + persistenceType=TopComponent.PERSISTENCE_NEVER,
29.393 + preferredID="source"
29.394 + )
29.395 + public static class SourceMVC extends MVE implements CloneableEditorSupport.Pane {
29.396 + @Override
29.397 + public JEditorPane getEditorPane() {
29.398 + throw new UnsupportedOperationException("Not supported yet.");
29.399 + }
29.400 +
29.401 + @Override
29.402 + public CloneableTopComponent getComponent() {
29.403 + throw new UnsupportedOperationException("Not supported yet.");
29.404 + }
29.405 +
29.406 + @Override
29.407 + public void updateName() {
29.408 + throw new UnsupportedOperationException("Not supported yet.");
29.409 + }
29.410 +
29.411 + @Override
29.412 + public void ensureVisible() {
29.413 + throw new UnsupportedOperationException("Not supported yet.");
29.414 + }
29.415 + }
29.416 +
29.417 + private static class LP implements Lookup.Provider, Serializable {
29.418 + private static final Map<Integer,Lookup> map = new HashMap<Integer, Lookup>();
29.419 +
29.420 + private final int cnt;
29.421 + public LP(Lookup lkp) {
29.422 + synchronized (map) {
29.423 + cnt = map.size() + 1;
29.424 + map.put(cnt, lkp);
29.425 + }
29.426 + }
29.427 +
29.428 + @Override
29.429 + public Lookup getLookup() {
29.430 + return map.get(cnt);
29.431 + }
29.432 + }
29.433 +
29.434 + public static final class DD extends DialogDisplayer {
29.435 + static int ret;
29.436 + static NotifyDescriptor d;
29.437 +
29.438 + @Override
29.439 + public Object notify(NotifyDescriptor descriptor) {
29.440 + assertNull("No descriptor yet", d);
29.441 + if (ret == -1) {
29.442 + fail("We should know what to return");
29.443 + }
29.444 + d = descriptor;
29.445 + if (d.getOptions().length <= ret) {
29.446 + fail("not enough options. Need index " + ret + " but is just " + Arrays.toString(d.getOptions()));
29.447 + }
29.448 + Object obj = d.getOptions()[ret];
29.449 + ret = -1;
29.450 + return obj;
29.451 + }
29.452 +
29.453 + @Override
29.454 + public Dialog createDialog(DialogDescriptor descriptor) {
29.455 + throw new UnsupportedOperationException("Not supported yet.");
29.456 + }
29.457 + }
29.458 +
29.459 + private static final class CntAction extends AbstractAction {
29.460 + int cnt;
29.461 +
29.462 + @Override
29.463 + public void actionPerformed(ActionEvent e) {
29.464 + cnt++;
29.465 + }
29.466 + }
29.467 +}
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
30.2 +++ b/core.multiview/test/unit/src/org/netbeans/core/multiview/TestBundle.properties Wed May 25 16:50:33 2011 +0200
30.3 @@ -0,0 +1,41 @@
30.4 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
30.5 +#
30.6 +# Copyright 2011 Oracle and/or its affiliates. All rights reserved.
30.7 +#
30.8 +# Oracle and Java are registered trademarks of Oracle and/or its affiliates.
30.9 +# Other names may be trademarks of their respective owners.
30.10 +#
30.11 +# The contents of this file are subject to the terms of either the GNU
30.12 +# General Public License Version 2 only ("GPL") or the Common
30.13 +# Development and Distribution License("CDDL") (collectively, the
30.14 +# "License"). You may not use this file except in compliance with the
30.15 +# License. You can obtain a copy of the License at
30.16 +# http://www.netbeans.org/cddl-gplv2.html
30.17 +# or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
30.18 +# specific language governing permissions and limitations under the
30.19 +# License. When distributing the software, include this License Header
30.20 +# Notice in each file and include the License file at
30.21 +# nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
30.22 +# particular file as subject to the "Classpath" exception as provided
30.23 +# by Oracle in the GPL Version 2 section of the License file that
30.24 +# accompanied this code. If applicable, add the following below the
30.25 +# License Header, with the fields enclosed by brackets [] replaced by
30.26 +# your own identifying information:
30.27 +# "Portions Copyrighted [year] [name of copyright owner]"
30.28 +#
30.29 +# If you wish your version of this file to be governed by only the CDDL
30.30 +# or only the GPL Version 2, indicate your decision by adding
30.31 +# "[Contributor] elects to include this software in this distribution
30.32 +# under the [CDDL or GPL Version 2] license." If you do not indicate a
30.33 +# single choice of license, a recipient has the option to distribute
30.34 +# your version of this file under either the CDDL, the GPL Version 2 or
30.35 +# to extend the choice of license to its licensees as provided above.
30.36 +# However, if you add GPL Version 2 code and therefore, elected the GPL
30.37 +# Version 2 license, then the option applies only if the new code is
30.38 +# made subject to such option by the copyright holder.
30.39 +#
30.40 +# Contributor(s):
30.41 +#
30.42 +# Portions Copyrighted 2011 Sun Microsystems, Inc.
30.43 +
30.44 +FIGARO=Figaro
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
31.2 +++ b/core.multiview/test/unit/src/org/netbeans/core/spi/multiview/text/MultiViewEditorElementTest.java Wed May 25 16:50:33 2011 +0200
31.3 @@ -0,0 +1,273 @@
31.4 +/*
31.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
31.6 + *
31.7 + * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
31.8 + *
31.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
31.10 + * Other names may be trademarks of their respective owners.
31.11 + *
31.12 + * The contents of this file are subject to the terms of either the GNU
31.13 + * General Public License Version 2 only ("GPL") or the Common
31.14 + * Development and Distribution License("CDDL") (collectively, the
31.15 + * "License"). You may not use this file except in compliance with the
31.16 + * License. You can obtain a copy of the License at
31.17 + * http://www.netbeans.org/cddl-gplv2.html
31.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
31.19 + * specific language governing permissions and limitations under the
31.20 + * License. When distributing the software, include this License Header
31.21 + * Notice in each file and include the License file at
31.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
31.23 + * particular file as subject to the "Classpath" exception as provided
31.24 + * by Oracle in the GPL Version 2 section of the License file that
31.25 + * accompanied this code. If applicable, add the following below the
31.26 + * License Header, with the fields enclosed by brackets [] replaced by
31.27 + * your own identifying information:
31.28 + * "Portions Copyrighted [year] [name of copyright owner]"
31.29 + *
31.30 + * If you wish your version of this file to be governed by only the CDDL
31.31 + * or only the GPL Version 2, indicate your decision by adding
31.32 + * "[Contributor] elects to include this software in this distribution
31.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
31.34 + * single choice of license, a recipient has the option to distribute
31.35 + * your version of this file under either the CDDL, the GPL Version 2 or
31.36 + * to extend the choice of license to its licensees as provided above.
31.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
31.38 + * Version 2 license, then the option applies only if the new code is
31.39 + * made subject to such option by the copyright holder.
31.40 + *
31.41 + * Contributor(s):
31.42 + *
31.43 + * Portions Copyrighted 2011 Sun Microsystems, Inc.
31.44 + */
31.45 +package org.netbeans.core.spi.multiview.text;
31.46 +
31.47 +import java.beans.PropertyChangeListener;
31.48 +import java.beans.VetoableChangeListener;
31.49 +import java.io.ByteArrayInputStream;
31.50 +import java.io.ByteArrayOutputStream;
31.51 +import java.io.IOException;
31.52 +import java.io.InputStream;
31.53 +import java.io.OutputStream;
31.54 +import java.io.Serializable;
31.55 +import java.util.Date;
31.56 +import org.netbeans.junit.NbTestCase;
31.57 +import org.openide.text.CloneableEditorSupport;
31.58 +import org.openide.util.Lookup;
31.59 +import org.openide.util.io.NbMarshalledObject;
31.60 +import org.openide.util.lookup.AbstractLookup;
31.61 +import org.openide.util.lookup.InstanceContent;
31.62 +import org.openide.windows.CloneableOpenSupport;
31.63 +
31.64 +
31.65 +/**
31.66 + *
31.67 + * @author Jaroslav Tulach <jtulach@netbeans.org>
31.68 + */
31.69 +public class MultiViewEditorElementTest extends NbTestCase {
31.70 +
31.71 + public MultiViewEditorElementTest(String n) {
31.72 + super(n);
31.73 + }
31.74 +
31.75 + public void testLookupMustContainCES() throws Exception {
31.76 + try {
31.77 + MultiViewEditorElement mvee = new MultiViewEditorElement(Lookup.EMPTY);
31.78 + } catch (IllegalArgumentException ex) {
31.79 + // OK
31.80 + return;
31.81 + }
31.82 + fail("Should throw an exception");
31.83 + }
31.84 +
31.85 + public void testSerializeAndDeserialize() throws Exception {
31.86 + InstanceContent ic = new InstanceContent();
31.87 + Lookup context = new AbstractLookup(ic);
31.88 +
31.89 + Env env = new Env();
31.90 + CES ces = new CES(env, context);
31.91 + env.setSupport(ces);
31.92 + ic.add(ces);
31.93 + ic.add(10);
31.94 +
31.95 + MultiViewEditorElement mvee = new MultiViewEditorElement(context);
31.96 +
31.97 + assertEquals("ces", ces, mvee.getLookup().lookup(CloneableEditorSupport.class));
31.98 + assertEquals("ten", Integer.valueOf(10), mvee.getLookup().lookup(Integer.class));
31.99 +
31.100 + NbMarshalledObject mar = new NbMarshalledObject(mvee);
31.101 + MultiViewEditorElement deser = (MultiViewEditorElement)mar.get();
31.102 +
31.103 + assertEquals("ten", Integer.valueOf(10), deser.getLookup().lookup(Integer.class));
31.104 + assertEquals("ces", ces, deser.getLookup().lookup(CloneableEditorSupport.class));
31.105 + }
31.106 +
31.107 +
31.108 + static class CES extends CloneableEditorSupport {
31.109 + public CES(Env env, Lookup l) {
31.110 + super(env, l);
31.111 + }
31.112 +
31.113 + @Override
31.114 + protected String messageSave() {
31.115 + return "do save";
31.116 + }
31.117 +
31.118 + @Override
31.119 + protected String messageName() {
31.120 + return "MY NAME";
31.121 + }
31.122 +
31.123 + @Override
31.124 + protected String messageToolTip() {
31.125 + return "tool tip";
31.126 + }
31.127 +
31.128 + @Override
31.129 + protected String messageOpening() {
31.130 + return "about to open";
31.131 + }
31.132 +
31.133 + @Override
31.134 + protected String messageOpened() {
31.135 + return "done opening";
31.136 + }
31.137 + } // end of CES
31.138 +
31.139 + /** Helper Env implementation. */
31.140 + public static class Env extends Object
31.141 + implements CloneableEditorSupport.Env, Serializable {
31.142 + private static Env LAST_ONE;
31.143 +
31.144 + /** object to serialize and be connected to*/
31.145 + private transient String output;
31.146 + /** Reference to support instance. */
31.147 + private transient CloneableOpenSupport support;
31.148 +
31.149 + /** Constructor. Attaches itself as listener to
31.150 + * the data object so, all property changes of the data object
31.151 + * are also rethrown to own listeners.
31.152 + *
31.153 + * @param obj data object to be attached to
31.154 + */
31.155 + public Env() {
31.156 + LAST_ONE = this;
31.157 + }
31.158 +
31.159 + public void setSupport(CloneableOpenSupport support) {
31.160 + this.support = support;
31.161 + }
31.162 +
31.163 + /** Method that allows environment to find its
31.164 + * cloneable open support.
31.165 + * @return the support or null if the environemnt is not in valid
31.166 + * state and the CloneableOpenSupport cannot be found for associated
31.167 + * data object
31.168 + */
31.169 + @Override
31.170 + public CloneableOpenSupport findCloneableOpenSupport() {
31.171 + return support;
31.172 + }
31.173 +
31.174 + /** Obtains the input stream.
31.175 + * @exception IOException if an I/O error occures
31.176 + */
31.177 + @Override
31.178 + public InputStream inputStream() throws IOException {
31.179 + return new ByteArrayInputStream(output.getBytes());
31.180 + }
31.181 +
31.182 + /** Obtains the output stream.
31.183 + * @exception IOException if an I/O error occures
31.184 + */
31.185 + @Override
31.186 + public OutputStream outputStream() throws IOException {
31.187 + return new ByteArrayOutputStream() {
31.188 +
31.189 + @Override
31.190 + public void close() throws IOException {
31.191 + super.close();
31.192 + output = new String(toByteArray());
31.193 + }
31.194 + };
31.195 + }
31.196 +
31.197 + Date date = new Date();
31.198 + /** The time when the data has been modified */
31.199 + @Override
31.200 + public Date getTime() {
31.201 + return date;
31.202 + }
31.203 +
31.204 + /** Mime type of the document.
31.205 + * @return the mime type to use for the document
31.206 + */
31.207 + @Override
31.208 + public String getMimeType() {
31.209 + return "text/test";
31.210 + }
31.211 +
31.212 + /** Adds property listener.
31.213 + */
31.214 + @Override
31.215 + public void addPropertyChangeListener(PropertyChangeListener l) {
31.216 + }
31.217 +
31.218 + /** Removes property listener.
31.219 + */
31.220 + @Override
31.221 + public void removePropertyChangeListener(PropertyChangeListener l) {
31.222 + }
31.223 +
31.224 + /** Adds veto listener.
31.225 + */
31.226 + @Override
31.227 + public void addVetoableChangeListener(VetoableChangeListener l) {
31.228 + }
31.229 +
31.230 + /** Removes veto listener.
31.231 + */
31.232 + @Override
31.233 + public void removeVetoableChangeListener(VetoableChangeListener l) {
31.234 + }
31.235 +
31.236 + /** Test whether the support is in valid state or not.
31.237 + * It could be invalid after deserialization when the object it
31.238 + * referenced to does not exist anymore.
31.239 + *
31.240 + * @return true or false depending on its state
31.241 + */
31.242 + @Override
31.243 + public boolean isValid() {
31.244 + return true;
31.245 + }
31.246 +
31.247 + /** Test whether the object is modified or not.
31.248 + * @return true if the object is modified
31.249 + */
31.250 + @Override
31.251 + public boolean isModified() {
31.252 + return false;
31.253 + }
31.254 +
31.255 + /** Support for marking the environement modified.
31.256 + * @exception IOException if the environment cannot be marked modified
31.257 + * (for example when the file is readonly), when such exception
31.258 + * is the support should discard all previous changes
31.259 + */
31.260 + @Override
31.261 + public void markModified() throws java.io.IOException {
31.262 + }
31.263 +
31.264 + /** Reverse method that can be called to make the environment
31.265 + * unmodified.
31.266 + */
31.267 + @Override
31.268 + public void unmarkModified() {
31.269 + }
31.270 +
31.271 + private Object readResolve() {
31.272 + return LAST_ONE;
31.273 + }
31.274 + } // End of Env class.
31.275 +
31.276 +}
32.1 --- a/form/nbproject/project.xml Wed May 25 16:24:45 2011 +0200
32.2 +++ b/form/nbproject/project.xml Wed May 25 16:50:33 2011 +0200
32.3 @@ -98,7 +98,7 @@
32.4 <compile-dependency/>
32.5 <run-dependency>
32.6 <release-version>1</release-version>
32.7 - <specification-version>1.10</specification-version>
32.8 + <specification-version>1.24</specification-version>
32.9 </run-dependency>
32.10 </dependency>
32.11 <dependency>
32.12 @@ -163,6 +163,15 @@
32.13 </run-dependency>
32.14 </dependency>
32.15 <dependency>
32.16 + <code-name-base>org.netbeans.modules.editor.mimelookup</code-name-base>
32.17 + <build-prerequisite/>
32.18 + <compile-dependency/>
32.19 + <run-dependency>
32.20 + <release-version>1</release-version>
32.21 + <specification-version>1.21</specification-version>
32.22 + </run-dependency>
32.23 + </dependency>
32.24 + <dependency>
32.25 <code-name-base>org.netbeans.modules.java.project</code-name-base>
32.26 <build-prerequisite/>
32.27 <compile-dependency/>
33.1 --- a/form/src/org/netbeans/modules/form/FormDesignerTC.java Wed May 25 16:24:45 2011 +0200
33.2 +++ b/form/src/org/netbeans/modules/form/FormDesignerTC.java Wed May 25 16:50:33 2011 +0200
33.3 @@ -64,16 +64,23 @@
33.4 import org.netbeans.modules.form.assistant.AssistantView;
33.5 import org.openide.actions.FileSystemAction;
33.6 import org.openide.awt.StatusDisplayer;
33.7 +import org.openide.filesystems.FileUtil;
33.8 +import org.openide.util.ContextAwareAction;
33.9 import org.openide.util.HelpCtx;
33.10 import org.openide.util.ImageUtilities;
33.11 +import org.openide.util.Lookup;
33.12 import org.openide.util.actions.SystemAction;
33.13 import org.openide.util.lookup.ProxyLookup;
33.14 import org.openide.windows.TopComponent;
33.15
33.16 -/**
33.17 - *
33.18 - * @author Tomas Pavek
33.19 - */
33.20 +@MultiViewElement.Registration(
33.21 + displayName="#CTL_DesignTabCaption",
33.22 + iconBase=FormEditorSupport.iconURL,
33.23 + persistenceType=TopComponent.PERSISTENCE_NEVER,
33.24 + preferredID=FormEditorSupport.MV_FORM_ID,
33.25 + mimeType="text/x-form",
33.26 + position=2000
33.27 +)
33.28 public class FormDesignerTC extends TopComponent implements MultiViewElement {
33.29
33.30 private FormEditorSupport formEditorSupport;
33.31 @@ -92,6 +99,10 @@
33.32 private static String iconURL =
33.33 "org/netbeans/modules/form/resources/formDesigner.gif"; // NOI18N
33.34
33.35 + public FormDesignerTC(Lookup lkp) {
33.36 + this(lkp.lookup(FormEditorSupport.class));
33.37 + }
33.38 +
33.39 FormDesignerTC(FormEditorSupport formEditorSupport) {
33.40 this.formEditorSupport = formEditorSupport;
33.41 lookup = new FormDesignerLookup();
33.42 @@ -345,16 +356,7 @@
33.43
33.44 @Override
33.45 public CloseOperationState canCloseElement() {
33.46 - // if this is not the last cloned designer, closing is OK
33.47 - if (!FormEditorSupport.isLastView(multiViewObserver.getTopComponent())) {
33.48 - return CloseOperationState.STATE_OK;
33.49 - }
33.50 -
33.51 - // return a placeholder state - to be sure our CloseHandler is called
33.52 - return MultiViewFactory.createUnsafeCloseState(
33.53 - "ID_FORM_CLOSING", // dummy ID // NOI18N
33.54 - MultiViewFactory.NOOP_CLOSE_ACTION,
33.55 - MultiViewFactory.NOOP_CLOSE_ACTION);
33.56 + return formEditorSupport.canCloseElement(multiViewObserver.getTopComponent());
33.57 }
33.58
33.59 @Override
34.1 --- a/form/src/org/netbeans/modules/form/FormEditorSupport.java Wed May 25 16:24:45 2011 +0200
34.2 +++ b/form/src/org/netbeans/modules/form/FormEditorSupport.java Wed May 25 16:50:33 2011 +0200
34.3 @@ -46,6 +46,7 @@
34.4
34.5 import java.awt.Cursor;
34.6 import java.awt.EventQueue;
34.7 +import java.awt.event.ActionEvent;
34.8 import java.beans.BeanInfo;
34.9 import java.beans.PropertyChangeEvent;
34.10 import java.beans.PropertyChangeListener;
34.11 @@ -70,6 +71,8 @@
34.12 import java.util.Set;
34.13 import java.util.logging.Level;
34.14 import java.util.logging.Logger;
34.15 +import javax.swing.AbstractAction;
34.16 +import javax.swing.Action;
34.17 import javax.swing.JButton;
34.18 import javax.swing.JComponent;
34.19 import javax.swing.JEditorPane;
34.20 @@ -111,6 +114,7 @@
34.21 import org.openide.filesystems.FileStatusEvent;
34.22 import org.openide.filesystems.FileStatusListener;
34.23 import org.openide.filesystems.FileSystem;
34.24 +import org.openide.filesystems.FileUtil;
34.25 import org.openide.loaders.DataObject;
34.26 import org.openide.loaders.MultiDataObject;
34.27 import org.openide.nodes.CookieSet;
34.28 @@ -122,8 +126,12 @@
34.29 import org.openide.text.DataEditorSupport;
34.30 import org.openide.text.NbDocument;
34.31 import org.openide.text.PositionRef;
34.32 +import org.openide.util.ContextAwareAction;
34.33 +import org.openide.util.Exceptions;
34.34 import org.openide.util.ImageUtilities;
34.35 +import org.openide.util.Lookup;
34.36 import org.openide.util.Mutex;
34.37 +import org.openide.util.NbBundle.Messages;
34.38 import org.openide.util.UserQuestionException;
34.39 import org.openide.windows.CloneableOpenSupport;
34.40 import org.openide.windows.CloneableTopComponent;
34.41 @@ -141,7 +149,7 @@
34.42 public class FormEditorSupport extends DataEditorSupport implements EditorCookie.Observable, CloseCookie, PrintCookie {
34.43
34.44 /** ID of the form designer (in the multiview) */
34.45 - private static final String MV_FORM_ID = "form"; //NOI18N
34.46 + static final String MV_FORM_ID = "form"; //NOI18N
34.47 /** ID of the java editor (in the multiview) */
34.48 private static final String MV_JAVA_ID = "java"; // NOI18N
34.49
34.50 @@ -153,7 +161,7 @@
34.51 private static final String SECTION_VARIABLES = "variables"; // NOI18N
34.52
34.53 /** Icon for the form editor multiview window */
34.54 - private static final String iconURL =
34.55 + static final String iconURL =
34.56 "org/netbeans/modules/form/resources/form.gif"; // NOI18N
34.57
34.58 /** The DataObject of the form */
34.59 @@ -833,14 +841,8 @@
34.60 if (!formDataObject.isValid()) {
34.61 return super.createPane(); // Issue 110249
34.62 }
34.63 - MultiViewDescription[] descs = new MultiViewDescription[] {
34.64 - new JavaDesc(formDataObject), new FormDesc(formDataObject) };
34.65
34.66 - CloneableTopComponent mvtc =
34.67 - MultiViewFactory.createCloneableMultiView(
34.68 - descs,
34.69 - descs[elementToOpen],
34.70 - new CloseHandler(formDataObject));
34.71 + CloneableTopComponent mvtc = MultiViews.createCloneableMultiView("text/x-form", getDataObject());
34.72
34.73 // #45665 - dock into editor mode if possible..
34.74 Mode editorMode = WindowManager.getDefault().findMode(CloneableEditorSupport.EDITOR_MODE);
34.75 @@ -976,6 +978,40 @@
34.76 });
34.77 }
34.78 }
34.79 +
34.80 + @Messages({
34.81 + "MSG_MODIFIED=File {0} is modified. Save?"
34.82 + })
34.83 + final CloseOperationState canCloseElement(TopComponent tc) {
34.84 + // if this is not the last cloned java editor component, closing is OK
34.85 + if (!FormEditorSupport.isLastView(tc)) {
34.86 + return CloseOperationState.STATE_OK;
34.87 + }
34.88 +
34.89 + if (!isModified()) {
34.90 + return CloseOperationState.STATE_OK;
34.91 + }
34.92 +
34.93 + AbstractAction save = new AbstractAction() {
34.94 + @Override
34.95 + public void actionPerformed(ActionEvent e) {
34.96 + try {
34.97 + saveDocument();
34.98 + } catch (IOException ex) {
34.99 + Exceptions.printStackTrace(ex);
34.100 + }
34.101 + }
34.102 + };
34.103 + save.putValue(Action.LONG_DESCRIPTION, Bundle.MSG_MODIFIED(
34.104 + getDataObject().getPrimaryFile().getNameExt()
34.105 + ));
34.106 +
34.107 + // return a placeholder state - to be sure our CloseHandler is called
34.108 + return MultiViewFactory.createUnsafeCloseState(
34.109 + "ID_FORM_CLOSING", // NOI18N
34.110 + save,
34.111 + MultiViewFactory.NOOP_CLOSE_ACTION);
34.112 + }
34.113
34.114 static boolean isLastView(TopComponent tc) {
34.115 if (!(tc instanceof CloneableTopComponent))
34.116 @@ -1157,165 +1193,40 @@
34.117 }
34.118 }
34.119
34.120 - // --------
34.121 -
34.122 - /** A descriptor for the FormDesigner element of multiview. Allows lazy
34.123 - * creation of the FormDesigner (and thus form loading). */
34.124 - private static class FormDesc implements MultiViewDescription, Serializable {
34.125 -
34.126 - private static final long serialVersionUID =-3126744316624172415L;
34.127 -
34.128 - private DataObject dataObject;
34.129 -
34.130 - private FormDesc() {
34.131 - }
34.132 -
34.133 - public FormDesc(DataObject formDO) {
34.134 - dataObject = formDO;
34.135 - }
34.136 -
34.137 - private FormEditorSupport getFormEditor() {
34.138 - return dataObject != null && dataObject instanceof FormDataObject ?
34.139 - ((FormDataObject)dataObject).getFormEditorSupport() : null;
34.140 - }
34.141 -
34.142 - @Override
34.143 - public MultiViewElement createElement() {
34.144 - return new FormDesignerTC(getFormEditor());
34.145 - }
34.146 -
34.147 - @Override
34.148 - public String getDisplayName() {
34.149 - return FormUtils.getBundleString("CTL_DesignTabCaption"); // NOI18N
34.150 - }
34.151 -
34.152 - @Override
34.153 - public org.openide.util.HelpCtx getHelpCtx() {
34.154 - return org.openide.util.HelpCtx.DEFAULT_HELP;
34.155 - }
34.156 -
34.157 - @Override
34.158 - public java.awt.Image getIcon() {
34.159 - if (dataObject.isValid()) {
34.160 - return dataObject.getNodeDelegate().getIcon(BeanInfo.ICON_COLOR_16x16);
34.161 - } else {
34.162 - return ImageUtilities.loadImage(iconURL);
34.163 - }
34.164 - }
34.165 -
34.166 - @Override
34.167 - public int getPersistenceType() {
34.168 - return TopComponent.PERSISTENCE_NEVER;
34.169 - }
34.170 -
34.171 - @Override
34.172 - public String preferredID() {
34.173 - return MV_FORM_ID;
34.174 - }
34.175 -
34.176 - public void writeExternal(ObjectOutput out) throws IOException {
34.177 - out.writeObject(dataObject);
34.178 - }
34.179 -
34.180 - public void readExternal(ObjectInput in)
34.181 - throws IOException, ClassNotFoundException
34.182 - {
34.183 - Object firstObject = in.readObject();
34.184 - if (firstObject instanceof FormDataObject)
34.185 - dataObject = (DataObject) firstObject;
34.186 - }
34.187 - }
34.188 -
34.189 - // -------
34.190 -
34.191 - /** A descriptor for the java editor as an element in multiview. */
34.192 - private static class JavaDesc implements MultiViewDescription, SourceViewMarker, Serializable {
34.193 -
34.194 - private static final long serialVersionUID =-3126744316624172415L;
34.195 -
34.196 - private DataObject dataObject;
34.197 -
34.198 - private JavaDesc() {
34.199 - }
34.200 -
34.201 - public JavaDesc(DataObject formDO) {
34.202 - dataObject = formDO;
34.203 - }
34.204 -
34.205 - private FormEditorSupport getJavaEditor() {
34.206 - return dataObject != null && dataObject instanceof FormDataObject ?
34.207 - ((FormDataObject)dataObject).getFormEditorSupport() : null;
34.208 - }
34.209 -
34.210 - @Override
34.211 - public MultiViewElement createElement() {
34.212 - FormEditorSupport javaEditor = getJavaEditor();
34.213 - if (javaEditor != null) {
34.214 - javaEditor.prepareDocument();
34.215 - JavaEditorTopComponent editor = new JavaEditorTopComponent(dataObject.getCookie(FormEditorSupport.class));
34.216 - Node[] nodes = editor.getActivatedNodes();
34.217 - if ((nodes == null) || (nodes.length == 0)) {
34.218 - editor.setActivatedNodes(new Node[] {dataObject.getNodeDelegate()});
34.219 - }
34.220 - return (MultiViewElement) editor;
34.221 - }
34.222 - return MultiViewFactory.BLANK_ELEMENT;
34.223 - }
34.224 -
34.225 - @Override
34.226 - public String getDisplayName() {
34.227 - return FormUtils.getBundleString("CTL_SourceTabCaption"); // NOI18N
34.228 - }
34.229 -
34.230 - @Override
34.231 - public org.openide.util.HelpCtx getHelpCtx() {
34.232 - return org.openide.util.HelpCtx.DEFAULT_HELP;
34.233 - }
34.234 -
34.235 - @Override
34.236 - public java.awt.Image getIcon() {
34.237 - if (dataObject.isValid()) {
34.238 - return dataObject.getNodeDelegate().getIcon(BeanInfo.ICON_COLOR_16x16);
34.239 - } else {
34.240 - return ImageUtilities.loadImage(iconURL);
34.241 - }
34.242 - }
34.243 -
34.244 - @Override
34.245 - public int getPersistenceType() {
34.246 - return TopComponent.PERSISTENCE_ONLY_OPENED;
34.247 - }
34.248 -
34.249 - @Override
34.250 - public String preferredID() {
34.251 - return MV_JAVA_ID;
34.252 - }
34.253 -
34.254 - public void writeExternal(ObjectOutput out) throws IOException {
34.255 - out.writeObject(dataObject);
34.256 - }
34.257 -
34.258 - public void readExternal(ObjectInput in)
34.259 - throws IOException, ClassNotFoundException
34.260 - {
34.261 - Object firstObject = in.readObject();
34.262 - if (firstObject instanceof FormDataObject)
34.263 - dataObject = (DataObject) firstObject;
34.264 - }
34.265 - }
34.266 -
34.267 - // --------
34.268 -
34.269 - private static class JavaEditorTopComponent
34.270 + @MultiViewElement.Registration(
34.271 + displayName="#CTL_SourceTabCaption",
34.272 + iconBase=iconURL,
34.273 + persistenceType=TopComponent.PERSISTENCE_ONLY_OPENED,
34.274 + preferredID=MV_JAVA_ID,
34.275 + mimeType="text/x-form",
34.276 + position=1000
34.277 + )
34.278 + public static class JavaEditorTopComponent
34.279 extends CloneableEditor
34.280 implements MultiViewElement
34.281 {
34.282 private static final long serialVersionUID =-3126744316624172415L;
34.283
34.284 private transient JComponent toolbar;
34.285 -
34.286 + private FormEditorSupport javaEditor;
34.287 private transient MultiViewElementCallback multiViewObserver;
34.288
34.289 +
34.290 + public JavaEditorTopComponent(Lookup context) {
34.291 + super(context.lookup(DataEditorSupport.class));
34.292 + javaEditor = context.lookup(FormEditorSupport.class);
34.293 + DataObject dataObject = context.lookup(DataObject.class);
34.294 + if (javaEditor != null) {
34.295 + javaEditor.prepareDocument();
34.296 + }
34.297 + if (dataObject != null) {
34.298 + Node[] nodes = getActivatedNodes();
34.299 + if ((nodes == null) || (nodes.length == 0)) {
34.300 + setActivatedNodes(new Node[]{dataObject.getNodeDelegate()});
34.301 + }
34.302 + }
34.303 + }
34.304 +
34.305 JavaEditorTopComponent() {
34.306 super();
34.307 }
34.308 @@ -1448,15 +1359,10 @@
34.309
34.310 @Override
34.311 public CloseOperationState canCloseElement() {
34.312 - // if this is not the last cloned java editor component, closing is OK
34.313 - if (!FormEditorSupport.isLastView(multiViewObserver.getTopComponent()))
34.314 + if (javaEditor == null) {
34.315 return CloseOperationState.STATE_OK;
34.316 -
34.317 - // return a placeholder state - to be sure our CloseHandler is called
34.318 - return MultiViewFactory.createUnsafeCloseState(
34.319 - "ID_JAVA_CLOSING", // dummy ID // NOI18N
34.320 - MultiViewFactory.NOOP_CLOSE_ACTION,
34.321 - MultiViewFactory.NOOP_CLOSE_ACTION);
34.322 + }
34.323 + return javaEditor.canCloseElement(multiViewObserver.getTopComponent());
34.324 }
34.325
34.326 protected boolean isActiveTC() {
34.327 @@ -1477,41 +1383,6 @@
34.328 }
34.329 }
34.330
34.331 - // ------
34.332 -
34.333 - /** Implementation of CloseOperationHandler for multiview. Ensures both form
34.334 - * and java editor are correctly closed, data saved, etc. Holds a reference
34.335 - * to form DataObject only - to be serializable with the multiview
34.336 - * TopComponent without problems.
34.337 - */
34.338 - private static class CloseHandler implements CloseOperationHandler,
34.339 - Serializable
34.340 - {
34.341 - private static final long serialVersionUID =-3126744315424172415L;
34.342 -
34.343 - private DataObject dataObject;
34.344 -
34.345 - private CloseHandler() {
34.346 - }
34.347 -
34.348 - public CloseHandler(DataObject formDO) {
34.349 - dataObject = formDO;
34.350 - }
34.351 -
34.352 - private FormEditorSupport getFormEditor() {
34.353 - return dataObject != null && dataObject instanceof FormDataObject ?
34.354 - ((FormDataObject)dataObject).getFormEditorSupport() : null;
34.355 - }
34.356 -
34.357 - @Override
34.358 - public boolean resolveCloseOperation(CloseOperationState[] elements) {
34.359 - FormEditorSupport formEditor = getFormEditor();
34.360 - return formEditor != null ? formEditor.canClose() : true;
34.361 - }
34.362 - }
34.363 -
34.364 - // ------
34.365 -
34.366 private static final class Environment extends DataEditorSupport.Env {
34.367
34.368 private static final long serialVersionUID = -1;
35.1 --- a/nbbuild/build.properties Wed May 25 16:24:45 2011 +0200
35.2 +++ b/nbbuild/build.properties Wed May 25 16:50:33 2011 +0200
35.3 @@ -102,6 +102,7 @@
35.4 autoupdate.services,\
35.5 autoupdate.ui,\
35.6 core.ide,\
35.7 + core.multiview,\
35.8 openide.util,\
35.9 openide.util.lookup,\
35.10 openide.actions,\
35.11 @@ -168,7 +169,6 @@
35.12 jellytools.ide,\
35.13 o.openidex.util,\
35.14 core.netigso,\
35.15 - core.multiview,\
35.16 o.n.swing.outline,\
35.17 o.n.swing.tabcontrol,\
35.18 editor.indent,\
36.1 --- a/openide.loaders/apichanges.xml Wed May 25 16:24:45 2011 +0200
36.2 +++ b/openide.loaders/apichanges.xml Wed May 25 16:50:33 2011 +0200
36.3 @@ -109,6 +109,22 @@
36.4 <!-- ACTUAL CHANGES BEGIN HERE: -->
36.5
36.6 <changes>
36.7 + <change id="DataEditorSupport.create-callable">
36.8 + <api name="editor"/>
36.9 + <summary>DataEditorSupport.create(...., Callable<Pane>)</summary>
36.10 + <version major="7" minor="21"/>
36.11 + <date day="7" month="4" year="2011"/>
36.12 + <author login="jtulach"/>
36.13 + <compatibility semantic="compatible" addition="yes"/>
36.14 + <description>
36.15 + <p>
36.16 + New <code>create</code> factory method to allow creation
36.17 + of different <code>CloneableEditorSupport.Pane</code> implementations
36.18 + than the default <code>CloneableEditor</code>.
36.19 + </p>
36.20 + </description>
36.21 + <class package="org.openide.text" name="DataEditorSupport"/>
36.22 + </change>
36.23 <change id="removing.org.openide.loaders.DataFolder.lazy">
36.24 <api name="loaders"/>
36.25 <summary>Removed <code>org.openide.loaders.DataFolder.lazy</code></summary>
37.1 --- a/openide.loaders/manifest.mf Wed May 25 16:24:45 2011 +0200
37.2 +++ b/openide.loaders/manifest.mf Wed May 25 16:50:33 2011 +0200
37.3 @@ -1,6 +1,6 @@
37.4 Manifest-Version: 1.0
37.5 OpenIDE-Module: org.openide.loaders
37.6 -OpenIDE-Module-Specification-Version: 7.22
37.7 +OpenIDE-Module-Specification-Version: 7.23
37.8 OpenIDE-Module-Localizing-Bundle: org/openide/loaders/Bundle.properties
37.9 OpenIDE-Module-Provides: org.netbeans.modules.templates.v1_0
37.10 OpenIDE-Module-Layer: org/netbeans/modules/openide/loaders/layer.xml
38.1 --- a/openide.loaders/src/org/openide/text/DataEditorSupport.java Wed May 25 16:24:45 2011 +0200
38.2 +++ b/openide.loaders/src/org/openide/text/DataEditorSupport.java Wed May 25 16:50:33 2011 +0200
38.3 @@ -47,9 +47,7 @@
38.4
38.5 import java.beans.PropertyChangeEvent;
38.6 import java.beans.PropertyChangeListener;
38.7 -import java.io.BufferedInputStream;
38.8 import java.io.BufferedOutputStream;
38.9 -import java.io.BufferedReader;
38.10 import java.io.CharConversionException;
38.11 import java.io.FilterOutputStream;
38.12 import java.io.IOException;
38.13 @@ -63,7 +61,6 @@
38.14 import java.io.Reader;
38.15 import java.io.Writer;
38.16 import java.lang.ref.Reference;
38.17 -import java.nio.ByteBuffer;
38.18 import java.nio.charset.CharacterCodingException;
38.19 import java.nio.charset.Charset;
38.20 import java.nio.charset.CharsetDecoder;
38.21 @@ -74,6 +71,7 @@
38.22 import java.util.HashSet;
38.23 import java.util.Map;
38.24 import java.util.Set;
38.25 +import java.util.concurrent.Callable;
38.26 import java.util.logging.Level;
38.27 import java.util.logging.Logger;
38.28 import javax.swing.text.BadLocationException;
38.29 @@ -105,7 +103,7 @@
38.30 import org.openide.nodes.Node;
38.31 import org.openide.nodes.NodeAdapter;
38.32 import org.openide.nodes.NodeListener;
38.33 -import org.openide.util.Exceptions;
38.34 +import org.openide.util.Lookup;
38.35 import org.openide.util.Mutex;
38.36 import org.openide.util.NbBundle;
38.37 import org.openide.util.Parameters;
38.38 @@ -136,7 +134,11 @@
38.39 * @param env environment to pass to
38.40 */
38.41 public DataEditorSupport (DataObject obj, CloneableEditorSupport.Env env) {
38.42 - super (env, new DOEnvLookup (obj));
38.43 + this(obj, new DOEnvLookup (obj), env);
38.44 + }
38.45 +
38.46 + DataEditorSupport(DataObject obj, Lookup lkp, CloneableEditorSupport.Env env) {
38.47 + super (env, lkp);
38.48 this.obj = obj;
38.49 }
38.50
38.51 @@ -168,6 +170,43 @@
38.52 public static CloneableEditorSupport create (DataObject obj, MultiDataObject.Entry entry, org.openide.nodes.CookieSet set) {
38.53 return new SimpleES (obj, entry, set);
38.54 }
38.55 +
38.56 + /** Factory method to create a bit more complicated CloneableEditorSupport for a given
38.57 + * entry of a given DataObject. The common use inside DataObject looks like
38.58 + * this:
38.59 + * <pre>
38.60 + * getCookieSet().add((Node.Cookie) DataEditorSupport.create(
38.61 + * this, getPrimaryEntry(), getCookieSet(),
38.62 + * new Callable<Pane>() {
38.63 + * public Pane call() {
38.64 + * return new {@link CloneableEditor YourSubclassOfCloneableEditor}(support);
38.65 + * }
38.66 + * }
38.67 + * ));
38.68 + * </pre>
38.69 + * The method can be used to instantiate <b>multi view</b> editor by returning
38.70 + * <a href="@org-netbeans-core-multiview@/org/netbeans/core/api/multiview/MultiViews.html">
38.71 + * MultiViews.createCloneableMultiView("text/yourmime", this)</a>.
38.72 + *
38.73 + * @param obj the data object
38.74 + * @param entry the entry to read and write from
38.75 + * @param set cookie set to add remove additional cookies (currently only {@link org.openide.cookies.SaveCookie})
38.76 + * @param paneFactory callback to create editor(s) for this support
38.77 + * @return a subclass of DataEditorSupport that implements at least
38.78 + * {@link org.openide.cookies.OpenCookie},
38.79 + * {@link org.openide.cookies.EditCookie},
38.80 + * {@link org.openide.cookies.EditorCookie.Observable},
38.81 + * {@link org.openide.cookies.PrintCookie},
38.82 + * {@link org.openide.cookies.CloseCookie}
38.83 + * @since 7.21
38.84 + */
38.85 + public static CloneableEditorSupport create(
38.86 + DataObject obj, MultiDataObject.Entry entry,
38.87 + org.openide.nodes.CookieSet set,
38.88 + Callable<CloneableEditorSupport.Pane> paneFactory
38.89 + ) {
38.90 + return new SimpleES (obj, entry, set, paneFactory);
38.91 + }
38.92
38.93 /** Getter of the data object that this support is associated with.
38.94 * @return data object passed in constructor
39.1 --- a/openide.loaders/src/org/openide/text/SimpleES.java Wed May 25 16:24:45 2011 +0200
39.2 +++ b/openide.loaders/src/org/openide/text/SimpleES.java Wed May 25 16:50:33 2011 +0200
39.3 @@ -45,6 +45,7 @@
39.4 package org.openide.text;
39.5
39.6 import java.io.IOException;
39.7 +import java.util.concurrent.Callable;
39.8 import org.openide.cookies.CloseCookie;
39.9 import org.openide.cookies.EditCookie;
39.10 import org.openide.cookies.EditorCookie;
39.11 @@ -55,6 +56,7 @@
39.12 import org.openide.filesystems.FileLock;
39.13 import org.openide.loaders.DataObject;
39.14 import org.openide.loaders.MultiDataObject;
39.15 +import org.openide.loaders.MultiDataObject.Entry;
39.16 import org.openide.nodes.CookieSet;
39.17 import org.openide.nodes.Node.Cookie;
39.18 import org.openide.windows.CloneableOpenSupport;
39.19 @@ -70,21 +72,52 @@
39.20 * data object's cookie set depending on if modification flag was set/unset. */
39.21 private final SaveCookie saveCookie = new SaveCookie() {
39.22 /** Implements <code>SaveCookie</code> interface. */
39.23 + @Override
39.24 public void save() throws IOException {
39.25 SimpleES.this.saveDocument();
39.26 }
39.27 +
39.28 + @Override
39.29 + public String toString() {
39.30 + return getDataObject().getPrimaryFile().getNameExt();
39.31 + }
39.32 };
39.33
39.34 - private CookieSet set;
39.35 + private final CookieSet set;
39.36 + private final Callable<Pane> factory;
39.37
39.38 /** Constructor.
39.39 * @param obj data object to work on
39.40 * @param set set to add/remove save cookie from
39.41 */
39.42 SimpleES (DataObject obj, MultiDataObject.Entry entry, CookieSet set) {
39.43 - super(obj, new Environment(obj, entry));
39.44 + this(obj, entry, set, null);
39.45 + }
39.46 +
39.47 + SimpleES(DataObject obj, Entry entry, CookieSet set, Callable<Pane> paneFactory) {
39.48 + super(obj, obj.getLookup(), new Environment(obj, entry));
39.49 this.set = set;
39.50 + this.factory = paneFactory;
39.51 }
39.52 +
39.53 + @Override
39.54 + protected boolean asynchronousOpen() {
39.55 + return true;
39.56 + }
39.57 +
39.58 + @Override
39.59 + protected Pane createPane() {
39.60 + if (factory != null) {
39.61 + try {
39.62 + return factory.call();
39.63 + } catch (Exception ex) {
39.64 + throw new IllegalStateException("Cannot create factory for " + getDataObject(), ex);
39.65 + }
39.66 + }
39.67 + return super.createPane();
39.68 + }
39.69 +
39.70 +
39.71
39.72 /**
39.73 * Overrides superclass method. Adds adding of save cookie if the document has been marked modified.
40.1 --- a/openide.loaders/test/unit/src/org/openide/text/SimpleDESTest.java Wed May 25 16:24:45 2011 +0200
40.2 +++ b/openide.loaders/test/unit/src/org/openide/text/SimpleDESTest.java Wed May 25 16:50:33 2011 +0200
40.3 @@ -44,6 +44,7 @@
40.4
40.5 package org.openide.text;
40.6
40.7 +import java.awt.EventQueue;
40.8 import java.io.PrintStream;
40.9 import java.util.logging.Level;
40.10 import org.netbeans.junit.*;
40.11 @@ -138,6 +139,7 @@
40.12
40.13 OpenCookie open = obj.getCookie(OpenCookie.class);
40.14 open.open ();
40.15 + waitAWT();
40.16
40.17 javax.swing.text.Document d = c.getDocument();
40.18 assertNotNull (d);
40.19 @@ -150,6 +152,14 @@
40.20 );
40.21 }
40.22
40.23 + private void waitAWT() throws Exception {
40.24 + EventQueue.invokeAndWait(new Runnable() {
40.25 + @Override
40.26 + public void run() {
40.27 + }
40.28 + });
40.29 + }
40.30 +
40.31 public void testItIsPossibleToMaskEditCookie () throws Exception {
40.32 doCookieCheck (false);
40.33 }
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
41.2 +++ b/openide.loaders/test/unit/src/org/openide/text/SimpleFactoryTest.java Wed May 25 16:50:33 2011 +0200
41.3 @@ -0,0 +1,236 @@
41.4 +/*
41.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
41.6 + *
41.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
41.8 + *
41.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
41.10 + * Other names may be trademarks of their respective owners.
41.11 + *
41.12 + * The contents of this file are subject to the terms of either the GNU
41.13 + * General Public License Version 2 only ("GPL") or the Common
41.14 + * Development and Distribution License("CDDL") (collectively, the
41.15 + * "License"). You may not use this file except in compliance with the
41.16 + * License. You can obtain a copy of the License at
41.17 + * http://www.netbeans.org/cddl-gplv2.html
41.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
41.19 + * specific language governing permissions and limitations under the
41.20 + * License. When distributing the software, include this License Header
41.21 + * Notice in each file and include the License file at
41.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
41.23 + * particular file as subject to the "Classpath" exception as provided
41.24 + * by Oracle in the GPL Version 2 section of the License file that
41.25 + * accompanied this code. If applicable, add the following below the
41.26 + * License Header, with the fields enclosed by brackets [] replaced by
41.27 + * your own identifying information:
41.28 + * "Portions Copyrighted [year] [name of copyright owner]"
41.29 + *
41.30 + * Contributor(s):
41.31 + *
41.32 + * The Original Software is NetBeans. The Initial Developer of the Original
41.33 + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
41.34 + * Microsystems, Inc. All Rights Reserved.
41.35 + *
41.36 + * If you wish your version of this file to be governed by only the CDDL
41.37 + * or only the GPL Version 2, indicate your decision by adding
41.38 + * "[Contributor] elects to include this software in this distribution
41.39 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
41.40 + * single choice of license, a recipient has the option to distribute
41.41 + * your version of this file under either the CDDL, the GPL Version 2 or
41.42 + * to extend the choice of license to its licensees as provided above.
41.43 + * However, if you add GPL Version 2 code and therefore, elected the GPL
41.44 + * Version 2 license, then the option applies only if the new code is
41.45 + * made subject to such option by the copyright holder.
41.46 + */
41.47 +
41.48 +package org.openide.text;
41.49 +
41.50 +import java.awt.Container;
41.51 +import java.awt.EventQueue;
41.52 +import java.io.IOException;
41.53 +import java.util.Enumeration;
41.54 +import java.util.concurrent.Callable;
41.55 +import java.util.logging.Level;
41.56 +import javax.swing.JEditorPane;
41.57 +import org.netbeans.api.actions.Openable;
41.58 +import org.netbeans.api.actions.Savable;
41.59 +import org.netbeans.junit.*;
41.60 +import org.openide.cookies.EditorCookie;
41.61 +import org.openide.filesystems.*;
41.62 +import org.openide.loaders.DataLoader;
41.63 +import org.openide.loaders.DataObject;
41.64 +import org.openide.loaders.DataObjectExistsException;
41.65 +import org.openide.loaders.MultiDataObject;
41.66 +import org.openide.nodes.CookieSet;
41.67 +import org.openide.nodes.Node;
41.68 +import org.openide.text.CloneableEditorSupport.Pane;
41.69 +import org.openide.util.Lookup;
41.70 +
41.71 +/** Check behavior of
41.72 + * {@link DataEditorSupport#create(org.openide.loaders.DataObject, org.openide.loaders.MultiDataObject.Entry, org.openide.nodes.CookieSet, java.util.concurrent.Callable)}
41.73 + * factory method.
41.74 + *
41.75 + * @author Jaroslav Tulach
41.76 + */
41.77 +public final class SimpleFactoryTest extends NbTestCase {
41.78 + static {
41.79 + System.setProperty("org.openide.windows.DummyWindowManager.VISIBLE", "false");
41.80 + }
41.81 + private FileSystem lfs;
41.82 + private DataObject obj;
41.83 +
41.84 + public SimpleFactoryTest(String name) {
41.85 + super(name);
41.86 + }
41.87 +
41.88 + @Override
41.89 + protected Level logLevel() {
41.90 + return Level.FINE;
41.91 + }
41.92 +
41.93 + @Override
41.94 + protected boolean runInEQ() {
41.95 + return false;
41.96 + }
41.97 +
41.98 + @Override
41.99 + protected void setUp() throws java.lang.Exception {
41.100 + clearWorkDir ();
41.101 +
41.102 + System.setProperty("org.openide.util.Lookup", "org.openide.text.SimpleFactoryTest$Lkp");
41.103 + super.setUp();
41.104 +
41.105 + LocalFileSystem l = new LocalFileSystem ();
41.106 + l.setRootDirectory (getWorkDir ());
41.107 + lfs = l;
41.108 +
41.109 + FileObject fo = FileUtil.createData (lfs.getRoot (), "AA/" + getName () + ".test");
41.110 + assertNotNull("file not found", fo);
41.111 + obj = DataObject.find(fo);
41.112 +
41.113 + assertEquals ("The right class", obj.getClass (), SO.class);
41.114 + }
41.115 +
41.116 + public void testOurNodeSubclassCreated() throws Exception {
41.117 + final EditorCookie ec = obj.getLookup().lookup(EditorCookie.class);
41.118 + assertNotNull("Editor", ec);
41.119 + Openable open = obj.getLookup().lookup(Openable.class);
41.120 + assertNotNull("Open", open);
41.121 + open.open();
41.122 +
41.123 + class GEP implements Runnable {
41.124 + JEditorPane[] arr;
41.125 +
41.126 + @Override
41.127 + public void run() {
41.128 + arr = ec.getOpenedPanes();
41.129 + }
41.130 + }
41.131 + GEP gep = new GEP();
41.132 + EventQueue.invokeAndWait(gep);
41.133 +
41.134 + assertEquals("One", 1, gep.arr.length);
41.135 +
41.136 + MyCE mice = null;
41.137 + Container c = gep.arr[0];
41.138 + for (;;) {
41.139 + if (c instanceof MyCE) {
41.140 + // OK
41.141 + mice = (MyCE)c;
41.142 + break;
41.143 + }
41.144 + if (c instanceof CloneableEditor) {
41.145 + fail("Wrong CloneableEditor: " + c);
41.146 + }
41.147 + if (c == null) {
41.148 + fail("No good parent!");
41.149 + }
41.150 + c = c.getParent();
41.151 + }
41.152 +
41.153 + assertNotNull("MyCE found", mice);
41.154 + assertNull("No integers", mice.getLookup().lookup(Integer.class));
41.155 + ((SO)obj).addInteger();
41.156 + assertEquals("One integer in object", Integer.valueOf(10), obj.getLookup().lookup(Integer.class));
41.157 + assertEquals("One integer", Integer.valueOf(10), mice.getLookup().lookup(Integer.class));
41.158 +
41.159 + Savable sav = obj.getLookup().lookup(Savable.class);
41.160 + assertNull("No savable yet", sav);
41.161 +
41.162 + ec.getDocument().insertString(0, "Ahoj!", null);
41.163 +
41.164 + sav = obj.getLookup().lookup(Savable.class);
41.165 + assertNotNull("Now modified", sav);
41.166 +
41.167 + assertEquals(obj.getPrimaryFile().getNameExt(), sav.toString());
41.168 + }
41.169 +
41.170 + //
41.171 + // Our fake lookup
41.172 + //
41.173 + public static final class Lkp extends org.openide.util.lookup.AbstractLookup {
41.174 + public Lkp () {
41.175 + this (new org.openide.util.lookup.InstanceContent ());
41.176 + }
41.177 +
41.178 + private Lkp (org.openide.util.lookup.InstanceContent ic) {
41.179 + super (ic);
41.180 + ic.add (new DLP ());
41.181 + }
41.182 + }
41.183 +
41.184 + private static final class SL extends org.openide.loaders.UniFileLoader {
41.185 + public SL () {
41.186 + super (SO.class.getName ());
41.187 + getExtensions().addExtension("test");
41.188 + }
41.189 + @Override
41.190 + protected MultiDataObject createMultiObject(FileObject primaryFile) throws DataObjectExistsException, IOException {
41.191 + return new SO (primaryFile);
41.192 + }
41.193 + } // end of SL
41.194 +
41.195 + private static final class SO extends org.openide.loaders.MultiDataObject
41.196 + implements Callable<CloneableEditorSupport.Pane> {
41.197 + private CloneableEditorSupport support = DataEditorSupport.create(this, getPrimaryEntry(), getCookieSet (), this);
41.198 +
41.199 +
41.200 + public SO (FileObject fo) throws org.openide.loaders.DataObjectExistsException {
41.201 + super (fo, SL.getLoader(SL.class));
41.202 + getCookieSet ().add((Node.Cookie)support);
41.203 + }
41.204 +
41.205 + @Override
41.206 + public Lookup getLookup() {
41.207 + return getCookieSet().getLookup();
41.208 + }
41.209 +
41.210 + @Override
41.211 + public Pane call() throws Exception {
41.212 + return new MyCE(support);
41.213 + }
41.214 +
41.215 + public void addInteger() {
41.216 + getCookieSet().assign(Integer.class, 10);
41.217 + }
41.218 + } // end of SO
41.219 +
41.220 + private static final class MyCE extends CloneableEditor {
41.221 + private MyCE(CloneableEditorSupport support) {
41.222 + super(support);
41.223 + this.associateLookup(support.getLookup());
41.224 + }
41.225 + }
41.226 +
41.227 + private static final class DLP extends org.openide.loaders.DataLoaderPool {
41.228 +
41.229 + @Override
41.230 + protected Enumeration<? extends DataLoader> loaders() {
41.231 + return java.util.Collections.enumeration(
41.232 + java.util.Collections.singleton(
41.233 + SL.getLoader (SL.class)
41.234 + )
41.235 + );
41.236 + }
41.237 +
41.238 + } // end of DataLoaderPool
41.239 +}
42.1 --- a/openide.text/apichanges.xml Wed May 25 16:24:45 2011 +0200
42.2 +++ b/openide.text/apichanges.xml Wed May 25 16:50:33 2011 +0200
42.3 @@ -49,6 +49,63 @@
42.4 <apidef name="text">Text API</apidef>
42.5 </apidefs>
42.6 <changes>
42.7 + <change id="CE.closeLast.boolean">
42.8 + <api name="text"/>
42.9 + <summary>CloneableEditor.closeLast</summary>
42.10 + <version major="6" minor="37"/>
42.11 + <date day="7" month="4" year="2011"/>
42.12 + <author login="jtulach"/>
42.13 + <compatibility addition="yes" binary="compatible" deletion="no"
42.14 + deprecation="yes" modification="no" semantic="compatible"
42.15 + />
42.16 + <description>
42.17 + <p>
42.18 + <code>CloneableEditor</code> has a new utility method
42.19 + <code>closeLast</code>.
42.20 + </p>
42.21 + </description>
42.22 + <class package="org.openide.text" name="CloneableEditor"/>
42.23 + <issue number="196810"/>
42.24 + </change>
42.25 + <change id="CE.associateLookup">
42.26 + <api name="text"/>
42.27 + <summary>CloneableEditor(associateLookup)</summary>
42.28 + <version major="6" minor="37"/>
42.29 + <date day="7" month="4" year="2011"/>
42.30 + <author login="jtulach"/>
42.31 + <compatibility addition="yes" binary="compatible" deletion="no"
42.32 + deprecation="yes" modification="no" semantic="compatible"
42.33 + />
42.34 + <description>
42.35 + <p>
42.36 + <code>CloneableEditor</code> offers new constructor
42.37 + that will reuse the lookup provided by its
42.38 + <a href="@TOP@/org/openide/text/CloneableEditorSupport.html">CloneableEditorSupport</a>.
42.39 + </p>
42.40 + </description>
42.41 + <class package="org.openide.text" name="CloneableEditor"/>
42.42 + <issue number="196810"/>
42.43 + </change>
42.44 + <change id="initializeBySupport">
42.45 + <api name="text"/>
42.46 + <summary>CloneableEditor.initializeBySupport</summary>
42.47 + <version major="6" minor="37"/>
42.48 + <date day="7" month="4" year="2011"/>
42.49 + <author login="jtulach"/>
42.50 + <compatibility addition="yes" binary="compatible" deletion="no"
42.51 + deprecation="yes" modification="no" semantic="compatible"
42.52 + />
42.53 + <description>
42.54 + <p>
42.55 + Subclasses of <code>CloneableEditor</code> can manually request own
42.56 + initialization by calling its
42.57 + <a href="@TOP@/org/openide/text/CloneableEditor.html#initializeBySupport()">initializeBySupport</a>
42.58 + method.
42.59 + </p>
42.60 + </description>
42.61 + <class package="org.openide.text" name="CloneableEditor"/>
42.62 + <issue number="196810"/>
42.63 + </change>
42.64 <change id="NbDocument-Annotatable">
42.65 <api name="text"/>
42.66 <summary>NbDocument.Annotatable threading changes</summary>
43.1 --- a/openide.text/manifest.mf Wed May 25 16:24:45 2011 +0200
43.2 +++ b/openide.text/manifest.mf Wed May 25 16:50:33 2011 +0200
43.3 @@ -1,7 +1,7 @@
43.4 Manifest-Version: 1.0
43.5 OpenIDE-Module: org.openide.text
43.6 OpenIDE-Module-Install: org/netbeans/modules/openide/text/Installer.class
43.7 -OpenIDE-Module-Specification-Version: 6.38
43.8 +OpenIDE-Module-Specification-Version: 6.39
43.9 OpenIDE-Module-Localizing-Bundle: org/openide/text/Bundle.properties
43.10 AutoUpdate-Essential-Module: true
43.11
44.1 --- a/openide.text/src/org/openide/text/CloneableEditor.java Wed May 25 16:24:45 2011 +0200
44.2 +++ b/openide.text/src/org/openide/text/CloneableEditor.java Wed May 25 16:50:33 2011 +0200
44.3 @@ -143,12 +143,27 @@
44.4 * @param support support that holds the document and operations above it
44.5 */
44.6 public CloneableEditor(CloneableEditorSupport support) {
44.7 + this(support, false);
44.8 + }
44.9 +
44.10 + /** Creates new editor component associated with
44.11 + * support object (possibly also with its
44.12 + * {@link CloneableEditorSupport#CloneableEditorSupport(org.openide.text.CloneableEditorSupport.Env, org.openide.util.Lookup) lookup}.
44.13 + *
44.14 + * @param support support that holds the document and operations above it
44.15 + * @param associateLookup true, if {@link #getLookup()} should return the lookup
44.16 + * associated with {@link CloneableEditorSupport}.
44.17 + */
44.18 + public CloneableEditor(CloneableEditorSupport support, boolean associateLookup) {
44.19 super();
44.20 this.support = support;
44.21
44.22 updateName();
44.23 _setCloseOperation();
44.24 setMinimumSize(new Dimension(10, 10));
44.25 + if (associateLookup) {
44.26 + associateLookup(support.getLookup());
44.27 + }
44.28 }
44.29 @SuppressWarnings("deprecation")
44.30 private void _setCloseOperation() {
44.31 @@ -241,6 +256,18 @@
44.32 }
44.33 return !Boolean.TRUE.equals(getClientProperty("oldInitialize")); // NOI18N
44.34 }
44.35 +
44.36 + /** Asks the associated {@link CloneableEditorSupport} to initialize
44.37 + * this editor via its {@link CloneableEditorSupport#initializeCloneableEditor(org.openide.text.CloneableEditor)}
44.38 + * method. By default called from the support on various occasions including
44.39 + * shortly after creation and
44.40 + * after the {@link CloneableEditor} has been deserialized.
44.41 + *
44.42 + * @since 6.37
44.43 + */
44.44 + protected final void initializeBySupport() {
44.45 + cloneableEditorSupport().initializeCloneableEditor(this);
44.46 + }
44.47
44.48 class AWTQuery implements Runnable {
44.49 private UserQuestionException ex;
44.50 @@ -868,14 +895,27 @@
44.51 }
44.52 }
44.53
44.54 - /** When closing last view, also close the document.
44.55 + /** When closing last view, also close the document.
44.56 + * Calls {@link #closeLast(boolean) closeLast(true)}.
44.57 * @return <code>true</code> if close succeeded
44.58 */
44.59 @Override
44.60 protected boolean closeLast() {
44.61 - if (!support.canClose()) {
44.62 - // if we cannot close the last window
44.63 - return false;
44.64 + return closeLast(true);
44.65 + }
44.66 +
44.67 + /** Utility method to close the document.
44.68 + *
44.69 + * @param ask verify and ask the user whether a document can be closed or not?
44.70 + * @return true if the document was successfully closed
44.71 + * @since 6.37
44.72 + */
44.73 + protected final boolean closeLast(boolean ask) {
44.74 + if (ask) {
44.75 + if (!support.canClose()) {
44.76 + // if we cannot close the last window
44.77 + return false;
44.78 + }
44.79 }
44.80
44.81 // close everything and do not ask
44.82 @@ -1111,6 +1151,7 @@
44.83 }
44.84
44.85 out.writeObject(new Integer(pos));
44.86 + out.writeBoolean(getLookup() == support.getLookup());
44.87 }
44.88
44.89 @Override
44.90 @@ -1138,6 +1179,12 @@
44.91
44.92 updateName();
44.93 isComponentOpened = true;
44.94 + if (in.available() > 0) {
44.95 + boolean associate = in.readBoolean();
44.96 + if (associate && support != null) {
44.97 + associateLookup(support.getLookup());
44.98 + }
44.99 + }
44.100 }
44.101
44.102 /**
44.103 @@ -1167,7 +1214,7 @@
44.104 if (discard()) {
44.105 throw new java.io.InvalidObjectException("Deserialized component is invalid: " + this); // NOI18N
44.106 } else {
44.107 - support.initializeCloneableEditor(this);
44.108 + initializeBySupport();
44.109
44.110 return this;
44.111 }
45.1 --- a/openide.text/src/org/openide/text/CloneableEditorSupport.java Wed May 25 16:24:45 2011 +0200
45.2 +++ b/openide.text/src/org/openide/text/CloneableEditorSupport.java Wed May 25 16:50:33 2011 +0200
45.3 @@ -1324,7 +1324,8 @@
45.4
45.5 /** Creates and initializes
45.6 * new <code>CloneableEditor</code> component.
45.7 - * Typically do not override this method.
45.8 + * Typically do not override this method (unless you are dealing with
45.9 + * <a href="@org-netbeans-core-multiview@/overview-summary.html">multiviews</a>).
45.10 * For creating your own <code>CloneableEditor</code> type component
45.11 * override {@link #createCloneableEditor} method.
45.12 *
46.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
46.2 +++ b/openide.text/test/unit/src/org/openide/text/CloneableEditorAssociateTest.java Wed May 25 16:50:33 2011 +0200
46.3 @@ -0,0 +1,245 @@
46.4 +/*
46.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
46.6 + *
46.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
46.8 + *
46.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
46.10 + * Other names may be trademarks of their respective owners.
46.11 + *
46.12 + * The contents of this file are subject to the terms of either the GNU
46.13 + * General Public License Version 2 only ("GPL") or the Common
46.14 + * Development and Distribution License("CDDL") (collectively, the
46.15 + * "License"). You may not use this file except in compliance with the
46.16 + * License. You can obtain a copy of the License at
46.17 + * http://www.netbeans.org/cddl-gplv2.html
46.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
46.19 + * specific language governing permissions and limitations under the
46.20 + * License. When distributing the software, include this License Header
46.21 + * Notice in each file and include the License file at
46.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
46.23 + * particular file as subject to the "Classpath" exception as provided
46.24 + * by Oracle in the GPL Version 2 section of the License file that
46.25 + * accompanied this code. If applicable, add the following below the
46.26 + * License Header, with the fields enclosed by brackets [] replaced by
46.27 + * your own identifying information:
46.28 + * "Portions Copyrighted [year] [name of copyright owner]"
46.29 + *
46.30 + * Contributor(s):
46.31 + *
46.32 + * The Original Software is NetBeans. The Initial Developer of the Original
46.33 + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
46.34 + * Microsystems, Inc. All Rights Reserved.
46.35 + *
46.36 + * If you wish your version of this file to be governed by only the CDDL
46.37 + * or only the GPL Version 2, indicate your decision by adding
46.38 + * "[Contributor] elects to include this software in this distribution
46.39 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
46.40 + * single choice of license, a recipient has the option to distribute
46.41 + * your version of this file under either the CDDL, the GPL Version 2 or
46.42 + * to extend the choice of license to its licensees as provided above.
46.43 + * However, if you add GPL Version 2 code and therefore, elected the GPL
46.44 + * Version 2 license, then the option applies only if the new code is
46.45 + * made subject to such option by the copyright holder.
46.46 + */
46.47 +
46.48 +package org.openide.text;
46.49 +
46.50 +
46.51 +import java.beans.*;
46.52 +import java.io.*;
46.53 +import java.util.*;
46.54 +import javax.swing.JEditorPane;
46.55 +import org.netbeans.junit.NbTestCase;
46.56 +import org.openide.util.Exceptions;
46.57 +import org.openide.util.Lookup;
46.58 +import org.openide.util.io.NbMarshalledObject;
46.59 +import org.openide.util.lookup.AbstractLookup;
46.60 +import org.openide.util.lookup.InstanceContent;
46.61 +import org.openide.windows.*;
46.62 +
46.63 +public class CloneableEditorAssociateTest extends NbTestCase
46.64 +implements CloneableEditorSupport.Env {
46.65 + static {
46.66 + System.setProperty("org.openide.windows.DummyWindowManager.VISIBLE", "false");
46.67 + }
46.68 + private transient InstanceContent ic;
46.69 + /** the support to work with */
46.70 + private transient CES support;
46.71 +
46.72 + // Env variables
46.73 + private transient String content = "";
46.74 + private transient boolean valid = true;
46.75 + private transient boolean modified = false;
46.76 + /** if not null contains message why this document cannot be modified */
46.77 + private transient String cannotBeModified;
46.78 + private transient Date date = new Date ();
46.79 + private transient List/*<PropertyChangeListener>*/ propL = new ArrayList ();
46.80 + private transient VetoableChangeListener vetoL;
46.81 +
46.82 + private static CloneableEditorAssociateTest RUNNING;
46.83 +
46.84 + public CloneableEditorAssociateTest(String s) {
46.85 + super(s);
46.86 + }
46.87 +
46.88 + @Override
46.89 + protected void setUp () {
46.90 + ic = new InstanceContent();
46.91 + support = new CES (this, new AbstractLookup(ic));
46.92 + RUNNING = this;
46.93 + }
46.94 +
46.95 + @Override
46.96 + protected boolean runInEQ() {
46.97 + return true;
46.98 + }
46.99 +
46.100 + private Object writeReplace () {
46.101 + return new Replace ();
46.102 + }
46.103 +
46.104 + public void testGetOpenedPanesWorksAfterDeserializationIssue39236 () throws Exception {
46.105 + support.open ();
46.106 +
46.107 + CloneableEditor ed = (CloneableEditor)support.getRef ().getAnyComponent ();
46.108 + ic.add(20);
46.109 + assertEquals("twenty", Integer.valueOf(20), ed.getLookup().lookup(Integer.class));
46.110 + ic.remove(20);
46.111 + assertNull("no twenty", ed.getLookup().lookup(Integer.class));
46.112 +
46.113 + JEditorPane[] panes = support.getOpenedPanes ();
46.114 + assertNotNull (panes);
46.115 + assertEquals ("One is there", 1, panes.length);
46.116 +
46.117 + NbMarshalledObject obj = new NbMarshalledObject (ed);
46.118 + ed.close ();
46.119 +
46.120 + panes = support.getOpenedPanes ();
46.121 + assertNull ("No panes anymore", panes);
46.122 +
46.123 + ed = (CloneableEditor)obj.get ();
46.124 +
46.125 + panes = support.getOpenedPanes ();
46.126 + assertNotNull ("One again", panes);
46.127 + assertEquals ("One is there again", 1, panes.length);
46.128 +
46.129 + ic.add(10);
46.130 + assertEquals("ten", Integer.valueOf(10), ed.getLookup().lookup(Integer.class));
46.131 + }
46.132 +
46.133 + //
46.134 + // Implementation of the CloneableEditorSupport.Env
46.135 + //
46.136 +
46.137 + public synchronized void addPropertyChangeListener(PropertyChangeListener l) {
46.138 + propL.add (l);
46.139 + }
46.140 + public synchronized void removePropertyChangeListener(PropertyChangeListener l) {
46.141 + propL.remove (l);
46.142 + }
46.143 +
46.144 + public synchronized void addVetoableChangeListener(VetoableChangeListener l) {
46.145 + assertNull ("This is the first veto listener", vetoL);
46.146 + vetoL = l;
46.147 + }
46.148 + public void removeVetoableChangeListener(VetoableChangeListener l) {
46.149 + assertEquals ("Removing the right veto one", vetoL, l);
46.150 + vetoL = null;
46.151 + }
46.152 +
46.153 + public CloneableOpenSupport findCloneableOpenSupport() {
46.154 + return RUNNING.support;
46.155 + }
46.156 +
46.157 + public String getMimeType() {
46.158 + return "text/plain";
46.159 + }
46.160 +
46.161 + public Date getTime() {
46.162 + return date;
46.163 + }
46.164 +
46.165 + public InputStream inputStream() throws IOException {
46.166 + return new ByteArrayInputStream (content.getBytes ());
46.167 + }
46.168 + public OutputStream outputStream() throws IOException {
46.169 + class ContentStream extends ByteArrayOutputStream {
46.170 + public void close () throws IOException {
46.171 + super.close ();
46.172 + content = new String (toByteArray ());
46.173 + }
46.174 + }
46.175 +
46.176 + return new ContentStream ();
46.177 + }
46.178 +
46.179 + public boolean isValid() {
46.180 + return valid;
46.181 + }
46.182 +
46.183 + public boolean isModified() {
46.184 + return modified;
46.185 + }
46.186 +
46.187 + public void markModified() throws IOException {
46.188 + if (cannotBeModified != null) {
46.189 + final String notify = cannotBeModified;
46.190 + IOException e = new IOException () {
46.191 + @Override
46.192 + public String getLocalizedMessage () {
46.193 + return notify;
46.194 + }
46.195 + };
46.196 + Exceptions.attachLocalizedMessage(e, cannotBeModified);
46.197 + throw e;
46.198 + }
46.199 +
46.200 + modified = true;
46.201 + }
46.202 +
46.203 + public void unmarkModified() {
46.204 + modified = false;
46.205 + }
46.206 +
46.207 + /** Implementation of the CES */
46.208 + private static final class CES extends CloneableEditorSupport {
46.209 + public CES (Env env, Lookup l) {
46.210 + super (env, l);
46.211 + }
46.212 +
46.213 + public CloneableTopComponent.Ref getRef () {
46.214 + return allEditors;
46.215 + }
46.216 +
46.217 + protected String messageName() {
46.218 + return "Name";
46.219 + }
46.220 +
46.221 + protected String messageOpened() {
46.222 + return "Opened";
46.223 + }
46.224 +
46.225 + protected String messageOpening() {
46.226 + return "Opening";
46.227 + }
46.228 +
46.229 + protected String messageSave() {
46.230 + return "Save";
46.231 + }
46.232 +
46.233 + protected String messageToolTip() {
46.234 + return "ToolTip";
46.235 + }
46.236 +
46.237 + @Override
46.238 + protected CloneableEditor createCloneableEditor() {
46.239 + return new CloneableEditor(this, true);
46.240 + }
46.241 + }
46.242 +
46.243 + private static final class Replace implements Serializable {
46.244 + public Object readResolve () {
46.245 + return RUNNING;
46.246 + }
46.247 + }
46.248 +}
47.1 --- a/openide.text/test/unit/src/org/openide/text/CloneableEditorTest.java Wed May 25 16:24:45 2011 +0200
47.2 +++ b/openide.text/test/unit/src/org/openide/text/CloneableEditorTest.java Wed May 25 16:50:33 2011 +0200
47.3 @@ -50,6 +50,7 @@
47.4 import java.util.*;
47.5 import javax.swing.JEditorPane;
47.6 import org.netbeans.junit.NbTestCase;
47.7 +import org.openide.nodes.Node;
47.8 import org.openide.util.Exceptions;
47.9 import org.openide.util.Lookup;
47.10 import org.openide.util.io.NbMarshalledObject;
47.11 @@ -116,6 +117,12 @@
47.12 assertEquals ("One is there again", 1, panes.length);
47.13 }
47.14
47.15 + public void testInitializeBySupport() {
47.16 + CloneableEditor ce = new CloneableEditor(support);
47.17 + ce.initializeBySupport();
47.18 + assertEquals("Nodes changed", Node.EMPTY, ce.getActivatedNodes()[0]);
47.19 + }
47.20 +
47.21 public void testEditorPaneActionMapIsParentOfCloneableEditorActionMap() {
47.22 support.open();
47.23
47.24 @@ -228,6 +235,12 @@
47.25 protected String messageToolTip() {
47.26 return "ToolTip";
47.27 }
47.28 +
47.29 + @Override
47.30 + protected void initializeCloneableEditor(CloneableEditor editor) {
47.31 + editor.setActivatedNodes(new Node[] { Node.EMPTY });
47.32 + }
47.33 +
47.34
47.35 }
47.36