/*
This file is part of RouteConverter.
RouteConverter is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
RouteConverter is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with RouteConverter; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Copyright (C) 2007 Christian Pesch. All Rights Reserved.
*/
package slash.navigation.converter.gui.panels;
import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.core.GridLayoutManager;
import com.intellij.uiDesigner.core.Spacer;
import slash.navigation.base.Wgs84Position;
import slash.navigation.common.SimpleNavigationPosition;
import slash.navigation.converter.gui.RouteConverter;
import slash.navigation.converter.gui.actions.AddAudioAction;
import slash.navigation.converter.gui.actions.DeletePositionAction;
import slash.navigation.converter.gui.actions.PlayVoiceAction;
import slash.navigation.converter.gui.helpers.PointsOfInterestTableHeaderMenu;
import slash.navigation.converter.gui.helpers.PointsOfInterestTablePopupMenu;
import slash.navigation.converter.gui.models.FilteringPositionsModel;
import slash.navigation.converter.gui.models.PointsOfInterestTableColumnModel;
import slash.navigation.converter.gui.models.PositionColumnValues;
import slash.navigation.converter.gui.models.PositionTableColumn;
import slash.navigation.converter.gui.models.PositionsModel;
import slash.navigation.converter.gui.predicates.PointOfInterestPositionPredicate;
import slash.navigation.converter.gui.renderer.DescriptionColumnTableCellEditor;
import slash.navigation.gui.actions.ActionManager;
import slash.navigation.gui.actions.FrameAction;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import java.awt.*;
import java.io.File;
import java.util.ResourceBundle;
import static java.awt.event.KeyEvent.VK_DELETE;
import static java.lang.Integer.MAX_VALUE;
import static javax.help.CSH.setHelpIDString;
import static javax.swing.DropMode.ON;
import static javax.swing.JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT;
import static javax.swing.KeyStroke.getKeyStroke;
import static javax.swing.event.TableModelEvent.ALL_COLUMNS;
import static slash.navigation.converter.gui.models.LocalActionConstants.POINTS_OF_INTEREST;
import static slash.navigation.converter.gui.models.PositionColumns.DESCRIPTION_COLUMN_INDEX;
import static slash.navigation.converter.gui.models.PositionColumns.PHOTO_COLUMN_INDEX;
import static slash.navigation.gui.helpers.JMenuHelper.registerAction;
import static slash.navigation.gui.helpers.JTableHelper.calculateRowHeight;
import static slash.navigation.gui.helpers.JTableHelper.isFirstToLastRow;
/**
* The Points of Interest panel of the route converter user interface.
*
* @author Christian Pesch
*/
public class PointOfInterestPanel implements PanelInTab {
private static final int ROW_HEIGHT_FOR_PHOTO_COLUMN = 200;
private JPanel pointsOfInterestPanel;
private JTable tablePointsOfInterest;
private JButton buttonPlayVoice;
private JButton buttonAddAudio;
private JButton buttonDeletePointsOfInterest;
private FilteringPositionsModel positionsModel;
public PointOfInterestPanel() {
$$$setupUI$$$();
initialize();
}
private void initialize() {
final RouteConverter r = RouteConverter.getInstance();
positionsModel = new FilteringPositionsModel(r.getConvertPanel().getPositionsModel(), new PointOfInterestPositionPredicate());
tablePointsOfInterest.setModel(getPositionsModel());
PointsOfInterestTableColumnModel tableColumnModel = new PointsOfInterestTableColumnModel();
tablePointsOfInterest.setColumnModel(tableColumnModel);
r.getUnitSystemModel().addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
getPositionsModel().fireTableRowsUpdated(0, MAX_VALUE, ALL_COLUMNS);
}
});
r.getTimeZone().addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
getPositionsModel().fireTableRowsUpdated(0, MAX_VALUE, ALL_COLUMNS);
}
});
tablePointsOfInterest.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting())
return;
if (getPositionsModel().isContinousRange())
return;
handlePositionsUpdate();
}
});
getPositionsModel().addTableModelListener(new TableModelListener() {
public void tableChanged(TableModelEvent e) {
if (!isFirstToLastRow(e))
return;
if (getPositionsModel().isContinousRange())
return;
handlePositionsUpdate();
}
});
tableColumnModel.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
handleColumnVisibilityUpdate((PositionTableColumn) e.getSource());
}
});
tablePointsOfInterest.registerKeyboardAction(new FrameAction() {
public void run() {
r.getContext().getActionManager().run("delete-points-of-interest");
}
}, getKeyStroke(VK_DELETE, 0), WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
tablePointsOfInterest.setDropMode(ON);
ActionManager actionManager = r.getContext().getActionManager();
new PointsOfInterestTableHeaderMenu(tablePointsOfInterest.getTableHeader(), tableColumnModel, actionManager);
new PointsOfInterestTablePopupMenu(tablePointsOfInterest).createPopupMenu();
actionManager.register("play-voice", new PlayVoiceAction(tablePointsOfInterest, getPositionsModel(), r.getUrlModel()));
actionManager.register("add-audio", new AddAudioAction(tablePointsOfInterest, getPositionsModel()));
actionManager.register("delete-points-of-interest", new DeletePositionAction(tablePointsOfInterest, getPositionsModel()));
actionManager.registerLocal("delete", POINTS_OF_INTEREST, "delete-points-of-interest");
registerAction(buttonPlayVoice, "play-voice");
registerAction(buttonAddAudio, "add-audio");
registerAction(buttonDeletePointsOfInterest, "delete-points-of-interest");
setHelpIDString(tablePointsOfInterest, "point-of-interest-list");
handlePositionsUpdate();
for (PositionTableColumn column : tableColumnModel.getPreparedColumns())
handleColumnVisibilityUpdate(column);
}
private int getDefaultRowHeight() {
return calculateRowHeight(this, new DescriptionColumnTableCellEditor(), new SimpleNavigationPosition(null, null));
}
public Component getRootComponent() {
return pointsOfInterestPanel;
}
public String getLocalName() {
return POINTS_OF_INTEREST;
}
public JComponent getFocusComponent() {
return tablePointsOfInterest;
}
public JButton getDefaultButton() {
return buttonPlayVoice;
}
public void initializeSelection() {
handlePositionsUpdate();
}
private FilteringPositionsModel getPositionsModel() {
return positionsModel;
}
private void handlePositionsUpdate() {
int[] selectedRows = tablePointsOfInterest.getSelectedRows();
boolean existsASelectedPosition = selectedRows.length > 0;
RouteConverter r = RouteConverter.getInstance();
ActionManager actionManager = r.getContext().getActionManager();
actionManager.enableLocal("delete", POINTS_OF_INTEREST, existsASelectedPosition);
actionManager.enable("play-voice", existsASelectedPosition);
actionManager.enable("add-audio", existsASelectedPosition);
if (r.isPointsOfInterestPanelSelected())
r.selectPositionsInMap(getPositionsModel().mapRows(selectedRows));
}
private void handleColumnVisibilityUpdate(PositionTableColumn column) {
if (column.getModelIndex() == PHOTO_COLUMN_INDEX)
tablePointsOfInterest.setRowHeight(column.isVisible() ? ROW_HEIGHT_FOR_PHOTO_COLUMN : getDefaultRowHeight());
}
public void addAudio(Wgs84Position position, File file) {
position.setOrigin(file);
RouteConverter r = RouteConverter.getInstance();
PositionsModel positionsModel = r.getConvertPanel().getPositionsModel();
int index = positionsModel.getIndex(position);
positionsModel.edit(index, new PositionColumnValues(DESCRIPTION_COLUMN_INDEX, file.getName().replaceAll(".wav", "")), true, true);
}
/**
* Method generated by IntelliJ IDEA GUI Designer
* >>> IMPORTANT!! <<<
* DO NOT edit this method OR call it in your code!
*
* @noinspection ALL
*/
private void $$$setupUI$$$() {
pointsOfInterestPanel = new JPanel();
pointsOfInterestPanel.setLayout(new GridLayoutManager(2, 1, new Insets(3, 3, 3, 3), -1, -1));
pointsOfInterestPanel.setMinimumSize(new Dimension(-1, -1));
pointsOfInterestPanel.setPreferredSize(new Dimension(560, 560));
final JScrollPane scrollPane1 = new JScrollPane();
pointsOfInterestPanel.add(scrollPane1, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false));
tablePointsOfInterest = new JTable();
tablePointsOfInterest.setAutoCreateColumnsFromModel(false);
tablePointsOfInterest.setShowHorizontalLines(false);
tablePointsOfInterest.setShowVerticalLines(false);
scrollPane1.setViewportView(tablePointsOfInterest);
final JPanel panel1 = new JPanel();
panel1.setLayout(new GridLayoutManager(1, 4, new Insets(0, 0, 0, 0), -1, -1));
pointsOfInterestPanel.add(panel1, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
buttonPlayVoice = new JButton();
this.$$$loadButtonText$$$(buttonPlayVoice, ResourceBundle.getBundle("slash/navigation/converter/gui/RouteConverter").getString("play-voice-action"));
buttonPlayVoice.setToolTipText(ResourceBundle.getBundle("slash/navigation/converter/gui/RouteConverter").getString("play-voice-action-tooltip"));
panel1.add(buttonPlayVoice, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
buttonDeletePointsOfInterest = new JButton();
this.$$$loadButtonText$$$(buttonDeletePointsOfInterest, ResourceBundle.getBundle("slash/navigation/converter/gui/RouteConverter").getString("delete-points-of-interest-action"));
buttonDeletePointsOfInterest.setToolTipText(ResourceBundle.getBundle("slash/navigation/converter/gui/RouteConverter").getString("delete-points-of-interest-action-tooltip"));
panel1.add(buttonDeletePointsOfInterest, new GridConstraints(0, 2, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
final Spacer spacer1 = new Spacer();
panel1.add(spacer1, new GridConstraints(0, 3, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, 1, null, null, null, 0, false));
buttonAddAudio = new JButton();
this.$$$loadButtonText$$$(buttonAddAudio, ResourceBundle.getBundle("slash/navigation/converter/gui/RouteConverter").getString("add-audio-action"));
buttonAddAudio.setToolTipText(ResourceBundle.getBundle("slash/navigation/converter/gui/RouteConverter").getString("add-audio-action-tooltip"));
panel1.add(buttonAddAudio, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
}
/**
* @noinspection ALL
*/
private void $$$loadButtonText$$$(AbstractButton component, String text) {
StringBuffer result = new StringBuffer();
boolean haveMnemonic = false;
char mnemonic = '\0';
int mnemonicIndex = -1;
for (int i = 0; i < text.length(); i++) {
if (text.charAt(i) == '&') {
i++;
if (i == text.length()) break;
if (!haveMnemonic && text.charAt(i) != '&') {
haveMnemonic = true;
mnemonic = text.charAt(i);
mnemonicIndex = result.length();
}
}
result.append(text.charAt(i));
}
component.setText(result.toString());
if (haveMnemonic) {
component.setMnemonic(mnemonic);
component.setDisplayedMnemonicIndex(mnemonicIndex);
}
}
/**
* @noinspection ALL
*/
public JComponent $$$getRootComponent$$$() {
return pointsOfInterestPanel;
}
}