blob: c4053c900bdb11bf05363bed159a85a5a21679db [file] [log] [blame]
/*
* 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.
}