/* * 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 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 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; } }