| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| |
| package org.netbeans.modules.i18n.wizard; |
| |
| |
| import java.awt.CardLayout; |
| import java.awt.Component; |
| import java.awt.Container; |
| import java.awt.EventQueue; |
| import java.awt.event.ActionEvent; |
| import java.awt.event.ActionListener; |
| import java.beans.BeanInfo; |
| import java.io.IOException; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.Map; |
| import javax.swing.event.ListSelectionEvent; |
| import javax.swing.event.ListSelectionListener; |
| import javax.swing.ImageIcon; |
| import javax.swing.JButton; |
| import javax.swing.JLabel; |
| import javax.swing.JPanel; |
| import javax.swing.JScrollPane; |
| import javax.swing.JTable; |
| import javax.swing.JTextArea; |
| import javax.swing.table.AbstractTableModel; |
| import javax.swing.table.DefaultTableCellRenderer; |
| import org.netbeans.api.java.classpath.ClassPath; |
| |
| import org.netbeans.modules.i18n.FactoryRegistry; |
| import org.netbeans.modules.i18n.HardCodedString; |
| import org.netbeans.modules.i18n.I18nString; |
| import org.netbeans.modules.i18n.I18nSupport; |
| import org.netbeans.modules.i18n.I18nUtil; |
| import org.netbeans.modules.i18n.ResourceHolder; |
| import org.netbeans.modules.i18n.SelectorUtils; |
| |
| import org.openide.WizardValidationException; |
| import org.openide.loaders.DataObject; |
| import org.openide.util.HelpCtx; |
| import org.openide.util.NbBundle; |
| import org.openide.filesystems.FileObject; |
| import org.openide.ErrorManager; |
| import org.openide.WizardDescriptor; |
| import org.openide.WizardDescriptor.AsynchronousValidatingPanel; |
| import org.openide.awt.Mnemonics; |
| |
| |
| /** |
| * Second panel of I18N Wizard. |
| * |
| * @author Peter Zavadsky |
| * @author Marian Petras |
| * @see Panel |
| */ |
| final class ResourceWizardPanel extends JPanel { |
| |
| /** Local copy of i18n wizard data. */ |
| private final Map<DataObject,SourceData> sourceMap = Util.createWizardSourceMap(); |
| |
| /** Table model for resourcesTable. */ |
| private final ResourceTableModel tableModel = new ResourceTableModel(); |
| |
| /** This component panel wizard descriptor. |
| * @see org.openide.WizardDescriptor.Panel |
| * @see Panel */ |
| private final Panel descPanel; |
| |
| private final boolean testMode; |
| |
| /** Creates new form SourceChooserPanel. */ |
| private ResourceWizardPanel(Panel descPanel, boolean testMode) { |
| this.descPanel = descPanel; |
| this.testMode = testMode; |
| |
| initComponents(); |
| |
| initTable(); |
| |
| initAccesibility(); |
| |
| if(testMode) { |
| HelpCtx.setHelpIDString(this, Util.HELP_ID_SELECTTESTRESOURCE); |
| } else { |
| HelpCtx.setHelpIDString(this, Util.HELP_ID_SELECTRESOURCE); |
| } |
| } |
| |
| |
| /** Getter for <code>resources</code> property. */ |
| public Map<DataObject,SourceData> getSourceMap() { |
| return sourceMap; |
| } |
| |
| /** Setter for <code>resources</code> property. */ |
| public void setSourceMap(Map<DataObject,SourceData> sourceMap) { |
| this.sourceMap.clear(); |
| this.sourceMap.putAll(sourceMap); |
| |
| tableModel.fireTableDataChanged(); |
| |
| descPanel.fireStateChanged(); |
| } |
| |
| private String getPanelDescription() { |
| if (testMode == false) { |
| return Util.getString("MSG_ResourcePanel_desc"); |
| } else { |
| return Util.getString("MSG_ResourcePanel_test_desc"); |
| } |
| } |
| |
| /** Inits table component. */ |
| private void initTable() { |
| resourcesTable.setDefaultRenderer(DataObject.class, new DefaultTableCellRenderer() { |
| @Override |
| public Component getTableCellRendererComponent(JTable table, Object value, |
| boolean isSelected, boolean hasFocus, int row, int column) { |
| |
| JLabel label = (JLabel)super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); |
| DataObject dataObject = (DataObject)value; |
| |
| if(dataObject != null) { |
| String name = "N/A"; |
| if (column == 0) { |
| // name for the first column, from sources |
| ClassPath cp = ClassPath.getClassPath(dataObject.getPrimaryFile(), ClassPath.SOURCE ); |
| name = cp.getResourceName( dataObject.getPrimaryFile(), '.', false ); |
| } else { |
| // name for resource bundle, from execution, |
| // but the reference file must be the |
| // corresponding source |
| DataObject dob = (DataObject)tableModel.getValueAt(row, 0); |
| name = Util.getResourceName(dob.getPrimaryFile(), dataObject.getPrimaryFile(), '.', false); |
| } |
| |
| label.setText(name); // NOI18N |
| label.setIcon(new ImageIcon(dataObject.getNodeDelegate().getIcon(BeanInfo.ICON_COLOR_16x16))); |
| } else { |
| label.setText(""); // NOI18N |
| label.setIcon(null); |
| } |
| |
| return label; |
| } |
| }); |
| |
| Component cellSample = new DefaultTableCellRenderer() |
| .getTableCellRendererComponent( |
| resourcesTable, //table |
| "N/A", //value //NOI18N |
| false, //isSelected |
| false, //hasFocus |
| 0, 0); //row, column |
| int cellHeight = cellSample.getPreferredSize().height; |
| int rowHeight = cellHeight + resourcesTable.getRowMargin(); |
| resourcesTable.setRowHeight(Math.max(16, rowHeight)); |
| |
| resourcesTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() { |
| public void valueChanged(ListSelectionEvent evt) { |
| addButton.setEnabled(!resourcesTable.getSelectionModel().isSelectionEmpty()); |
| } |
| }); |
| |
| addButton.setEnabled(!resourcesTable.getSelectionModel().isSelectionEmpty()); |
| } |
| |
| |
| private void initAccesibility() { |
| addButton.getAccessibleContext().setAccessibleDescription(Util.getString("ACS_CTL_SelectResource"));//NOI18N |
| addAllButton.getAccessibleContext().setAccessibleDescription(Util.getString("ACS_CTL_SelectResourceAll"));//NOI18N |
| resourcesTable.getAccessibleContext().setAccessibleDescription(Util.getString("ACSD_resourcesTable"));//NOI18N |
| resourcesTable.getAccessibleContext().setAccessibleName(Util.getString("ACSN_resourcesTable"));//NOI18N |
| } |
| |
| /** |
| * This method is called from within the constructor to initialize the form. |
| */ |
| // <editor-fold defaultstate="collapsed" desc="UI initialization code"> |
| private void initComponents() { |
| resourcesTable = new JTable(); |
| resourcesTable.setModel(tableModel); |
| |
| addAllButton = new JButton(); |
| Mnemonics.setLocalizedText( |
| addAllButton, |
| Util.getString("CTL_SelectResourceAll")); //NOI18N |
| addAllButton.addActionListener(new ActionListener() { |
| public void actionPerformed(ActionEvent evt) { |
| addAllButtonActionPerformed(evt); |
| } |
| }); |
| |
| addButton = new JButton(); |
| Mnemonics.setLocalizedText( |
| addButton, |
| Util.getString("CTL_SelectResource")); //NOI18N |
| addButton.addActionListener(new ActionListener() { |
| public void actionPerformed(ActionEvent evt) { |
| addButtonActionPerformed(evt); |
| } |
| }); |
| |
| Util.layoutSelectResourcePanel( |
| this, |
| getPanelDescription(), |
| Util.getString("LBL_SelectedResources"), //NOI18N |
| resourcesTable, |
| addAllButton, |
| addButton); |
| }// </editor-fold> |
| |
| private void addButtonActionPerformed(ActionEvent evt) { |
| DataObject resource = selectResource(); |
| |
| if (resource == null) { |
| return; |
| } |
| |
| int[] selectedRows = resourcesTable.getSelectedRows(); |
| |
| // Feed data. |
| for(int i=0; i<selectedRows.length; i++) { |
| DataObject dataObject = (DataObject) resourcesTable.getValueAt(selectedRows[i], 0); |
| |
| sourceMap.put(dataObject, new SourceData(resource)); |
| |
| tableModel.fireTableCellUpdated(selectedRows[i], 1); |
| } |
| |
| descPanel.fireStateChanged(); |
| } |
| |
| private void addAllButtonActionPerformed(ActionEvent evt) { |
| DataObject resource = selectResource(); |
| |
| if (resource == null) { |
| return; |
| } |
| |
| // Feed data. |
| for (int i = 0; i < resourcesTable.getRowCount(); i++) { |
| DataObject dataObject = (DataObject) resourcesTable.getValueAt(i, 0); |
| |
| sourceMap.put(dataObject, new SourceData(resource)); |
| |
| tableModel.fireTableCellUpdated(i, 1); |
| } |
| |
| descPanel.fireStateChanged(); |
| } |
| |
| /** Helper method. Gets user selected resource. */ |
| private DataObject selectResource() { |
| FileObject fo = null; |
| DataObject source = null; |
| for (DataObject dobj : sourceMap.keySet()) { |
| fo = dobj.getPrimaryFile(); |
| source = dobj; |
| } |
| |
| // Get i18n support for this source. |
| I18nSupport support = null; |
| try { |
| support = FactoryRegistry.getFactory(source.getClass()).create(source); |
| } catch(IOException ioe) { |
| ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ioe); |
| } |
| |
| ResourceHolder rh = support != null ? support.getResourceHolder() : null; |
| |
| DataObject template = null; |
| try { |
| template = rh != null ? rh.getTemplate(rh.getResourceClasses()[0]) : null; |
| } catch (IOException ex) { |
| ErrorManager.getDefault().notify(ex); |
| } |
| |
| return SelectorUtils.selectOrCreateBundle(fo, template, null); |
| } |
| |
| // Variables declaration |
| private JButton addAllButton; |
| private JButton addButton; |
| private JTextArea descTextArea; |
| private JScrollPane jScrollPane1; |
| private JLabel lblSelectedResources; |
| private JTable resourcesTable; |
| // End of variables declaration |
| |
| /** Table model for this class. */ |
| private class ResourceTableModel extends AbstractTableModel { |
| |
| /** Constructor. */ |
| public ResourceTableModel() { |
| } |
| |
| |
| /** Implements superclass abstract method. */ |
| public int getColumnCount() { |
| return 2; |
| } |
| |
| /** Implemenst superclass abstract method. */ |
| public int getRowCount() { |
| return sourceMap.size(); |
| } |
| |
| /** Implements superclass abstract method. */ |
| public Object getValueAt(int rowIndex, int columnIndex) { |
| |
| if (columnIndex == 0) { |
| return sourceMap.keySet().toArray()[rowIndex]; |
| } else { |
| SourceData[] values = new SourceData[0]; |
| SourceData value = sourceMap.values().toArray(values)[rowIndex]; |
| return value == null ? null : value.getResource(); |
| } |
| |
| } |
| |
| /** Overrides superclass method. |
| * @return DataObject.class */ |
| @Override |
| public Class getColumnClass(int columnIndex) { |
| return DataObject.class; |
| } |
| |
| /** Overrides superclass method. */ |
| @Override |
| public String getColumnName(int column) { |
| String msgKey = (column == 0) ? "CTL_Source" //NOI18N |
| : "CTL_Resource"; //NOI18N |
| return NbBundle.getMessage(ResourceWizardPanel.class, msgKey); |
| } |
| } // End of ResourceTableModel inner class. |
| |
| |
| /** <code>WizardDescriptor.Panel</code> used for <code>ResourceChooserPanel</code>. |
| * @see I18nWizardDescriptorPanel |
| * @see org.openide.WizardDescriptor.Panel */ |
| public static class Panel extends I18nWizardDescriptor.Panel |
| implements AsynchronousValidatingPanel<I18nWizardDescriptor.Settings> { |
| |
| private static final String CARD_GUI = "gui"; //NOI18N |
| private static final String CARD_PROGRESS = "progress"; //NOI18N |
| |
| /** Cached component. */ |
| private transient ResourceWizardPanel resourcePanel; |
| |
| /** Indicates whether this panel is used in i18n test wizard or not. */ |
| private final boolean testWizard; |
| |
| /** */ |
| private volatile ProgressWizardPanel progressPanel; |
| |
| /** Constructs Panel for i18n wizard. */ |
| public Panel() { |
| this(false); |
| } |
| |
| /** Constructs panel for i18n wizard or i18n test wizard. */ |
| public Panel(boolean testWizard) { |
| this.testWizard = testWizard; |
| } |
| |
| |
| /** Gets component to display. Implements superclass abstract method. |
| * @return this instance */ |
| protected Component createComponent() { |
| JPanel panel = new JPanel(new CardLayout()); |
| |
| // Accessibility |
| panel.getAccessibleContext().setAccessibleDescription(NbBundle.getBundle(ResourceWizardPanel.class).getString("ACS_ResourceWizardPanel")); |
| |
| panel.putClientProperty(WizardDescriptor.PROP_CONTENT_SELECTED_INDEX, Integer.valueOf(1)); |
| |
| String msgKey = testWizard ? "TXT_SelectTestResource" //NOI18N |
| : "TXT_SelectResource"; //NOI18N |
| panel.setName(NbBundle.getMessage(ResourceWizardPanel.class, msgKey)); |
| panel.setPreferredSize(I18nWizardDescriptor.PREFERRED_DIMENSION); |
| |
| panel.add(getUI(), CARD_GUI); |
| |
| return panel; |
| } |
| |
| /** Indicates if panel is valid. Overrides superclass method. */ |
| @Override |
| public boolean isValid() { |
| return !getUI().getSourceMap().containsValue(null); |
| } |
| |
| /** Reads settings at the start when the panel comes to play. Overrides superclass method. */ |
| @Override |
| public void readSettings(I18nWizardDescriptor.Settings settings) { |
| super.readSettings(settings); |
| getUI().setSourceMap(getMap()); |
| |
| Container container = (Container) getComponent(); |
| ((CardLayout) container.getLayout()).show(container, CARD_GUI); |
| } |
| |
| /** Stores settings at the end of panel show. Overrides superclass abstract method. */ |
| @Override |
| public void storeSettings(I18nWizardDescriptor.Settings settings) { |
| super.storeSettings(settings); |
| // Update sources. |
| getMap().clear(); |
| getMap().putAll(getUI().getSourceMap()); |
| } |
| |
| /** */ |
| public void prepareValidation() { |
| assert EventQueue.isDispatchThread(); |
| if (progressPanel == null) { |
| progressPanel = new ProgressWizardPanel(false); |
| } |
| |
| showProgressPanel(progressPanel); |
| |
| progressPanel.setMainText(NbBundle.getMessage(ResourceWizardPanel.class, |
| "TXT_Loading"));//NOI18N |
| progressPanel.setMainProgress(0); |
| } |
| |
| public void validate() throws WizardValidationException { |
| assert !EventQueue.isDispatchThread(); |
| |
| // Do search. |
| Map<DataObject,SourceData> sourceMap = getUI().getSourceMap(); |
| Iterator<Map.Entry<DataObject,SourceData>> sourceIterator |
| = sourceMap.entrySet().iterator(); |
| |
| // For each source perform the task. |
| final String prefixLoading |
| = NbBundle.getMessage(ResourceWizardPanel.class, |
| "TXT_Loading") //NOI18N |
| + ' '; |
| final String prefixSearchingIn |
| = NbBundle.getMessage(ResourceWizardPanel.class, |
| "TXT_SearchingIn") //NOI18N |
| + ' '; |
| |
| for (int i = 0; sourceIterator.hasNext(); i++) { |
| Map.Entry<DataObject,SourceData> entry = sourceIterator.next(); |
| DataObject source = entry.getKey(); |
| FileObject fileObj = source.getPrimaryFile(); |
| String fileName = ClassPath.getClassPath(fileObj, ClassPath.SOURCE) |
| .getResourceName(fileObj, '.', false); |
| |
| progressPanel.setMainText(prefixLoading + fileName); |
| |
| // retrieve existing sourcedata -- will provide the resource for the new instance |
| SourceData sourceData = entry.getValue(); |
| |
| // prepare new sourcedata |
| // Get i18n support for this source. |
| I18nSupport support = sourceData.getSupport(); |
| if (support == null) { |
| try { |
| support = FactoryRegistry.getFactory(source.getClass()).create(source); |
| } catch(IOException ioe) { |
| ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ioe); |
| // Remove source from settings. |
| sourceIterator.remove(); |
| continue; |
| } |
| |
| sourceData = new SourceData(sourceData.getResource(), support); |
| entry.setValue(sourceData); |
| } |
| |
| progressPanel.setMainText(prefixSearchingIn + fileName); |
| |
| HardCodedString[] foundStrings; |
| |
| if (testWizard) { |
| // Find all i18n-zied hard coded strings in the source. |
| foundStrings = support.getFinder().findAllI18nStrings(); |
| } else { |
| // Find all non-i18-ized hard coded strings in the source. |
| foundStrings = support.getFinder().findAllHardCodedStrings(); |
| } |
| |
| if (foundStrings == null) { |
| // Set empty map. |
| sourceData.setStringMap(Collections.<HardCodedString,I18nString>emptyMap()); |
| continue; |
| } |
| |
| Map<HardCodedString,I18nString> map |
| = new HashMap<HardCodedString,I18nString>(foundStrings.length); |
| |
| // Put <hard coded string, i18n-string> pairs into map. |
| for (HardCodedString hcString : foundStrings) { |
| if (testWizard && support.getResourceHolder().getValueForKey(hcString.getText()) |
| != null) { |
| continue; |
| } |
| map.put(hcString, support.getDefaultI18nString(hcString)); |
| } |
| |
| progressPanel.setMainProgress((int)((i+1)/(float)sourceMap.size() * 100)); |
| |
| sourceData.setStringMap(map); |
| } // End of outer for. |
| } |
| |
| /** Helper method. Places progress panel for monitoring search. */ |
| private void showProgressPanel(ProgressWizardPanel progressPanel) { |
| Container container = (Container) getComponent(); |
| container.add(progressPanel, CARD_PROGRESS); |
| ((CardLayout) container.getLayout()).show(container, CARD_PROGRESS); |
| } |
| |
| /** Gets help. Implements superclass abstract method. */ |
| public HelpCtx getHelp() { |
| return new HelpCtx(testWizard ? I18nUtil.HELP_ID_TESTING |
| : I18nUtil.HELP_ID_WIZARD); |
| } |
| |
| private synchronized ResourceWizardPanel getUI() { |
| if (resourcePanel == null) { |
| resourcePanel = new ResourceWizardPanel(this, testWizard); |
| } |
| return resourcePanel; |
| } |
| |
| } // End of nested Panel class. |
| |
| } |