1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
|
package tim.prune.function;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.Comparator;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import tim.prune.App;
import tim.prune.GenericFunction;
import tim.prune.I18nManager;
import tim.prune.data.DataPoint;
import tim.prune.data.Track;
import tim.prune.undo.UndoRearrangePhotos;
/**
* Class to provide the function for rearranging photo points
*/
public class RearrangePhotosFunction extends GenericFunction
{
/** Function dialog */
private JDialog _dialog = null;
/** Radio buttons for start/end */
private JRadioButton[] _positionRadios = null;
/** Radio buttons for sorting */
private JRadioButton[] _sortRadios = null;
/**
* Constructor
* @param inApp app object
*/
public RearrangePhotosFunction(App inApp)
{
super(inApp);
}
/** Begin the rearrange */
public void begin()
{
// Make dialog window
if (_dialog == null)
{
_dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()), true);
_dialog.setLocationRelativeTo(_parentFrame);
_dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
_dialog.getContentPane().add(makeDialogComponents());
_dialog.pack();
}
// Reset dialog and show
_dialog.setVisible(true);
}
/** Get the name key (not needed) */
public String getNameKey() {
return "function.rearrangephotos";
}
/**
* Create dialog components
* @return Panel containing all gui elements in dialog
*/
private JPanel makeDialogComponents()
{
JPanel dialogPanel = new JPanel();
dialogPanel.setLayout(new BorderLayout());
dialogPanel.add(new JLabel(I18nManager.getText("dialog.rearrangephotos.desc")), BorderLayout.NORTH);
// Radios for position (start / end)
_positionRadios = new JRadioButton[2];
final String[] posNames = {"tostart", "toend"};
ButtonGroup posGroup = new ButtonGroup();
JPanel posPanel = new JPanel();
posPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
for (int i=0; i<2; i++)
{
_positionRadios[i] = new JRadioButton(I18nManager.getText("dialog.rearrangephotos." + posNames[i]));
posGroup.add(_positionRadios[i]);
posPanel.add(_positionRadios[i]);
}
_positionRadios[0].setSelected(true);
// Radios for sort (none / filename / time)
_sortRadios = new JRadioButton[3];
final String[] sortNames = {"nosort", "sortbyfilename", "sortbytime"};
ButtonGroup sortGroup = new ButtonGroup();
JPanel sortPanel = new JPanel();
sortPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
for (int i=0; i<3; i++)
{
_sortRadios[i] = new JRadioButton(I18nManager.getText("dialog.rearrangephotos." + sortNames[i]));
sortGroup.add(_sortRadios[i]);
sortPanel.add(_sortRadios[i]);
}
_sortRadios[0].setSelected(true);
// add to middle of dialog
JPanel centrePanel = new JPanel();
centrePanel.setLayout(new BoxLayout(centrePanel, BoxLayout.Y_AXIS));
centrePanel.add(posPanel);
centrePanel.add(sortPanel);
dialogPanel.add(centrePanel, BorderLayout.CENTER);
// button panel at bottom
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
JButton okButton = new JButton(I18nManager.getText("button.ok"));
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
finish();
_dialog.dispose();
}
});
buttonPanel.add(okButton);
JButton cancelButton = new JButton(I18nManager.getText("button.cancel"));
cancelButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
_dialog.dispose();
}
});
buttonPanel.add(cancelButton);
dialogPanel.add(buttonPanel, BorderLayout.SOUTH);
return dialogPanel;
}
/**
* Perform the rearrange
*/
private void finish()
{
Track track = _app.getTrackInfo().getTrack();
UndoRearrangePhotos undo = new UndoRearrangePhotos(track);
// Loop through track collecting non-photo points and photo points
final int numPoints = track.getNumPoints();
DataPoint[] nonPhotos = new DataPoint[numPoints];
DataPoint[] photos = new DataPoint[numPoints];
int numNonPhotos = 0;
int numPhotos = 0;
for (int i=0; i<numPoints; i++)
{
DataPoint point = track.getPoint(i);
if (point.getPhoto() != null) {
photos[numPhotos] = point;
numPhotos++;
}
else {
nonPhotos[numNonPhotos] = point;
numNonPhotos++;
}
}
// Sort photos if necessary
if (!_sortRadios[0].isSelected() && numPhotos > 1) {
sortPhotos(photos, _sortRadios[1].isSelected());
}
// Put the non-photo points and photo points together
DataPoint[] neworder = new DataPoint[numPoints];
if (_positionRadios[0].isSelected()) {
// photos at front
System.arraycopy(photos, 0, neworder, 0, numPhotos);
System.arraycopy(nonPhotos, 0, neworder, numPhotos, numNonPhotos);
}
else {
// photos at end
System.arraycopy(nonPhotos, 0, neworder, 0, numNonPhotos);
System.arraycopy(photos, 0, neworder, numNonPhotos, numPhotos);
}
// Give track the new point order
if (track.replaceContents(neworder))
{
_app.getTrackInfo().getSelection().clearAll();
_app.completeFunction(undo, I18nManager.getText("confirm.rearrangephotos"));
// Note: subscribers are informed up to three times now
}
else
{
JOptionPane.showMessageDialog(_parentFrame, I18nManager.getText("error.rearrange.noop"),
I18nManager.getText("error.function.noop.title"), JOptionPane.WARNING_MESSAGE);
}
}
/**
* Sort the given photo list either by filename or by time
* @param inPhotos array of DataPoint objects to sort
* @param inSortByFile true to sort by filename, false to sort by timestamp
* @return sorted array
*/
private static void sortPhotos(DataPoint[] inPhotos, boolean inSortByFile)
{
Comparator<DataPoint> comparator = null;
if (inSortByFile)
{
// sort by filename
comparator = new Comparator<DataPoint>() {
public int compare(DataPoint inP1, DataPoint inP2) {
if (inP2 == null) return -1; // all nulls at end
if (inP1 == null) return 1;
if (inP1.getPhoto().getFile() == null || inP2.getPhoto().getFile() == null)
return inP1.getPhoto().getName().compareTo(inP2.getPhoto().getName());
return inP1.getPhoto().getFile().compareTo(inP2.getPhoto().getFile());
}
};
}
else
{
// sort by photo timestamp
comparator = new Comparator<DataPoint>() {
public int compare(DataPoint inP1, DataPoint inP2) {
if (inP2 == null) return -1; // all nulls at end
if (inP1 == null) return 1;
long secDiff = inP1.getPhoto().getTimestamp().getSecondsSince(inP2.getPhoto().getTimestamp());
return (secDiff<0?-1:(secDiff==0?0:1));
}
};
}
Arrays.sort(inPhotos, comparator);
}
}
|