/**
*#########################################################################
*
* A component of the Gatherer application, part of the Greenstone digital
* library suite from the New Zealand Digital Library Project at the
* University of Waikato, New Zealand.
*
*
*
* Author: John Thompson, Greenstone Digital Library, University of Waikato
*
*
*
* Copyright (C) 1999 New Zealand Digital Library Project
*
*
*
* This program 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.
*
*
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*########################################################################
*/
package org.greenstone.gatherer.gui;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.event.*;
import org.greenstone.gatherer.Configuration;
import org.greenstone.gatherer.DebugStream;
import org.greenstone.gatherer.Dictionary;
import org.greenstone.gatherer.Gatherer;
import org.greenstone.gatherer.LocalGreenstone;
import org.greenstone.gatherer.collection.BasicCollectionConfiguration;
import org.greenstone.gatherer.collection.CollectionManager;
import org.greenstone.gatherer.shell.GShell;
import org.greenstone.gatherer.shell.GShellEvent;
import org.greenstone.gatherer.shell.GShellListener;
import org.greenstone.gatherer.util.ArrayTools;
import org.greenstone.gatherer.util.CheckList;
import org.greenstone.gatherer.util.CheckListEntry;
import org.greenstone.gatherer.util.StaticStrings;
import org.greenstone.gatherer.util.Utility;
/** This class provides the functionality to write a CD-ROM/DVD image of current collections from the GSDLHOME/collect/ directory to CDROM. The user chooses the collection from a list, where each entry also displays details about itself, confirms the delete of a collection by checking a checkbox then presses the ok button to actually delete the collection.
Copied from DeleteCollectionPrompt
* @author John Thompson, Greenstone Digital Library, University of Waikato
* @version 2.3
*/
public class WriteCDImagePrompt
extends ModalDialog
implements GShellListener {
private OKButtonListener ok_button_listener;
private ArrayList all_collections = null;
private ArrayList selected_collections = null;
/** The list of collections to include in exported cd-rom/dvd image */
private CheckList list = null;
/** The currently selected collection for deletion. */
private BasicCollectionConfiguration collection = null;
/** A reference to ourself so any inner-classes can dispose of us. */
private WriteCDImagePrompt prompt = null;
/** The close button, which exits the prompt without deleting anything. */
private JButton cancel_button = null;
/** The ok button which causes the selected collection to be deleted. */
private JButton ok_button = null;
/** The label above details. */
private JLabel details_label = null;
/** The label above the list. */
private JLabel list_label = null;
/** The text area used to display details about the collection selected. */
private JTextArea details_textarea = null;
/** The text area used to display instructions for the cd-rom/dvd export */
private JTextArea instructions_textarea;
/** The radio button for switching on the noinstall option */
private JRadioButton noinstall_button = null;
private JRadioButton install_button = null;
private JTextField title_field = null;
private JTextField estimated_size_field = null;
private JLabel title_label = null;
private JLabel estimated_size_label = null;
/** A string array used to pass arguments to the exportcol.pl script */
private String args[] = null;
private String cd_title = null;
/** whether the exporting was successful or not */
private boolean successful = false;
/** whether we are trying to export or not */
private boolean exporting = false;
/** the error message if any */
private StringBuffer error_message = null;
/** This is the size of the exported stuff on its own without collections. */
private long total_exported_size = 14000000;
/** The size of the export prompt screen. */
public static final Dimension SIZE = new Dimension(500, 500);
/** Constructor.
* @see org.greenstone.gatherer.collection.WriteCDImagePrompt.CancelButtonListener
* @see org.greenstone.gatherer.collection.WriteCDImagePrompt.CollectionListListener
* @see org.greenstone.gatherer.collection.WriteCDImagePrompt.OKButtonListener
*/
public WriteCDImagePrompt() {
super(Gatherer.g_man, true);
cancel_button = new GLIButton(Dictionary.get("General.Close"), Dictionary.get("General.Close_Tooltip"));
details_textarea = new JTextArea(Dictionary.get("DeleteCollectionPrompt.No_Collection"));
details_textarea.setEditable(false);
details_label = new JLabel(Dictionary.get("DeleteCollectionPrompt.Collection_Details"));
instructions_textarea = new JTextArea(Dictionary.get("WriteCDImagePrompt.Instructions"));
instructions_textarea.setCaretPosition(0);
instructions_textarea.setEditable(false);
instructions_textarea.setLineWrap(true);
instructions_textarea.setRows(4);
instructions_textarea.setWrapStyleWord(true);
all_collections = new ArrayList();
list = new CheckList(true);
list_label = new JLabel(Dictionary.get("DeleteCollectionPrompt.Collection_List"));
ok_button = new GLIButton(Dictionary.get("WriteCDImagePrompt.Export"), Dictionary.get("WriteCDImagePrompt.Export_Tooltip"));
title_field = new JTextField();
// Dictionary.setTooltip(title_field, "WriteCDImagePrompt.CD_Name_Tooltip");
title_label = new JLabel(Dictionary.get("WriteCDImagePrompt.CD_Name"));
estimated_size_field = new JTextField();
estimated_size_field.setEditable(false);
// work out the size of the images directory - could be large if they
// have the classic interface pack installed
total_exported_size += getFileSize(new File(LocalGreenstone.getDirectoryPath()+File.separator+"images"));
estimated_size_field.setText(Utility.formatFileLength(total_exported_size));
estimated_size_field.setBackground(Configuration.getColor("coloring.collection_tree_background", false));
estimated_size_label = new JLabel(Dictionary.get("WriteCDImagePrompt.Size_Label"));
scanForCollections();
list.setListData(all_collections);
prompt = this;
setSize(SIZE);
setTitle(Dictionary.get("WriteCDImagePrompt.Export"));
setJMenuBar(new SimpleMenuBar("exportingcollections"));
cancel_button.addActionListener(new CancelButtonListener());
list.addListSelectionListener(new CollectionListListener());
list.clearSelection();
list.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
ok_button_listener = new OKButtonListener();
ok_button.addActionListener(ok_button_listener);
ok_button.setEnabled(false);
//title.getDocument().addDocumentListener(new DocumentListener());
noinstall_button = new JRadioButton(Dictionary.get("WriteCDImagePrompt.NoInstall"));
noinstall_button.setToolTipText(Dictionary.get("WriteCDImagePrompt.NoInstall_Tooltip"));
install_button = new JRadioButton(Dictionary.get("WriteCDImagePrompt.Install"));
install_button.setToolTipText(Dictionary.get("WriteCDImagePrompt.Install_Tooltip"));
}
/** Destructor. */
public void destroy() {
all_collections.clear();
all_collections = null;
cancel_button = null;
details_textarea = null;
details_label = null;
list = null;
ok_button = null;
prompt = null;
if (selected_collections!=null) {
selected_collections.clear();
selected_collections = null;
}
title_field = null;
title_label = null;
}
/** This method causes the modal prompt to be displayed.
* returns true if it has exported the collections that are currently selected */
public boolean display() {
// Radio buttons
ButtonGroup radio_group = new ButtonGroup();
radio_group.add(install_button);
install_button.setSelected(true);
radio_group.add(noinstall_button);
// Top pane
JPanel instructions_pane = new JPanel(new BorderLayout());
instructions_pane.setBorder(BorderFactory.createEmptyBorder(5,5,0,5));
instructions_pane.add(new JScrollPane(instructions_textarea), BorderLayout.CENTER);
title_label.setBorder(BorderFactory.createEmptyBorder(0,5,0,15));
JPanel title_pane = new JPanel(new BorderLayout());
title_pane.add(title_label, BorderLayout.WEST);
title_pane.add(title_field, BorderLayout.CENTER);
title_pane.setBorder(BorderFactory.createEmptyBorder(5,0,5,0));
JPanel radio_pane = new JPanel(new GridLayout(2,1));
install_button.setBackground(Configuration.getColor("coloring.collection_heading_background", true));
noinstall_button.setBackground(Configuration.getColor("coloring.collection_heading_background", true));
radio_pane.add(install_button);
radio_pane.add(noinstall_button);
JPanel options_pane = new JPanel(new BorderLayout());
options_pane.add(title_pane, BorderLayout.NORTH);
options_pane.add(radio_pane, BorderLayout.CENTER);
instructions_pane.add(options_pane, BorderLayout.SOUTH);
// Central pane
JPanel list_pane = new JPanel(new BorderLayout());
list_pane.add(list_label, BorderLayout.NORTH);
list_pane.add(new JScrollPane(list), BorderLayout.CENTER);
list_pane.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0));
JPanel details_pane = new JPanel(new BorderLayout());
details_pane.add(details_label, BorderLayout.NORTH);
details_pane.add(new JScrollPane(details_textarea), BorderLayout.CENTER);
details_pane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
JPanel central_pane = new JPanel(new GridLayout(2, 1));
central_pane.add(list_pane);
central_pane.add(details_pane);
central_pane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
// Lower pane
JPanel estimated_size_pane = new JPanel(new BorderLayout());
estimated_size_pane.add(estimated_size_label, BorderLayout.WEST);
estimated_size_pane.add(estimated_size_field, BorderLayout.CENTER);
estimated_size_pane.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0));
JPanel button_pane = new JPanel(new GridLayout(1, 2));
button_pane.add(ok_button);
button_pane.add(cancel_button);
button_pane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
JPanel lower_pane = new JPanel(new BorderLayout());
lower_pane.add(estimated_size_pane, BorderLayout.NORTH);
lower_pane.add(button_pane, BorderLayout.SOUTH);
lower_pane.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 5));
// Final.
JPanel content_pane = (JPanel)this.getContentPane();
content_pane.setLayout(new BorderLayout());
content_pane.add(instructions_pane, BorderLayout.NORTH);
content_pane.add(central_pane, BorderLayout.CENTER);
content_pane.add(lower_pane, BorderLayout.SOUTH);
// Center and display.
Dimension screen_size = Configuration.screen_size;
this.setLocation((screen_size.width - SIZE.width) / 2, (screen_size.height - SIZE.height) / 2);
this.setVisible(true); // blocks until the dialog is killed
return true;
}
private long getFileSize(File file)
{
long file_size = 0;
// Directory case
if (file.isDirectory()) {
File files[] = file.listFiles();
for (int i = 0; i < files.length; i++) {
file_size += getFileSize(files[i]);
}
}
// File case
else {
file_size = file.length();
}
return file_size;
}
/** This method calls the builcol.pl scripts via a GShell so as to not lock up the processor.
* @see org.greenstone.gatherer.Configuration
* @see org.greenstone.gatherer.Gatherer
* @see org.greenstone.gatherer.collection.Collection
* @see org.greenstone.gatherer.gui.BuildOptions
* @see org.greenstone.gatherer.shell.GShell
* @see org.greenstone.gatherer.shell.GShellListener
* @see org.greenstone.gatherer.shell.GShellProgressMonitor
* @see org.greenstone.gatherer.util.Utility
*/
public void writeCDImageCollections()
{
DebugStream.println("WriteCDImagePrompt.writeCDImageCollections()");
int num_collections = selected_collections.size();
if (num_collections == 0) return;
cd_title = title_field.getText();
cd_title = cd_title.trim();
cd_title = cd_title.replaceAll("\"","");
// Generate the exportcol.pl command
ArrayList command_parts_list = new ArrayList();
if (Utility.isWindows() && (!Gatherer.isGsdlRemote)) {
command_parts_list.add(Configuration.perl_path);
command_parts_list.add("-S");
}
command_parts_list.add(LocalGreenstone.getBinScriptDirectoryPath() + "exportcol.pl");
command_parts_list.add("-gli");
command_parts_list.add("-language");
command_parts_list.add(Configuration.getLanguage());
if (cd_title.equals("")) {
command_parts_list.add("-cdname");
command_parts_list.add("Greenstone Collections");
command_parts_list.add("-cddir");
command_parts_list.add("exported_collections");
}
else {
command_parts_list.add("-cdname");
command_parts_list.add(cd_title);
String cd_dir = "exported_"+cd_title.replaceAll("\\s","");
command_parts_list.add("-cddir");
command_parts_list.add(cd_dir);
}
if (noinstall_button.isSelected()) {
command_parts_list.add("-noinstall");
}
for (int i = 0; i < num_collections; i++) {
command_parts_list.add(((BasicCollectionConfiguration) selected_collections.get(i)).getShortName());
}
DebugStream.print("export command = ");
for (int i = 0; i < command_parts_list.size(); i++) {
DebugStream.print(command_parts_list.get(i) + " ");
}
DebugStream.println("");
// Run the exportcol.pl command
String[] command_parts = (String[]) command_parts_list.toArray(new String[0]);
GShell process = new GShell(command_parts, GShell.CDIMAGE, 3, this, null, GShell.GSHELL_CDIMAGE);
process.start();
//process.run();
DebugStream.println("WriteCDImagePrompt.writeCDImageCollections().return");
}
/** Shows an export complete prompt.
* @param success A boolean indicating if the collection was successfully deleted.
* @see org.greenstone.gatherer.collection.Collection
*/
public void resultPrompt(boolean success, String extra) {
args = new String[2];
StringBuffer coll_names = new StringBuffer();
for (int i=0; i0) {
coll_names.append(", ");
}
BasicCollectionConfiguration complete_collection = (BasicCollectionConfiguration)selected_collections.get(i);
coll_names.append(complete_collection.getName() + StaticStrings.SPACE_CHARACTER + StaticStrings.OPEN_PARENTHESIS_CHARACTER + complete_collection.getShortName() + StaticStrings.CLOSE_PARENTHESIS_CHARACTER);
complete_collection = null;
}
args[0] = coll_names.toString();
args[1] = LocalGreenstone.getTmpDirectoryPath();
if(cd_title.equals("")) {
args[1] += "exported_collections";
} else {
args[1] += "exported_"+cd_title.replaceAll("\\s","");
}
String title;
String label;
if (success) {
title = Dictionary.get("WriteCDImagePrompt.Successful_Title");
label = Dictionary.get("WriteCDImagePrompt.Successful_Export", args);
} else {
title = Dictionary.get("WriteCDImagePrompt.Failed_Title");
label = Dictionary.get("WriteCDImagePrompt.Failed_Export", args);
}
SimpleResultDialog result_dialog = new SimpleResultDialog(title, label, extra);
result_dialog.setVisible(true); // Blocks
result_dialog.dispose();
result_dialog = null;
}
/** Method to scan the collect directory retrieving and reloading each collection it finds, while building the list of known collections.
* @see org.greenstone.gatherer.Configuration
* @see org.greenstone.gatherer.Gatherer
* @see org.greenstone.gatherer.util.ArrayTools
* @see org.greenstone.gatherer.util.Utility
*/
private void scanForCollections() {
// Start at the collect dir.
File collect_directory = new File(Gatherer.getCollectDirectoryPath());
if (collect_directory.exists()) {
// Now for each child directory see if it contains a .col file and
// if so try to load it..
File collections[] = collect_directory.listFiles();
ArrayTools.sort(collections);
for(int i = 0; collections != null && i < collections.length; i++) {
if(collections[i].isDirectory() && !collections[i].getName().equals(StaticStrings.MODEL_COLLECTION_NAME)) {
File config_file = new File(collections[i], Utility.CONFIG_FILE);
if (config_file.exists()) {
BasicCollectionConfiguration config = new BasicCollectionConfiguration(config_file);
all_collections.add(config);
config = null;
}
}
}
}
// Otherwise the collect directory doesn't actually exist, so there ain't much we can do.
}
/** All implementation of GShellListener must include this method so the listener can be informed of messages from the GShell.
* @param event A GShellEvent that contains, amoung other things, the message.
*/
public synchronized void message(GShellEvent event) {
// Ignore the messages from RecPlug with 'show_progress' set (used for progress bars)
String message = event.getMessage();
if (message.startsWith("exportcol.pl>")) {
message = message.substring(13);
//DebugStream.println("message = "+event.getMessage());
error_message.append(message);
error_message.append("\n");
}
}
/** All implementation of GShellListener must include this method so the listener can be informed when a GShell begins its task. Implementation side-effect, not actually used.
* @param event A GShellEvent that contains details of the initial state of the GShell before task comencement.
*/
public synchronized void processBegun(GShellEvent event) {
// We don't care.
}
/** All implementation of GShellListener must include this method so the listener can be informed when a GShell completes its task.
* @param event A GShellEvent that contains details of the final state of the GShell after task completion.
*/
public synchronized void processComplete(GShellEvent event) {
successful = false;
if(event.getStatus() == GShell.OK) {
if(event.getType() == GShell.CDIMAGE) {
successful = true;
}
}
ok_button_listener.processComplete();
}
/** A button listener implementation, which listens for actions on the close button and disposes of the dialog when detected. */
private class CancelButtonListener
implements ActionListener {
/** Any implementation of ActionListener must include this method so we can be informed when the button is actioned.
* @param event An ActionEvent containing all the relevant information garnered from the event itself.
*/
public void actionPerformed(ActionEvent event) {
prompt.dispose();
}
}
/** This private class listens for selection events in from the list and then displays the appropriate details for that collection.
*/
private class CollectionListListener
implements ListSelectionListener
{
/** Any implementation of ListSelectionListener must include this method so we can be informed when the list selection changes.
* @param event a ListSelectionEvent containing all the relevant information garnered from the event itself
*/
public void valueChanged(ListSelectionEvent event)
{
// Wait for things to settle down a bit
if (event.getValueIsAdjusting()) {
return;
}
// Can only export when something is ticked
ok_button.setEnabled(!list.isNothingTicked());
if (list.isSelectionEmpty()) {
// This only happens when the dialog is first entered
details_textarea.setText(Dictionary.get("DeleteCollectionPrompt.No_Collection"));
return;
}
collection = (BasicCollectionConfiguration) ((CheckListEntry) list.getSelectedValue()).getObject();
args = new String[3];
args[0] = collection.getCreator();
args[1] = collection.getMaintainer();
args[2] = collection.getDescription();
details_textarea.setText(Dictionary.get("DeleteCollectionPrompt.Details", args));
details_textarea.setCaretPosition(0);
// Find the size of the "etc", "images" and "index" directories of the collection
String collection_directory_path = CollectionManager.getCollectionDirectoryPath(collection.getShortName());
File etc_directory = new File(collection_directory_path + "etc");
File images_directory = new File(collection_directory_path + "images");
File index_directory = new File(collection_directory_path + "index");
long collection_size_built = getFileSize(etc_directory) + getFileSize(images_directory) + getFileSize(index_directory);
// Add/subtract it from the total, depending on whether the collection has just been ticked/unticked
if (((CheckListEntry) list.getSelectedValue()).isSelected()) {
total_exported_size += collection_size_built;
}
else {
total_exported_size -= collection_size_built;
}
// Update the size field
estimated_size_field.setText(Utility.formatFileLength(total_exported_size));
}
}
/** The OK button listener implementation. */
private class OKButtonListener
implements ActionListener {
private Component glass_pane;
private MouseListener mouse_blocker_listener;
private ProgressDialog progress_dialog;
/** Any implementation of ActionListener must include this method so we can be informed when the button is actioned.
* @param event An ActionEvent containing all the relevant information garnered from the event itself.
* @see org.greenstone.gatherer.Configuration
* @see org.greenstone.gatherer.Gatherer
* @see org.greenstone.gatherer.util.Utility
*/
public void actionPerformed(ActionEvent event) {
///ystem.err.println("OK Clicked");
// Make sure there are some colls specified
selected_collections = list.getTicked();
error_message = new StringBuffer();
// Set the cursor to hourglass
glass_pane = getGlassPane();
mouse_blocker_listener = new MouseAdapter() {};
glass_pane.addMouseListener(mouse_blocker_listener);
glass_pane.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
glass_pane.setVisible(true);
// Export the selected collection.
///ystem.err.println("Write CD-ROM/DVD image for named collections");
writeCDImageCollections();
// Show progress dialog
///ystem.err.println("Showing progress dialog");
progress_dialog = new ProgressDialog();
progress_dialog.setVisible(true);
}
public void processComplete() {
///ystem.err.println("Process complete");
// Dispose of progress dialog
progress_dialog.setVisible(false);
progress_dialog.dispose();
progress_dialog = null;
// unset the cursor
glass_pane.setVisible(false);
glass_pane.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
glass_pane.removeMouseListener(mouse_blocker_listener);
glass_pane = null;
mouse_blocker_listener= null;
if (successful) {
resultPrompt(true, error_message.toString());
} else {
resultPrompt(false, error_message.toString());
}
error_message = null;
}
private class ProgressDialog
extends ModalDialog {
private Dimension size = new Dimension(400,65);
public ProgressDialog() {
super(Gatherer.g_man, Dictionary.get("WriteCDImagePrompt.Title"), true);
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
setSize(size);
JPanel content_pane = (JPanel) getContentPane();
JLabel progress_label = new JLabel(Dictionary.get("WriteCDImagePrompt.Progress_Label"));
JProgressBar progress_bar = new JProgressBar();
progress_bar.setIndeterminate(true);
content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
content_pane.setLayout(new BorderLayout());
content_pane.add(progress_label, BorderLayout.NORTH);
content_pane.add(progress_bar, BorderLayout.CENTER);
// Position
Rectangle frame_bounds = Gatherer.g_man.getBounds();
setLocation(frame_bounds.x + (frame_bounds.width - size.width) / 2, frame_bounds.y + (frame_bounds.height - size.height) / 2);
}
}
}
}