+++ /dev/null
-package tim.prune.function.cache;
-
-import java.awt.BorderLayout;
-import java.awt.CardLayout;
-import java.awt.Dimension;
-import java.awt.FlowLayout;
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
-import java.awt.Insets;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.io.File;
-
-import javax.swing.BorderFactory;
-import javax.swing.Box;
-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.JProgressBar;
-import javax.swing.JRadioButton;
-import javax.swing.JScrollPane;
-import javax.swing.JTable;
-import javax.swing.ListSelectionModel;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-import javax.swing.event.ListSelectionEvent;
-import javax.swing.event.ListSelectionListener;
-
-import tim.prune.App;
-import tim.prune.GenericFunction;
-import tim.prune.I18nManager;
-import tim.prune.config.Config;
-import tim.prune.gui.WholeNumberField;
-
-/**
- * Function class to manage the tile cache on local disk
- */
-public class ManageCacheFunction extends GenericFunction implements Runnable
-{
- private JDialog _dialog = null;
- private CardLayout _cards = null;
- private JPanel _cardPanel = null;
- private JProgressBar _progressBar = null;
- private File _cacheDir = null;
- private TileCacheModel _model = null;
- private JTable _setsTable = null;
- private JButton _deleteSetButton = null;
- private JLabel _tileSetLabel = null, _zoomLabel = null;
- private JLabel _ageLabel = null;
- private JRadioButton _deleteAllRadio = null;
- private WholeNumberField _daysField = null;
-
- private static TileFilter _TILEFILTER = new TileFilter();
-
-
- /**
- * Constructor
- * @param inApp App object
- */
- public ManageCacheFunction(App inApp) {
- super(inApp);
- }
-
- /**
- * @return name key
- */
- public String getNameKey() {
- return "function.managetilecache";
- }
-
- /**
- * Show the dialog to start
- */
- public void begin()
- {
- // First check if directory even exists
- _cacheDir = null;
- String path = Config.getConfigString(Config.KEY_DISK_CACHE);
- if (path != null && !path.equals("")) {
- _cacheDir = new File(path);
- }
- if (_cacheDir == null || !_cacheDir.exists() || !_cacheDir.isDirectory())
- {
- _app.showErrorMessage(getNameKey(), "error.cache.notthere");
- return;
- }
-
- // Build the dialog if it hasn't already been built
- if (_dialog == null)
- {
- _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()), true); // modal
- _dialog.setLocationRelativeTo(_parentFrame);
- _cardPanel = makeContents();
- _dialog.getContentPane().add(_cardPanel);
- _dialog.pack();
- }
- // Start a new thread to build the model
- new Thread(this).start();
- // Show the first panel of the dialog including progress bar
- _cards.first(_cardPanel);
- _dialog.setVisible(true);
- }
-
-
- /**
- * Make the components for the dialog
- * @return contents inside a panel
- */
- private JPanel makeContents()
- {
- JPanel dialogPanel = new JPanel();
- _cards = new CardLayout();
- dialogPanel.setLayout(_cards);
-
- // Make first card including progress bar
- JPanel firstCard = new JPanel();
- firstCard.setLayout(new BorderLayout());
- JPanel progPanel = new JPanel();
- progPanel.setLayout(new BoxLayout(progPanel, BoxLayout.Y_AXIS));
- progPanel.add(Box.createVerticalGlue());
- progPanel.add(new JLabel(I18nManager.getText("confirm.running")));
- _progressBar = new JProgressBar(0, 10);
- _progressBar.setIndeterminate(true);
- progPanel.add(_progressBar);
- progPanel.add(Box.createVerticalGlue());
- firstCard.add(progPanel, BorderLayout.CENTER);
- // Cancel button at bottom
- JPanel buttonPanel = new JPanel();
- buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
- JButton cancelButton = new JButton(I18nManager.getText("button.cancel"));
- cancelButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- // Cancel model building and close dialog
- if (_model != null) _model.cancel();
- _dialog.dispose();
- }
- });
- buttonPanel.add(cancelButton);
- firstCard.add(buttonPanel, BorderLayout.SOUTH);
- dialogPanel.add(firstCard, "card1");
-
- // Make second card including tileset table
- JPanel secondCard = new JPanel();
- secondCard.setLayout(new BorderLayout());
- // Table in the middle
- JPanel midPanel = new JPanel();
- midPanel.setLayout(new BorderLayout());
- _setsTable = new JTable();
- _setsTable.setPreferredScrollableViewportSize(new Dimension(500, 130));
- _setsTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
- midPanel.add(new JScrollPane(_setsTable), BorderLayout.CENTER);
- midPanel.setBorder(BorderFactory.createEmptyBorder(8, 5, 8, 5));
- secondCard.add(midPanel, BorderLayout.CENTER);
- // Activate buttons if a tileset is selected
- _setsTable.getSelectionModel().addListSelectionListener(
- new ListSelectionListener() {
- public void valueChanged(ListSelectionEvent e) {
- ListSelectionModel lsm = (ListSelectionModel) e.getSource();
- _deleteSetButton.setEnabled(!lsm.isSelectionEmpty());
- }
- });
-
- // button panel at bottom
- buttonPanel = new JPanel();
- // left group
- JPanel leftPanel = new JPanel();
- leftPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
- _deleteSetButton = new JButton(I18nManager.getText("button.delete"));
- _deleteSetButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent arg0) {
- showDeleteCard();
- }
- });
- leftPanel.add(_deleteSetButton);
- // right group
- JPanel rightPanel = new JPanel();
- rightPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
- JButton closeButton = new JButton(I18nManager.getText("button.close"));
- closeButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- if (_dialog != null) _dialog.dispose();
- }
- });
- rightPanel.add(closeButton);
- buttonPanel.add(leftPanel, BorderLayout.WEST);
- buttonPanel.add(rightPanel, BorderLayout.EAST);
- secondCard.add(buttonPanel, BorderLayout.SOUTH);
- dialogPanel.add(secondCard, "card2");
-
- // Make third card including delete options
- JPanel thirdCard = new JPanel();
- thirdCard.setLayout(new BorderLayout());
- // main panel
- JPanel mainPanel = new JPanel();
- GridBagLayout gridbag = new GridBagLayout();
- GridBagConstraints c = new GridBagConstraints();
- mainPanel.setLayout(gridbag);
- c.gridx = 0; c.gridy = 0;
- c.gridheight = 1; c.gridwidth = 2;
- c.weightx = 0.0; c.weighty = 0.0;
- c.anchor = GridBagConstraints.FIRST_LINE_START;
- _tileSetLabel = new JLabel("dummy text to be replaced");
- mainPanel.add(_tileSetLabel, c);
- c.gridx = 0; c.gridy = 1;
- c.ipady = 20;
- _zoomLabel = new JLabel("dummy text to be replaced");
- mainPanel.add(_zoomLabel, c);
-
- JRadioButton deleteOldRadio = new JRadioButton(I18nManager.getText("dialog.diskcache.deleteold"));
- _deleteAllRadio = new JRadioButton(I18nManager.getText("dialog.diskcache.deleteall"));
- ButtonGroup bGroup = new ButtonGroup();
- bGroup.add(_deleteAllRadio);
- bGroup.add(deleteOldRadio);
- _deleteAllRadio.addChangeListener(new ChangeListener() {
- public void stateChanged(ChangeEvent e) {
- enableAgeFields();
- }
- });
- c.gridx = 0; c.gridy = 2;
- c.anchor = GridBagConstraints.LINE_START;
- c.ipady = 0;
- mainPanel.add(deleteOldRadio, c);
- c.gridwidth = 1;
- c.gridx = 0; c.gridy = 3;
- c.insets = new Insets(0, 40, 0, 0);
- _ageLabel = new JLabel(I18nManager.getText("dialog.diskcache.maximumage"));
- mainPanel.add(_ageLabel, c);
- _daysField = new WholeNumberField(2);
- _daysField.setMinimumSize(new Dimension(20, 1));
- _daysField.setText("30"); // default is 30 days
- c.gridx = 1; c.gridy = 3;
- c.ipadx = 20;
- c.insets = new Insets(0, 15, 0, 0);
- mainPanel.add(_daysField, c);
- c.gridx = 0; c.gridy = 4;
- c.gridwidth = 2;
- c.ipadx = 0;
- c.insets = new Insets(0, 0, 0, 0);
- mainPanel.add(_deleteAllRadio, c);
- _deleteAllRadio.setSelected(true);
- thirdCard.add(mainPanel, BorderLayout.CENTER);
- // button panel
- buttonPanel = new JPanel();
- buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
- JButton deleteButton = new JButton(I18nManager.getText("button.delete"));
- deleteButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent arg0) {
- deleteCurrentSets();
- }
- });
- buttonPanel.add(deleteButton);
- cancelButton = new JButton(I18nManager.getText("button.cancel"));
- cancelButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- // Go back to second card
- _cards.show(_cardPanel, "card2");
- }
- });
- buttonPanel.add(cancelButton);
- thirdCard.add(buttonPanel, BorderLayout.SOUTH);
- dialogPanel.add(thirdCard, "card3");
- return dialogPanel;
- }
-
-
- /**
- * Construct the model in a separate thread
- * and go on to the second panel of the dialog
- */
- public void run()
- {
- // TODO: Maybe this can be speeded up so that it just finds the tilesets first and then gets the details later
- // Check if directory has anything in it
- _model = new TileCacheModel(_cacheDir);
- _model.buildTileSets();
- if (_model.isAborted()) return;
-
- if (_model.getNumTileSets() <= 0)
- {
- _app.showErrorMessage(getNameKey(), "error.cache.empty");
- _dialog.dispose();
- return;
- }
-
- // Set controls according to current config
- _setsTable.setModel(new TileSetTableModel(_model));
- _deleteSetButton.setEnabled(false);
- // Set column widths after model has been set
- _setsTable.getColumnModel().getColumn(0).setPreferredWidth(220);
- _setsTable.getColumnModel().getColumn(1).setPreferredWidth(200);
- // Show second panel
- _cards.next(_cardPanel);
- }
-
- /**
- * Prepare and show the delete panel
- */
- private void showDeleteCard()
- {
- // set tileset label
- int numSelected = 0;
- String desc = null;
- RowInfo totals = new RowInfo();
- for (int i=0; i<_setsTable.getRowCount(); i++) {
- if (_setsTable.isRowSelected(i))
- {
- if (desc == null) desc = _model.getTileSet(i).getPath();
- totals.addRow(_model.getTileSet(i).getRowInfo());
- numSelected++;
- }
- }
- if (numSelected == 0) return;
- String tileSetDesc = (numSelected == 1?desc:I18nManager.getText("dialog.diskcache.tileset.multiple"));
- _tileSetLabel.setText(I18nManager.getText("dialog.diskcache.tileset") + " : "
- + tileSetDesc);
- _zoomLabel.setText(I18nManager.getText("dialog.diskcache.table.zoom") + " : "
- + totals.getZoomRange());
-
- // enable/disable edit fields
- enableAgeFields();
- // show the next card
- _cards.next(_cardPanel);
- }
-
- /**
- * Enable or disable the fields for entering tile age
- */
- private void enableAgeFields()
- {
- boolean showAgeBoxes = !_deleteAllRadio.isSelected();
- _ageLabel.setEnabled(showAgeBoxes);
- _daysField.setEnabled(showAgeBoxes);
- }
-
- /**
- * Try to delete all the files in the currently selected tilesets
- * (Maybe more than one tileset is selected in the table)
- */
- private void deleteCurrentSets()
- {
- // Determine age limit if given
- int ageLimit = -1;
- if (!_deleteAllRadio.isSelected()) {
- ageLimit = _daysField.getValue();
- }
- // Loop over selected tilesets and delete them
- int totalDeleted = 0;
- for (int i=0; i<_setsTable.getRowCount(); i++)
- {
- if (_setsTable.isRowSelected(i))
- {
- File dir = new File(_model.getCacheDir(), _model.getTileSet(i).getPath());
- if (dir.exists())
- {
- int numFilesDeleted = deleteFilesFrom(dir, ageLimit);
- if (numFilesDeleted > 0) {
- totalDeleted += numFilesDeleted;
- }
- }
- }
- }
- if (totalDeleted > 0)
- {
- // Show confirmation message
- JOptionPane.showMessageDialog(_dialog, I18nManager.getTextWithNumber("dialog.diskcache.deleted", totalDeleted),
- I18nManager.getText(getNameKey()), JOptionPane.INFORMATION_MESSAGE);
- // reload model
- _cards.first(_cardPanel);
- new Thread(this).start();
- }
- else {
- _app.showErrorMessage(getNameKey(), "error.cache.cannotdelete");
- }
- }
-
-
- /**
- * Delete recursively all files which are older than the age limit
- * @param inDir directory to delete from
- * @param inMaxDays age limit in days
- * @return number of files deleted
- */
- private static int deleteFilesFrom(File inDir, int inMaxDays)
- {
- int numDeleted = 0;
- long now = System.currentTimeMillis();
- if (inDir.exists() && inDir.isDirectory())
- {
- for (File subdir : inDir.listFiles())
- {
- if (subdir.isDirectory()) {
- numDeleted += deleteFilesFrom(subdir, inMaxDays);
- }
- else if (subdir.isFile() && subdir.exists() && _TILEFILTER.accept(subdir))
- {
- long fileAge = (now - subdir.lastModified()) / 1000 / 60 / 60 / 24;
- if (inMaxDays < 0 || fileAge > inMaxDays)
- {
- if (subdir.delete()) {
- numDeleted++;
- }
- }
- }
- }
- // Try to delete the directory (doesn't work if not empty)
- inDir.delete();
- }
- return numDeleted;
- }
-}