// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.czechaddress.gui;
import java.util.ArrayList;
import java.util.List;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableModel;
import org.openstreetmap.josm.Main;
import org.openstreetmap.josm.gui.ExtendedDialog;
import org.openstreetmap.josm.plugins.czechaddress.CzechAddressPlugin;
import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.AddressElement;
import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.Database;
import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.House;
import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.Region;
import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.Street;
import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.Suburb;
import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.ViToCi;
import org.openstreetmap.josm.plugins.czechaddress.gui.databaseeditors.EditorFactory;
import org.openstreetmap.josm.plugins.czechaddress.gui.utils.HalfCookedTreeModel;
import org.openstreetmap.josm.plugins.czechaddress.gui.utils.UniversalTreeRenderer;
import org.openstreetmap.josm.plugins.czechaddress.intelligence.Capitalizator;
import org.openstreetmap.josm.plugins.czechaddress.intelligence.Reasoner;
import org.openstreetmap.josm.tools.ImageProvider;
/**
* Editing the database of {@link AddressElement}s.
*
* <p>Currently allows to display the current location + its children and
* automatic street renaming.</p>
*
* @author Radomír Černoch radomir.cernoch@gmail.com
* @author Libor Pechacek, lpechacek@gmx.com
*/
public class ManagerDialog extends ExtendedDialog {
RenameModel<Street> streetModel = new RenameModel<>();
public ManagerDialog() {
super(Main.parent, "Inspektor databáze", new String[] {}, true);
initComponents();
dbTree.setModel(new DatabaseModel());
dbTree.setCellRenderer(new UniversalTreeRenderer());
dbEditButton.setIcon(ImageProvider.get("actions", "edit.png"));
org.openstreetmap.josm.data.osm.DataSet dataSet = Main.getLayerManager().getEditDataSet();
if (dataSet != null) {
Capitalizator cap = new Capitalizator(dataSet.allPrimitives(),
CzechAddressPlugin.getLocation().getStreets());
for (Street capStreet : cap.getCapitalised()) {
assert cap.translate(capStreet).get("name") != null : capStreet;
String elemName = capStreet.getName();
String primName = cap.translate(capStreet).get("name");
if (!elemName.equals(primName)) {
streetModel.elems.add(capStreet);
streetModel.names.add(primName);
}
}
}
renameTable.setModel(streetModel);
renameTable.setDefaultRenderer(AddressElement.class,
new AddressElementRenderer());
renameTable.setDefaultRenderer(String.class,
new AddressElementRenderer());
// And finalize initializing the form.
setContent(mainPanel);
setButtonIcons(new String[] {"ok.png", "cancel.png"});
setDefaultButton(1);
setCancelButton(2);
setupDialog();
}
public int countAutomaticRenameProposals() {
return streetModel.getRowCount();
}
private static class DatabaseModel extends HalfCookedTreeModel {
@Override
public Object getRoot() {
return CzechAddressPlugin.getLocation();
}
@Override
public Object getChild(Object parent, int index) {
if (parent instanceof House)
return null;
if (parent instanceof Street)
return ((Street) parent).getHouses().get(index);
if (parent instanceof Suburb) {
Suburb suburb = (Suburb) parent;
if (index < suburb.getHouses().size())
return suburb.getHouses().get(index);
else
index -= suburb.getHouses().size();
if (index < suburb.getStreets().size())
return suburb.getStreets().get(index);
else
return null;
}
if (parent instanceof ViToCi) {
ViToCi vitoci = (ViToCi) parent;
if (index < vitoci.getHouses().size())
return vitoci.getHouses().get(index);
else
index -= vitoci.getHouses().size();
if (index < vitoci.getStreets().size())
return vitoci.getStreets().get(index);
else
index -= vitoci.getStreets().size();
if (index < vitoci.getSuburbs().size())
return vitoci.getSuburbs().get(index);
else
return null;
}
if (parent instanceof Region) {
Region region = (Region) parent;
if (index < region.getHouses().size())
return region.getHouses().get(index);
else
index -= region.getHouses().size();
if (index < region.getStreets().size())
return region.getStreets().get(index);
else
index -= region.getStreets().size();
if (index < region.getViToCis().size())
return region.getViToCis().get(index);
else
return null;
}
if (parent instanceof Database)
return ((Database) parent).regions.get(index);
return null;
}
@Override
public int getChildCount(Object parent) {
if (parent instanceof House)
return 0;
if (parent instanceof Street)
return ((Street) parent).getHouses().size();
if (parent instanceof Suburb)
return ((Suburb) parent).getHouses().size() +
((Suburb) parent).getStreets().size();
if (parent instanceof ViToCi)
return ((ViToCi) parent).getHouses().size() +
((ViToCi) parent).getStreets().size() +
((ViToCi) parent).getSuburbs().size();
if (parent instanceof Region)
return ((Region) parent).getHouses().size() +
((Region) parent).getStreets().size() +
((Region) parent).getViToCis().size();
if (parent instanceof Database)
return ((Database) parent).regions.size();
return 0;
}
@Override
public int getIndexOfChild(Object parent, Object child) {
return 0;
}
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
mainPanel = new javax.swing.JPanel();
tabbedPane = new javax.swing.JTabbedPane();
jPanel1 = new javax.swing.JPanel();
streetScrollPane = new javax.swing.JScrollPane();
renameTable = new javax.swing.JTable();
renamerButton = new javax.swing.JButton();
jPanel2 = new javax.swing.JPanel();
jScrollPane1 = new javax.swing.JScrollPane();
dbTree = new javax.swing.JTree();
dbEditButton = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
getContentPane().setLayout(new java.awt.GridLayout(1, 0));
mainPanel.setLayout(new java.awt.GridLayout(1, 0));
renameTable.setModel(new javax.swing.table.DefaultTableModel(
new Object[][] {
{null, null},
{null, null},
{null, null},
{null, null}
},
new String[] {
"Původní název", "Návrh z mapy"
}
) {
Class<?>[] types = new Class[] {
java.lang.Object.class, java.lang.String.class
};
boolean[] canEdit = new boolean[] {
false, true
};
@Override
public Class<?> getColumnClass(int columnIndex) {
return types[columnIndex];
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit[columnIndex];
}
});
renameTable.setColumnSelectionAllowed(true);
streetScrollPane.setViewportView(renameTable);
renamerButton.setText("Použít navržené změny");
renamerButton.addActionListener(new java.awt.event.ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent evt) {
renamerButtonActionPerformed(evt);
}
});
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
.addContainerGap(253, Short.MAX_VALUE)
.addComponent(renamerButton)
.addContainerGap())
.addComponent(streetScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 426, Short.MAX_VALUE)
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
.addComponent(streetScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 342, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(renamerButton)
.addContainerGap())
);
tabbedPane.addTab("Návrhy na přejmenování", jPanel1);
dbTree.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
@Override
public void valueChanged(javax.swing.event.TreeSelectionEvent evt) {
dbTreeValueChanged(evt);
}
});
jScrollPane1.setViewportView(dbTree);
dbEditButton.setText("Upravit");
dbEditButton.setEnabled(false);
dbEditButton.addActionListener(new java.awt.event.ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent evt) {
dbEditButtonActionPerformed(evt);
}
});
javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
jPanel2.setLayout(jPanel2Layout);
jPanel2Layout.setHorizontalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 426, Short.MAX_VALUE)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
.addContainerGap(356, Short.MAX_VALUE)
.addComponent(dbEditButton)
.addContainerGap())
);
jPanel2Layout.setVerticalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 342, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(dbEditButton)
.addContainerGap())
);
tabbedPane.addTab("Inspektor databáze", jPanel2);
mainPanel.add(tabbedPane);
getContentPane().add(mainPanel);
pack();
} // </editor-fold>//GEN-END:initComponents
private void renamerButtonActionPerformed(java.awt.event.ActionEvent evt) { //GEN-FIRST:event_renamerButtonActionPerformed
assert streetModel.elems.size() == streetModel.names.size();
Reasoner r = Reasoner.getInstance();
synchronized (r) {
r.openTransaction();
for (int i = 0; i < streetModel.elems.size(); i++) {
streetModel.elems.get(i).setName(streetModel.names.get(i));
r.update(streetModel.elems.get(i));
}
r.closeTransaction();
}
streetModel.elems.clear();
streetModel.names.clear();
jPanel1.setVisible(false);
} //GEN-LAST:event_renamerButtonActionPerformed
private AddressElement dbTreeValue = null;
private void dbTreeValueChanged(javax.swing.event.TreeSelectionEvent evt) { //GEN-FIRST:event_dbTreeValueChanged
try {
dbTreeValue = (AddressElement) dbTree.getSelectionPath().getLastPathComponent();
} catch (NullPointerException except) {
dbTreeValue = null;
System.err.println("Strange exception has occurred."+
" If you find a way to reproduce it, please report a bug!");
except.printStackTrace();
}
dbEditButton.setEnabled(EditorFactory.isEditable(dbTreeValue));
} //GEN-LAST:event_dbTreeValueChanged
private void dbEditButtonActionPerformed(java.awt.event.ActionEvent evt) { //GEN-FIRST:event_dbEditButtonActionPerformed
if (EditorFactory.isEditable(dbTreeValue)) {
if (EditorFactory.edit(dbTreeValue))
dbTree.repaint();
} else
dbEditButton.setEnabled(false);
} //GEN-LAST:event_dbEditButtonActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton dbEditButton;
private javax.swing.JTree dbTree;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel2;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JPanel mainPanel;
private javax.swing.JTable renameTable;
private javax.swing.JButton renamerButton;
private javax.swing.JScrollPane streetScrollPane;
private javax.swing.JTabbedPane tabbedPane;
// End of variables declaration//GEN-END:variables
private static class AddressElementRenderer extends DefaultTableCellRenderer {
AddressElementRenderer() {}
@Override
protected void setValue(Object value) {
super.setValue(value);
if (value instanceof AddressElement)
setText(((AddressElement) value).getName());
}
}
private static class RenameModel<Element> implements TableModel {
List<Element> elems = new ArrayList<>();
List<String> names = new ArrayList<>();
@Override
public int getRowCount() {
assert elems.size() == names.size();
return elems.size();
}
@Override
public int getColumnCount() {
return 2;
}
@Override
public String getColumnName(int columnIndex) {
if (columnIndex == 0) return "Původní název";
if (columnIndex == 1) return "Navržený název";
assert false : columnIndex;
return null;
}
@Override
public Class<?> getColumnClass(int columnIndex) {
if (columnIndex == 0) return AddressElement.class;
if (columnIndex == 1) return String.class;
assert false : columnIndex;
return null;
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return columnIndex == 1;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
if (columnIndex == 0) return elems.get(rowIndex);
if (columnIndex == 1) return names.get(rowIndex);
assert false : columnIndex;
return null;
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
assert columnIndex == 1;
names.set(rowIndex, (String) aValue);
}
@Override
public void addTableModelListener(TableModelListener l) {
}
@Override
public void removeTableModelListener(TableModelListener l) {
}
}
}