/*
* AppleCommander - An Apple ][ image utility.
* Copyright (C) 2002-2022 by Robert Greene
* robgreene at users.sourceforge.net
*
* 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.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.webcodepro.applecommander.ui.swt;
import com.webcodepro.applecommander.compiler.ApplesoftCompiler;
import com.webcodepro.applecommander.storage.FileFilter;
import com.webcodepro.applecommander.storage.*;
import com.webcodepro.applecommander.storage.FormattedDisk.FileColumnHeader;
import com.webcodepro.applecommander.storage.filters.*;
import com.webcodepro.applecommander.storage.os.prodos.ProdosDiskSizeDoesNotMatchException;
import com.webcodepro.applecommander.storage.os.prodos.ProdosFormatDisk;
import com.webcodepro.applecommander.storage.physical.*;
import com.webcodepro.applecommander.ui.ImportSpecification;
import com.webcodepro.applecommander.ui.UiBundle;
import com.webcodepro.applecommander.ui.UserPreferences;
import com.webcodepro.applecommander.ui.swt.util.DropDownSelectionListener;
import com.webcodepro.applecommander.ui.swt.util.ImageManager;
import com.webcodepro.applecommander.ui.swt.util.SwtUtil;
import com.webcodepro.applecommander.ui.swt.wizard.compilefile.CompileWizard;
import com.webcodepro.applecommander.ui.swt.wizard.exportfile.ExportWizard;
import com.webcodepro.applecommander.ui.swt.wizard.importfile.ImportWizard;
import com.webcodepro.applecommander.util.AppleUtil;
import com.webcodepro.applecommander.util.Host;
import com.webcodepro.applecommander.util.StreamUtil;
import com.webcodepro.applecommander.util.TextBundle;
import io.github.applecommander.applesingle.AppleSingle;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.printing.PrintDialog;
import org.eclipse.swt.printing.Printer;
import org.eclipse.swt.printing.PrinterData;
import org.eclipse.swt.widgets.*;
import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.*;
/**
* Build the Disk File tab for the Disk Window.
*
* Date created: Nov 17, 2002 9:46:53 PM
* @author Rob Greene
*
* Changed at: Dec 1, 2017
* @author Lisias Toledo
*/
public class DiskExplorerTab {
private static final char CTRL_C = 'C' - '@';
private static final char CTRL_D = 'D' - '@';
private static final char CTRL_E = 'E' - '@';
private static final char CTRL_I = 'I' - '@';
private static final char CTRL_P = 'P' - '@';
private static final char CTRL_S = 'S' - '@';
private static final char CTRL_V = 'V' - '@';
// These are given to us from DiskWindow
private Shell shell;
private ImageManager imageManager;
private DiskWindow diskWindow;
private FormattedDisk[] disks;
private SashForm sashForm;
private Tree directoryTree;
private Table fileTable;
private ToolBar toolBar;
private ToolItem standardFormatToolItem;
private ToolItem nativeFormatToolItem;
private ToolItem detailFormatToolItem;
private ToolItem showDeletedFilesToolItem;
private ToolItem exportToolItem;
private ToolItem importToolItem;
private ToolItem compileToolItem;
private ToolItem viewFileItem;
private ToolItem printToolItem;
private ToolItem deleteToolItem;
private ToolItem saveToolItem;
private ToolItem saveAsToolItem;
private ToolItem changeOrderToolItem;
private Menu changeImageOrderMenu;
private UserPreferences userPreferences = UserPreferences.getInstance();
private TextBundle textBundle = UiBundle.getInstance();
private FileFilter fileFilter;
private GraphicsFileFilter graphicsFilter = new GraphicsFileFilter();
private AppleWorksWordProcessorFileFilter awpFilter = new AppleWorksWordProcessorFileFilter();
private GutenbergFileFilter gutenbergFilter = new GutenbergFileFilter();
private int currentFormat = FormattedDisk.FILE_DISPLAY_STANDARD;
private boolean formatChanged;
private List currentFileList;
private Map columnWidths = new HashMap<>();
private boolean showDeletedFiles;
/**
* Create the DISK INFO tab.
*/
public DiskExplorerTab(CTabFolder tabFolder, FormattedDisk[] disks, ImageManager imageManager, DiskWindow diskWindow) {
this.disks = disks;
this.shell = tabFolder.getShell();
this.imageManager = imageManager;
this.diskWindow = diskWindow;
createFilesTab(tabFolder);
}
/**
* Dispose of resources.
*/
public void dispose() {
sashForm.dispose();
directoryTree.dispose();
fileTable.dispose();
standardFormatToolItem.dispose();
nativeFormatToolItem.dispose();
detailFormatToolItem.dispose();
showDeletedFilesToolItem.dispose();
exportToolItem.dispose();
importToolItem.dispose();
deleteToolItem.dispose();
compileToolItem.dispose();
viewFileItem.dispose();
toolBar.dispose();
changeOrderToolItem.dispose();
directoryTree = null;
fileTable = null;
currentFileList = null;
}
/**
* Create the FILES tab.
*/
protected void createFilesTab(CTabFolder tabFolder) {
CTabItem ctabitem = new CTabItem(tabFolder, SWT.NULL);
ctabitem.setText(textBundle.get("FilesTab")); //$NON-NLS-1$
Composite composite = new Composite(tabFolder, SWT.NULL);
ctabitem.setControl(composite);
GridLayout gridLayout = new GridLayout(1, false);
composite.setLayout(gridLayout);
GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
createFileToolBar(composite, gridData);
sashForm = new SashForm(composite, SWT.NONE);
sashForm.setOrientation(SWT.HORIZONTAL);
gridData = new GridData(GridData.FILL_BOTH);
gridData.horizontalSpan = 2;
sashForm.setLayoutData(gridData);
directoryTree = new Tree(sashForm, SWT.SINGLE | SWT.BORDER);
directoryTree.setMenu(createDirectoryPopupMenu());
directoryTree.addSelectionListener(new SelectionListener() {
/**
* Single-click handler.
*/
public void widgetSelected(SelectionEvent event) {
try {
changeCurrentFormat(getCurrentFormat()); // minor hack
} catch (DiskException e) {
DiskExplorerTab.this.diskWindow.handle(e);
}
}
/**
* Double-click handler.
*/
public void widgetDefaultSelected(SelectionEvent event) {
Tree item = (Tree) event.getSource();
TreeItem[] treeItem = item.getSelection();
treeItem[0].setExpanded(!treeItem[0].getExpanded());
}
});
directoryTree.addListener(SWT.KeyUp, createDirectoryKeyboardHandler());
directoryTree.addListener(SWT.KeyUp, createToolbarCommandHandler());
fileTable = new Table(sashForm, SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER);
fileTable.setHeaderVisible(true);
sashForm.setWeights(new int[] {1,2});
for (int i=0; i files = disks[i].getFiles().iterator();
while (files.hasNext()) {
FileEntry entry = (FileEntry) files.next();
if (entry.isDirectory()) {
TreeItem item = new TreeItem(diskItem, SWT.BORDER);
item.setText(entry.getFilename());
item.setData(entry);
addDirectoriesToTree(item, (DirectoryEntry)entry);
}
}
} catch (DiskException e) {
this.diskWindow.handle(e);
}
}
}
computeColumnWidths(FormattedDisk.FILE_DISPLAY_STANDARD);
computeColumnWidths(FormattedDisk.FILE_DISPLAY_NATIVE);
computeColumnWidths(FormattedDisk.FILE_DISPLAY_DETAIL);
formatChanged = true;
try {
fillFileTable(disks[0].getFiles());
} catch (DiskException e) {
this.diskWindow.handle(e);
}
directoryTree.setSelection(new TreeItem[] { directoryTree.getItems()[0] });
}
/**
* Construct the popup menu for the directory table on the File tab.
* Using the first logical disk as the indicator for all logical disks.
*/
protected Menu createDirectoryPopupMenu() {
Menu menu = new Menu(shell, SWT.POP_UP);
MenuItem item = new MenuItem(menu, SWT.CASCADE);
item.setText(textBundle.get("ExpandMenuItem")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
TreeItem[] treeItem = getDirectoryTree().getSelection();
treeItem[0].setExpanded(true);
}
});
item.setEnabled(disks[0].canHaveDirectories());
item = new MenuItem(menu, SWT.CASCADE);
item.setText(textBundle.get("CollapseMenuItem")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
TreeItem[] treeItem = getDirectoryTree().getSelection();
treeItem[0].setExpanded(false);
}
});
item.setEnabled(disks[0].canHaveDirectories());
item = new MenuItem(menu, SWT.SEPARATOR);
item = new MenuItem(menu, SWT.CASCADE);
item.setText(textBundle.get("ExpandAllMenuItem")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
TreeItem[] treeItem = getDirectoryTree().getSelection();
setDirectoryExpandedStates(treeItem[0], true);
}
});
item.setEnabled(disks[0].canHaveDirectories());
item = new MenuItem(menu, SWT.CASCADE);
item.setText(textBundle.get("CollapseAllMenuItem")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
TreeItem[] treeItem = getDirectoryTree().getSelection();
setDirectoryExpandedStates(treeItem[0], false);
}
});
item.setEnabled(disks[0].canHaveDirectories());
item = new MenuItem(menu, SWT.SEPARATOR);
item = new MenuItem(menu, SWT.CASCADE);
item.setText(textBundle.get("CreateDirectoryMenuItem")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
// FIXME need to create directory
}
});
item.setEnabled(disks[0].canCreateDirectories());
item = new MenuItem(menu, SWT.SEPARATOR);
item = new MenuItem(menu, SWT.CASCADE);
item.setText(textBundle.get("ImportMenuItem")); //$NON-NLS-1$
item.setImage(imageManager.get(ImageManager.ICON_IMPORT_FILE));
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
try {
importFiles();
} catch (DiskException e) {
DiskExplorerTab.this.diskWindow.handle(e);
}
}
});
item.setEnabled(disks[0].canCreateFile() && disks[0].canWriteFileData());
return menu;
}
/**
* Construct the popup menu for the file table on the File tab.
*/
protected Menu createFilePopupMenu() {
Menu menu = new Menu(shell, SWT.POP_UP);
menu.addMenuListener(new MenuAdapter() {
/**
* Toggle all sub-menu MenuItems to the proper state to reflect
* the current file extension chosen.
*/
public void menuShown(MenuEvent event) {
Menu theMenu = (Menu) event.getSource();
MenuItem[] subItems = theMenu.getItems();
FileEntry fileEntry = getSelectedFileEntry();
// View File
subItems[0].setEnabled(getDisk(0).canReadFileData()
&& fileEntry != null && !fileEntry.isDeleted()
&& !fileEntry.isDirectory());
subItems[1].setEnabled(getDisk(0).canReadFileData()
&& fileEntry != null && !fileEntry.isDeleted()
&& !fileEntry.isDirectory());
// Compile File
subItems[3].setEnabled(getDisk(0).canReadFileData()
&& fileEntry != null && fileEntry.canCompile()
&& !fileEntry.isDeleted());
// Export File
subItems[5].setEnabled(getDisk(0).canReadFileData()
&& fileEntry != null && !fileEntry.isDeleted()
&& !fileEntry.isDirectory());
subItems[6].setEnabled(getDisk(0).canReadFileData()
&& fileEntry != null && !fileEntry.isDeleted()
&& !fileEntry.isDirectory());
// Delete File
subItems[8].setEnabled(getDisk(0).canDeleteFile()
&& fileEntry != null && !fileEntry.isDeleted());
}
});
MenuItem item = new MenuItem(menu, SWT.CASCADE);
item.setText(textBundle.get("ViewWizardMenuItem")); //$NON-NLS-1$
item.setAccelerator(SWT.CTRL+'V');
item.setImage(imageManager.get(ImageManager.ICON_VIEW_FILE));
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
try {
viewFile(null);
} catch (DiskException e) {
DiskExplorerTab.this.diskWindow.handle(e);
}
}
});
item = new MenuItem(menu, SWT.CASCADE);
item.setText(textBundle.get("ViewAsMenuItem")); //$NON-NLS-1$
item.setMenu(createFileViewMenu(SWT.DROP_DOWN));
item = new MenuItem(menu, SWT.SEPARATOR);
item = new MenuItem(menu, SWT.CASCADE);
item.setText(textBundle.get("CompileMenuItem")); //$NON-NLS-1$
item.setAccelerator(SWT.CTRL+'C');
item.setImage(imageManager.get(ImageManager.ICON_COMPILE_FILE));
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
compileFileWizard();
}
});
item = new MenuItem(menu, SWT.SEPARATOR);
item = new MenuItem(menu, SWT.CASCADE);
item.setText(textBundle.get("ExportWizardMenuItem")); //$NON-NLS-1$
item.setAccelerator(SWT.CTRL+'E');
item.setImage(imageManager.get(ImageManager.ICON_EXPORT_FILE));
item = new MenuItem(menu, SWT.CASCADE);
item.setText(textBundle.get("ExportAsMenuItem")); //$NON-NLS-1$
item.setMenu(createFileExportMenu(SWT.DROP_DOWN));
item = new MenuItem(menu, SWT.SEPARATOR);
item = new MenuItem(menu, SWT.CASCADE);
item.setText(textBundle.get("DeleteMenuItem")); //$NON-NLS-1$
item.setAccelerator(SWT.CTRL+'D');
item.setImage(imageManager.get(ImageManager.ICON_DELETE_FILE));
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
deleteFile();
}
});
return menu;
}
/**
* Construct the popup menu for the view as right-click option.
*/
protected Menu createFileViewMenu(int style) {
Menu menu = new Menu(shell, style);
MenuItem item = new MenuItem(menu, SWT.NONE);
item.setText(textBundle.get("ViewAsTextMenuItem")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
try {
viewFile(TextFileFilter.class);
} catch (DiskException e) {
DiskExplorerTab.this.diskWindow.handle(e);
}
}
});
item = new MenuItem(menu, SWT.NONE);
item.setText(textBundle.get("VeiwAsGraphicsMenuItem")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
try {
viewFile(GraphicsFileFilter.class);
} catch (DiskException e) {
DiskExplorerTab.this.diskWindow.handle(e);
}
}
});
return menu;
}
/**
* Construct the popup menu for the export button on the toolbar.
*/
protected Menu createFileExportMenu(int style) {
Menu menu = new Menu(shell, style);
MenuItem item = new MenuItem(menu, SWT.NONE);
item.setText(textBundle.get("ExportAsRawDiskDataMenuItem")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
setFileFilter(null);
exportFile(null);
}
});
item = new MenuItem(menu, SWT.NONE);
item.setText(textBundle.get("ExportAsBinaryMenuItem")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
setFileFilter(new BinaryFileFilter());
exportFile(null);
}
});
item = new MenuItem(menu, SWT.NONE);
item.setText(textBundle.get("ExportAsApplesoftBasicMenuItem")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
setFileFilter(new ApplesoftFileFilter());
exportFile(null);
}
});
item = new MenuItem(menu, SWT.NONE);
item.setText(textBundle.get("ExportAsIntegerBasicMenuItem")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
setFileFilter(new IntegerBasicFileFilter());
exportFile(null);
}
});
item = new MenuItem(menu, SWT.NONE);
item.setText(textBundle.get("ExportAsBusinessBASICMenuItem")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
setFileFilter(new BusinessBASICFileFilter());
exportFile(null);
}
});
item = new MenuItem(menu, SWT.NONE);
item.setText(textBundle.get("ExportAsAsciiTextMenuItem")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
setFileFilter(new TextFileFilter());
exportFile(null);
}
});
item = new MenuItem(menu, SWT.NONE);
item.setText(textBundle.get("ExportAsFormattedAssemblyMenuItem")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
setFileFilter(new AssemblySourceFileFilter());
exportFile(null);
}
});
item = new MenuItem(menu, SWT.NONE);
item.setText(textBundle.get("ExportAsPascalTextMenuItem")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
setFileFilter(new PascalTextFileFilter());
exportFile(null);
}
});
item = new MenuItem(menu, SWT.CASCADE);
item.setText(textBundle.get("GutenbergRenderingMenuItem")); //$NON-NLS-1$
Menu subMenu2 = new Menu(shell, SWT.DROP_DOWN);
item.setMenu(subMenu2);
item = new MenuItem(subMenu2, SWT.NONE);
item.setText(textBundle.get("WordProcessorRenderAsTextMenuItem")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
/**
* Set the appropriate rendering style.
*/
public void widgetSelected(SelectionEvent event) {
getGutenbergFilter().selectTextRendering();
setFileFilter(getGutenbergFilter());
exportFile(null);
}
});
item = new MenuItem(subMenu2, SWT.NONE);
item.setText(textBundle.get("WordProcessorRenderAsHtmlMenuItem")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
/**
* Set the appropriate rendering style.
*/
public void widgetSelected(SelectionEvent event) {
getGutenbergFilter().selectHtmlRendering();
setFileFilter(getGutenbergFilter());
exportFile(null);
}
});
item = new MenuItem(subMenu2, SWT.NONE);
item.setText(textBundle.get("WordProcessorRenderAsRtfMenuItem")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
/**
* Set the appropriate rendering style.
*/
public void widgetSelected(SelectionEvent event) {
getGutenbergFilter().selectRtfRendering();
setFileFilter(getGutenbergFilter());
exportFile(null);
}
});
item = new MenuItem(menu, SWT.NONE);
item.setText(textBundle.get("ExportAsAppleWorksSpreadsheetFileMenuItem")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
setFileFilter(new AppleWorksSpreadSheetFileFilter());
exportFile(null);
}
});
item = new MenuItem(menu, SWT.NONE);
item.setText(textBundle.get("ExportAsAppleWorksDatabaseFileMenuItem")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
setFileFilter(new AppleWorksDataBaseFileFilter());
exportFile(null);
}
});
item = new MenuItem(menu, SWT.SEPARATOR);
item = new MenuItem(menu, SWT.NONE);
item.setText(textBundle.get("ExportAsAppleWorksWordProcessorFileMenuItem")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
setFileFilter(getAwpFilter());
exportFile(null);
}
});
item = new MenuItem(menu, SWT.CASCADE);
item.setText(textBundle.get("WordProcessorRenderingMenuItem")); //$NON-NLS-1$
Menu subMenu = new Menu(shell, SWT.DROP_DOWN);
item.setMenu(subMenu);
subMenu.addMenuListener(new MenuAdapter() {
/**
* Toggle all sub-menu MenuItems to the proper state to reflect
* the current file extension chosen.
*/
public void menuShown(MenuEvent event) {
Menu theMenu = (Menu) event.getSource();
MenuItem[] subItems = theMenu.getItems();
subItems[0].setSelection(getAwpFilter().isTextRendering());
subItems[1].setSelection(getAwpFilter().isHtmlRendering());
subItems[2].setSelection(getAwpFilter().isRtfRendering());
}
});
item = new MenuItem(subMenu, SWT.RADIO);
item.setText(textBundle.get("WordProcessorRenderAsTextMenuItem")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
/**
* Set the appropriate rendering style.
*/
public void widgetSelected(SelectionEvent event) {
getAwpFilter().selectTextRendering();
}
});
item = new MenuItem(subMenu, SWT.RADIO);
item.setText(textBundle.get("WordProcessorRenderAsHtmlMenuItem")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
/**
* Set the appropriate rendering style.
*/
public void widgetSelected(SelectionEvent event) {
getAwpFilter().selectHtmlRendering();
}
});
item = new MenuItem(subMenu, SWT.RADIO);
item.setText(textBundle.get("WordProcessorRenderAsRtfMenuItem")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
/**
* Set the appropriate rendering style.
*/
public void widgetSelected(SelectionEvent event) {
getAwpFilter().selectRtfRendering();
}
});
item = new MenuItem(menu, SWT.SEPARATOR);
item = new MenuItem(menu, SWT.NONE);
item.setText(textBundle.get("ExportAsGraphicsMenuItem")); //$NON-NLS-1$
item.setEnabled(GraphicsFileFilter.isCodecAvailable());
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
setFileFilter(getGraphicsFilter());
exportFile(null);
}
});
// Add graphics mode
item = new MenuItem(menu, SWT.CASCADE);
item.setText(textBundle.get("ExportGraphicsModeMenuItem")); //$NON-NLS-1$
item.setEnabled(GraphicsFileFilter.isCodecAvailable());
subMenu = new Menu(shell, SWT.DROP_DOWN);
item.setMenu(subMenu);
subMenu.addMenuListener(new MenuAdapter() {
/**
* Toggle all sub-menu MenuItems to the proper state to reflect
* the current file extension chosen.
*/
public void menuShown(MenuEvent event) {
Menu theMenu = (Menu) event.getSource();
MenuItem[] subItems = theMenu.getItems();
subItems[0].setSelection(getGraphicsFilter().isHiresBlackAndWhiteMode());
subItems[1].setSelection(getGraphicsFilter().isHiresColorMode());
subItems[2].setSelection(getGraphicsFilter().isDoubleHiresBlackAndWhiteMode());
subItems[3].setSelection(getGraphicsFilter().isDoubleHiresColorMode());
subItems[4].setSelection(getGraphicsFilter().isSuperHires16Mode());
subItems[5].setSelection(getGraphicsFilter().isSuperHires3200Mode());
subItems[6].setSelection(getGraphicsFilter().isQuickDraw2Icon());
}
});
item = new MenuItem(subMenu, SWT.RADIO);
item.setText(textBundle.get("ExportGraphicsAsHiresBlackAndWhiteMenuItem")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
/**
* Set the appropriate graphics mode.
*/
public void widgetSelected(SelectionEvent event) {
getGraphicsFilter().setMode(GraphicsFileFilter.MODE_HGR_BLACK_AND_WHITE);
}
});
item = new MenuItem(subMenu, SWT.RADIO);
item.setText(textBundle.get("ExportGraphicsAsHiresColorMenuItem")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
/**
* Set the appropriate graphics mode.
*/
public void widgetSelected(SelectionEvent event) {
getGraphicsFilter().setMode(GraphicsFileFilter.MODE_HGR_COLOR);
}
});
item = new MenuItem(subMenu, SWT.RADIO);
item.setText(textBundle.get("ExportGraphicsAsDoubleHiresBlackAndWhiteMenuItem")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
/**
* Set the appropriate graphics mode.
*/
public void widgetSelected(SelectionEvent event) {
getGraphicsFilter().setMode(GraphicsFileFilter.MODE_DHR_BLACK_AND_WHITE);
}
});
item = new MenuItem(subMenu, SWT.RADIO);
item.setText(textBundle.get("ExportGraphicsAsDoubleHiresColorMenuItem")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
/**
* Set the appropriate graphics mode.
*/
public void widgetSelected(SelectionEvent event) {
getGraphicsFilter().setMode(GraphicsFileFilter.MODE_DHR_COLOR);
}
});
item = new MenuItem(subMenu, SWT.RADIO);
item.setText(textBundle.get("ExportGraphicsAsSuperHiresMenuItem")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
/**
* Set the appropriate graphics mode.
*/
public void widgetSelected(SelectionEvent event) {
getGraphicsFilter().setMode(GraphicsFileFilter.MODE_SHR_16);
}
});
item = new MenuItem(subMenu, SWT.RADIO);
item.setText(textBundle.get("ExportGraphicsAsSuperHires3200ColorMenuItem")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
/**
* Set the appropriate graphics mode.
*/
public void widgetSelected(SelectionEvent event) {
getGraphicsFilter().setMode(GraphicsFileFilter.MODE_SHR_3200);
}
});
item = new MenuItem(subMenu, SWT.RADIO);
item.setText(textBundle.get("ExportGraphicsAsQuickDraw2IconMenuItem")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
/**
* Set the appropriate graphics mode.
*/
public void widgetSelected(SelectionEvent event) {
getGraphicsFilter().setMode(GraphicsFileFilter.MODE_QUICKDRAW2_ICON);
}
});
// Add graphics formats, if any are defined.
String[] formats = GraphicsFileFilter.getFileExtensions();
if (formats != null && formats.length > 0) {
item = new MenuItem(menu, SWT.CASCADE);
item.setText(textBundle.get("ExportGraphicsFormatMenuItem")); //$NON-NLS-1$
item.setEnabled(GraphicsFileFilter.isCodecAvailable());
subMenu = new Menu(shell, SWT.DROP_DOWN);
item.setMenu(subMenu);
subMenu.addMenuListener(new MenuAdapter() {
/**
* Toggle all sub-menu MenuItems to the proper state to reflect
* the current file extension chosen.
*/
public void menuShown(MenuEvent event) {
Menu theMenu = (Menu) event.getSource();
MenuItem[] subItems = theMenu.getItems();
for (int i=0; i headers = disks[0].getFileColumnHeaders(format);
int[] headerWidths = new int[headers.size()];
GC gc = new GC(shell);
for (int i=0; i= header.getMaximumWidth()) {
headerWidths[i] = gc.stringExtent(header.getTitle()).x +
2 * gc.stringExtent(textBundle.get("WidestCharacter")).x; //$NON-NLS-1$
} else {
headerWidths[i] = gc.stringExtent(
textBundle.get("WidestCharacter")).x //$NON-NLS-1$
* header.getMaximumWidth();
}
}
gc.dispose();
gc = null;
columnWidths.put(Integer.valueOf(format), headerWidths);
}
/**
* Preserve the column widths.
*/
protected void preserveColumnWidths() {
TableColumn[] columns = fileTable.getColumns();
int[] widths = new int[columns.length];
for (int i=0; i fileList) {
int[] weights = sashForm.getWeights();
if (formatChanged) {
fileTable.dispose();
fileTable = new Table(sashForm, SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER);
fileTable.addListener(SWT.KeyUp, createFileKeyboardHandler());
fileTable.addListener(SWT.KeyUp, createToolbarCommandHandler());
fileTable.setHeaderVisible(true);
fileTable.setMenu(createFilePopupMenu());
fileTable.addSelectionListener(new SelectionListener() {
/**
* Single-click handler.
*/
public void widgetSelected(SelectionEvent event) {
getImportToolItem().setEnabled(getDisk(0).canCreateFile() && getDisk(0).canWriteFileData());
if (getFileTable().getSelectionCount() > 0) {
FileEntry fileEntry = getSelectedFileEntry();
getExportToolItem().setEnabled(getDisk(0).canReadFileData());
getDeleteToolItem().setEnabled(getDisk(0).canDeleteFile());
getCompileToolItem().setEnabled(fileEntry != null && fileEntry.canCompile());
getViewFileToolItem().setEnabled(true);
} else {
getExportToolItem().setEnabled(false);
getDeleteToolItem().setEnabled(false);
getCompileToolItem().setEnabled(false);
getViewFileToolItem().setEnabled(false);
}
}
/**
* Double-click handler.
*/
public void widgetDefaultSelected(SelectionEvent event) {
try {
viewFile(null);
} catch (DiskException e) {
DiskExplorerTab.this.diskWindow.handle(e);
}
}
});
TableColumn column = null;
List headers = disks[0].getFileColumnHeaders(currentFormat);
int[] widths = (int[])columnWidths.get(Integer.valueOf(currentFormat));
for (int i=0; i data = entry.getFileColumnData(currentFormat);
for (int i=0; i 1) ?
textBundle.get("DeletePromptMultipleFiles") : //$NON-NLS-1$
textBundle.get("DeletePromptSingleFile") //$NON-NLS-1$
+ textBundle.get("DeletePromptTrailer"); //$NON-NLS-1$
int answer = SwtUtil.showYesNoDialog(shell,
textBundle.get("DeletePromptTitle"), //$NON-NLS-1$
message);
if (answer == SWT.YES) {
for (int i=0; i specs = wizard.getImportSpecifications();
// Progress meter for import wizard:
dialog = new Shell(shell, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
dialog.setText(textBundle.get("ImportingFilesTitle")); //$NON-NLS-1$
GridLayout layout = new GridLayout();
layout.horizontalSpacing = 5;
layout.makeColumnsEqualWidth = false;
layout.marginHeight = 5;
layout.marginWidth = 5;
layout.numColumns = 2;
layout.verticalSpacing = 5;
dialog.setLayout(layout);
Label label = new Label(dialog, SWT.NONE);
label.setText(textBundle.get("ImportingFilesProcessingLabel")); //$NON-NLS-1$
Label countLabel = new Label(dialog, SWT.NONE);
GridData gridData = new GridData();
gridData.widthHint = 300;
countLabel.setLayoutData(gridData);
label = new Label(dialog, SWT.NONE);
label.setText(textBundle.get("ImportingFilesFilenameLabel")); //$NON-NLS-1$
Label nameLabel = new Label(dialog, SWT.NONE);
gridData = new GridData();
gridData.widthHint = 300;
nameLabel.setLayoutData(gridData);
gridData = new GridData(GridData.FILL_HORIZONTAL);
gridData.horizontalSpan = 2;
gridData.grabExcessHorizontalSpace = true;
ProgressBar progressBar = new ProgressBar(dialog, SWT.NONE);
progressBar.setLayoutData(gridData);
progressBar.setMinimum(0);
progressBar.setMaximum(specs.size());
dialog.pack();
SwtUtil.center(shell, dialog);
dialog.open();
// begin the import:
for (int i=0; i fileList = directory.getFiles();
formatChanged = (currentFormat != newFormat);
if (formatChanged || !fileList.equals(currentFileList)) {
preserveColumnWidths(); // must be done before assigning newFormat
currentFormat = newFormat;
fillFileTable(fileList);
// Ensure that the control buttons are set appropriately.
// Primarily required for keyboard interface.
standardFormatToolItem.setSelection(
currentFormat == FormattedDisk.FILE_DISPLAY_STANDARD);
nativeFormatToolItem.setSelection(
currentFormat == FormattedDisk.FILE_DISPLAY_NATIVE);
detailFormatToolItem.setSelection(
currentFormat == FormattedDisk.FILE_DISPLAY_DETAIL);
}
}
/**
* Handle SaveAs.
*/
protected void saveAs() {
FileDialog fileDialog = new FileDialog(shell, SWT.SAVE);
fileDialog.setFilterPath(userPreferences.getSaveDirectory());
fileDialog.setFileName(Host.getFileName(disks[0].getFilename()));
fileDialog.setText(textBundle.get("SaveDiskImageAsPrompt")); //$NON-NLS-1$
String fullpath = fileDialog.open();
if (fileDialog.getFilterPath() != null) {
userPreferences.setSaveDirectory(fileDialog.getFilterPath());
}
if (fullpath == null) {
return; // user pressed cancel
}
try {
disks[0].saveAs(fullpath);
diskWindow.setStandardWindowTitle();
saveToolItem.setEnabled(disks[0].hasChanged());
} catch (IOException ex) {
showSaveError(ex);
}
}
/**
* Handle save.
* If this is the first time a disk has been saved (a new image),
* default to the SaveAs behavior.
*/
protected void save() {
try {
if (disks[0].isNewImage()) {
saveAs(); // no directory -> assume a new/unsaved image
return;
}
disks[0].save();
saveToolItem.setEnabled(disks[0].hasChanged());
} catch (IOException ex) {
showSaveError(ex);
}
}
/**
* Display the Save error dialog box.
* @see #save
* @see #saveAs
*/
protected void showSaveError(IOException ex) {
Shell finalShell = shell;
String errorMessage = ex.getMessage();
if (errorMessage == null) {
errorMessage = ex.getClass().getName();
}
MessageBox box = new MessageBox(finalShell,
SWT.ICON_ERROR | SWT.CLOSE);
box.setText(textBundle.get("SaveDiskImageErrorTitle")); //$NON-NLS-1$
box.setMessage(textBundle.format("SaveDiskImageErrorMessage", //$NON-NLS-1$
getDisk(0).getFilename(), errorMessage));
box.open();
}
/**
* Create the keyboard handler for the directory pane.
* These are keys that are only active in the directory
* viewer. See createToolbarCommandHandler for the general application
* keyboard handler.
* @see #createToolbarCommandHandler
*/
private Listener createDirectoryKeyboardHandler() {
return new Listener() {
public void handleEvent(Event event) {
if (event.type == SWT.KeyUp) {
TreeItem[] treeItem = null;
if ((event.stateMask & SWT.CTRL) != 0) {
switch (event.character) {
case '-':
treeItem = getDirectoryTree().getSelection();
setDirectoryExpandedStates(treeItem[0], false);
break;
case '+':
treeItem = getDirectoryTree().getSelection();
setDirectoryExpandedStates(treeItem[0], true);
break;
}
} else { // assume no control and no alt
switch (event.character) {
case '-':
treeItem = getDirectoryTree().getSelection();
treeItem[0].setExpanded(false);
break;
case '+':
treeItem = getDirectoryTree().getSelection();
treeItem[0].setExpanded(true);
break;
}
}
}
}
};
}
/**
* Open up the view file window for the currently selected file.
* @throws DiskException
*/
protected void viewFile(Class extends FileFilter> fileFilterClass) throws DiskException {
FileEntry fileEntry = getSelectedFileEntry();
if (fileEntry.isDeleted()) {
SwtUtil.showErrorDialog(shell, textBundle.get("DeleteFileErrorTitle"), //$NON-NLS-1$
textBundle.get("DeleteFileErrorMessage")); //$NON-NLS-1$
} else if (fileEntry.isDirectory()) {
TreeItem item = findDirectoryItem(directoryTree.getSelection()[0].getItems(), fileEntry.getFilename(), 1, 0);
if (item != null) {
directoryTree.showItem(item);
directoryTree.setSelection(new TreeItem[] { item });
changeCurrentFormat(currentFormat); // minor hack
}
} else { // Assuming a normal file!
FileViewerWindow window = null;
FileFilter fileFilter = null;
try {
Constructor extends FileFilter> constructor = fileFilterClass.getConstructor();
fileFilter = constructor.newInstance();
} catch (NullPointerException ex) {
// This is expected
} catch (InstantiationException e) {
SwtUtil.showSystemErrorDialog(shell, e);
} catch (IllegalAccessException e) {
SwtUtil.showSystemErrorDialog(shell, e);
} catch (NoSuchMethodException e) {
SwtUtil.showSystemErrorDialog(shell, e);
} catch (SecurityException e) {
SwtUtil.showSystemErrorDialog(shell, e);
} catch (IllegalArgumentException e) {
SwtUtil.showSystemErrorDialog(shell, e);
} catch (InvocationTargetException e) {
SwtUtil.showSystemErrorDialog(shell, e);
}
if (fileFilter != null) {
window = new FileViewerWindow(shell, fileEntry, imageManager, fileFilter);
} else {
window = new FileViewerWindow(shell, fileEntry, imageManager);
}
window.open();
}
}
/**
* Locate a named item in the directory tree.
*/
protected TreeItem findDirectoryItem(TreeItem[] treeItems, String name, int maxDepth, int currentDepth) {
if (maxDepth == currentDepth) return null;
for (int i=0; ionly active in the file
* viewer. See createToolbarCommandHandler for the general application
* keyboard handler.
* @see #createToolbarCommandHandler
*/
private Listener createFileKeyboardHandler() {
return new Listener() {
public void handleEvent(Event event) {
FileEntry fileEntry = getSelectedFileEntry();
if (fileEntry != null && event.type == SWT.KeyUp && (event.stateMask & SWT.CTRL) != 0) {
try {
switch (event.character) {
case CTRL_C: // Compile Wizard
if (getCompileToolItem().isEnabled()) {
compileFileWizard();
}
break;
case CTRL_D: // Delete file
if (getDeleteToolItem().isEnabled()) {
deleteFile();
}
break;
case CTRL_E: // Export Wizard
exportFileWizard();
break;
case CTRL_V: // View file
viewFile(null);
break;
}
} catch (DiskException e) {
DiskExplorerTab.this.diskWindow.handle(e);
}
}
}
};
}
/**
* The toolbar command handler contains the global toolbar
* actions. This does not include file-specific actions.
* The intent is that the listener is then added to multiple
* visual components (i.e., the file listing as well as the
* directory listing).
*/
private Listener createToolbarCommandHandler() {
return new Listener() {
public void handleEvent(Event event) {
if (event.type == SWT.KeyUp) {
if ((event.stateMask & SWT.CTRL) != 0) { // CTRL key held
if ((event.stateMask & SWT.SHIFT) != 0) { // SHIFT key held
switch (event.character) {
case CTRL_S: // Save As...
saveAs();
break;
}
} else {
try {
switch (event.character) {
case CTRL_I: // Import Wizard
importFiles();
break;
case CTRL_P: // Print...
print();
break;
case CTRL_S: // Save
if (getSaveToolItem().isEnabled()) {
save();
}
break;
}
} catch (DiskException e) {
DiskExplorerTab.this.diskWindow.handle(e);
}
}
} else { // No CTRL key
if ((event.stateMask & SWT.ALT) != SWT.ALT) // Ignore ALT key combinations like alt-F4!
try {
switch (event.keyCode) {
case SWT.F2: // Standard file display
changeCurrentFormat(FormattedDisk.FILE_DISPLAY_STANDARD);
break;
case SWT.F3: // Native file display
changeCurrentFormat(FormattedDisk.FILE_DISPLAY_NATIVE);
break;
case SWT.F4: // Detail file display
changeCurrentFormat(FormattedDisk.FILE_DISPLAY_DETAIL);
break;
case SWT.F5: // Show deleted files
setShowDeletedFiles(!getShowDeletedFilesToolItem().getSelection());
getShowDeletedFilesToolItem().setSelection(isShowDeletedFiles());
fillFileTable(getCurrentFileList());
break;
}
} catch (DiskException e) {
DiskExplorerTab.this.diskWindow.handle(e);
}
}
}
}
};
}
/**
* Get the currently selected FileEntry. Note that this
* can return null if there are none selected. Also, if there
* are multiple files selected, this is not complete.
*/
protected FileEntry getSelectedFileEntry() {
FileEntry fileEntry = null;
if (fileTable.getSelectionIndex() >= 0) {
fileEntry = (FileEntry) fileTable.getItem(fileTable.getSelectionIndex()).getData();
}
return fileEntry;
}
/**
* Internal class that controls printing of a file listing.
*/
private class Printing implements Runnable {
private Printer printer;
private int y;
private int x;
private Rectangle clientArea;
private GC gc;
private List fileHeaders;
private int[] printColumnWidths;
private int[] printColumnPosition;
private Font normalFont;
private Font headerFont;
private String filename;
private int page = 1;
private int dpiY;
private int dpiX;
public Printing(Printer printer) {
this.printer = printer;
}
public void run() {
if (printer.startJob(getDisk(0).getFilename())) {
clientArea = printer.getClientArea();
dpiY = printer.getDPI().y;
dpiX = printer.getDPI().x;
// Setup 1" margin:
Rectangle trim = printer.computeTrim(0, 0, 0, 0);
clientArea.x = dpiX + trim.x;
clientArea.y = dpiY + trim.y;
clientArea.width -= (clientArea.x + trim.width);
clientArea.height -= (clientArea.y + trim.height);
// Set default values:
y = clientArea.y;
x = clientArea.x;
gc = new GC(printer);
int fontSize = 12;
if (getCurrentFormat() == FormattedDisk.FILE_DISPLAY_NATIVE) {
fontSize = 10;
} else if (getCurrentFormat() == FormattedDisk.FILE_DISPLAY_DETAIL) {
fontSize = 8;
}
normalFont = new Font(printer, new String(), fontSize, SWT.NORMAL);
headerFont = new Font(printer, new String(), fontSize, SWT.BOLD);
for (int i=0; i= header.getTitle().length()) ?
header.getMaximumWidth() : header.getTitle().length();
totalWidth+= widths[i];
}
printColumnWidths = new int[fileHeaders.size()];
printColumnPosition = new int[fileHeaders.size()];
int position = clientArea.x;
for (int i=0; i (clientArea.y + clientArea.height)) { // filled a page
printFooter();
printer.endPage();
y = clientArea.y;
}
}
protected void printHeader() {
Point point = gc.stringExtent(filename);
gc.drawString(filename,
clientArea.x + (clientArea.width - point.x)/2,
y - dpiY + point.y);
}
protected void printFooter() {
TextBundle textBundle = UiBundle.getInstance();
String text = textBundle.format("PageNumberText", page); //$NON-NLS-1$
Point point = gc.stringExtent(text);
gc.drawString(text,
clientArea.x + (clientArea.width - point.x)/2,
clientArea.y + clientArea.height + dpiY - point.y);
page++;
}
protected void printFiles(DirectoryEntry directory, int level) throws DiskException {
for (FileEntry fileEntry : directory.getFiles()) {
if (!fileEntry.isDeleted() || isShowDeletedFiles()) {
List columns = fileEntry.getFileColumnData(getCurrentFormat());
for (int i=0; i getCurrentFileList() {
return currentFileList;
}
protected ToolItem getSaveToolItem() {
return saveToolItem;
}
protected ToolItem getShowDeletedFilesToolItem() {
return showDeletedFilesToolItem;
}
}