/* * AppleCommander - An Apple ][ image utility. * Copyright (C) 2002 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 java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import com.webcodepro.applecommander.storage.AppleWorksWordProcessorFileFilter; import com.webcodepro.applecommander.storage.ApplesoftFileFilter; import com.webcodepro.applecommander.storage.BinaryFileFilter; import com.webcodepro.applecommander.storage.FileEntry; import com.webcodepro.applecommander.storage.FileEntryComparator; import com.webcodepro.applecommander.storage.FileFilter; import com.webcodepro.applecommander.storage.FormattedDisk; import com.webcodepro.applecommander.storage.GraphicsFileFilter; import com.webcodepro.applecommander.storage.IntegerBasicFileFilter; import com.webcodepro.applecommander.storage.TextFileFilter; import com.webcodepro.applecommander.storage.FormattedDisk.FileColumnHeader; import com.webcodepro.applecommander.ui.UserPreferences; 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.MenuAdapter; import org.eclipse.swt.events.MenuEvent; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.ToolBar; import org.eclipse.swt.widgets.ToolItem; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; /** * Build the Disk File tab for the Disk Window. *

* Date created: Nov 17, 2002 9:46:53 PM * @author: Rob Greene */ public class DiskExplorerTab { private Shell shell; private SashForm sashForm; private Tree directoryTree; private Table fileTable; private ToolBar toolBar; private ToolItem exportToolItem; private ToolItem importToolItem; private ToolItem deleteToolItem; private ImageManager imageManager; private UserPreferences userPreferences = UserPreferences.getInstance(); private FormattedDisk disk; private FileFilter fileFilter; private GraphicsFileFilter graphicsFilter = new GraphicsFileFilter(); private AppleWorksWordProcessorFileFilter awpFilter = new AppleWorksWordProcessorFileFilter(); 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 disk, ImageManager imageManager) { this.disk = disk; this.shell = tabFolder.getShell(); this.imageManager = imageManager; createFilesTab(tabFolder); } /** * Dispose of resources. */ public void dispose() { sashForm.dispose(); directoryTree.dispose(); fileTable.dispose(); exportToolItem.dispose(); importToolItem.dispose(); deleteToolItem.dispose(); toolBar.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("Files"); 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) { changeCurrentFormat(currentFormat); // minor hack } /** * Double-click handler. */ public void widgetDefaultSelected(SelectionEvent event) { Tree item = (Tree) event.getSource(); TreeItem[] treeItem = item.getSelection(); treeItem[0].setExpanded(!treeItem[0].getExpanded()); } }); fileTable = new Table(sashForm, SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER); fileTable.setHeaderVisible(true); sashForm.setWeights(new int[] {1,2}); TreeItem diskItem = new TreeItem(directoryTree, SWT.BORDER); diskItem.setText(disk.getDiskName()); diskItem.setData(disk); directoryTree.setSelection(new TreeItem[] { diskItem }); if (disk.canHaveDirectories()) { Iterator files = disk.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, entry); } } } computeColumnWidths(FormattedDisk.FILE_DISPLAY_STANDARD); computeColumnWidths(FormattedDisk.FILE_DISPLAY_NATIVE); computeColumnWidths(FormattedDisk.FILE_DISPLAY_DETAIL); formatChanged = true; fillFileTable(disk.getFiles()); } /** * Construct the popup menu for the directory table on the File tab. */ protected Menu createDirectoryPopupMenu() { Menu menu = new Menu(shell, SWT.POP_UP); MenuItem item = new MenuItem(menu, SWT.CASCADE); item.setText("Expand"); item.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { TreeItem[] treeItem = directoryTree.getSelection(); treeItem[0].setExpanded(true); } }); item.setEnabled(disk.canHaveDirectories()); item = new MenuItem(menu, SWT.CASCADE); item.setText("Collapse"); item.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { TreeItem[] treeItem = directoryTree.getSelection(); treeItem[0].setExpanded(false); } }); item.setEnabled(disk.canHaveDirectories()); item = new MenuItem(menu, SWT.SEPARATOR); item = new MenuItem(menu, SWT.CASCADE); item.setText("Expand All"); item.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { TreeItem[] treeItem = directoryTree.getSelection(); setDirectoryExpandedStates(treeItem[0], true); } }); item.setEnabled(disk.canHaveDirectories()); item = new MenuItem(menu, SWT.CASCADE); item.setText("Collapse All"); item.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { TreeItem[] treeItem = directoryTree.getSelection(); setDirectoryExpandedStates(treeItem[0], false); } }); item.setEnabled(disk.canHaveDirectories()); 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); MenuItem item = new MenuItem(menu, SWT.CASCADE); item.setText("Import..."); item.setEnabled(disk.canCreateFile() && disk.canWriteFileData()); item.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { // FIXME } }); item = new MenuItem(menu, SWT.CASCADE); item.setText("Export"); item.setEnabled(disk.canReadFileData()); item.setMenu(createFileExportMenu(SWT.DROP_DOWN)); item = new MenuItem(menu, SWT.SEPARATOR); item = new MenuItem(menu, SWT.CASCADE); item.setText("Delete..."); item.setEnabled(disk.canDeleteFile()); item.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { // FIXME } }); 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("Raw disk data..."); item.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { fileFilter = null; exportFile(null); } }); item = new MenuItem(menu, SWT.NONE); item.setText("Binary..."); item.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { fileFilter = new BinaryFileFilter(); exportFile(null); } }); item = new MenuItem(menu, SWT.NONE); item.setText("Applesoft Basic..."); item.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { fileFilter = new ApplesoftFileFilter(); exportFile(null); } }); item = new MenuItem(menu, SWT.NONE); item.setText("Integer Basic..."); item.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { fileFilter = new IntegerBasicFileFilter(); exportFile(null); } }); item = new MenuItem(menu, SWT.NONE); item.setText("ASCII Text..."); item.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { fileFilter = new TextFileFilter(); exportFile(null); } }); item = new MenuItem(menu, SWT.SEPARATOR); item = new MenuItem(menu, SWT.NONE); item.setText("AppleWorks WordProcessor File..."); item.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { fileFilter = awpFilter; exportFile(null); } }); item = new MenuItem(menu, SWT.CASCADE); item.setText("Rendering"); 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(awpFilter.isTextRendering()); subItems[1].setSelection(awpFilter.isHtmlRendering()); } }); item = new MenuItem(subMenu, SWT.RADIO); item.setText("Text"); item.addSelectionListener(new SelectionAdapter() { /** * Set the appropriate rendering style. */ public void widgetSelected(SelectionEvent event) { awpFilter.setRendering(AppleWorksWordProcessorFileFilter.RENDER_AS_TEXT); } }); item = new MenuItem(subMenu, SWT.RADIO); item.setText("HTML"); item.addSelectionListener(new SelectionAdapter() { /** * Set the appropriate rendering style. */ public void widgetSelected(SelectionEvent event) { awpFilter.setRendering(AppleWorksWordProcessorFileFilter.RENDER_AS_HTML); } }); item = new MenuItem(menu, SWT.SEPARATOR); item = new MenuItem(menu, SWT.NONE); item.setText("Graphics..."); item.setEnabled(graphicsFilter.isCodecAvailable()); item.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { fileFilter = graphicsFilter; exportFile(null); } }); // Add graphics mode item = new MenuItem(menu, SWT.CASCADE); item.setText("Mode"); item.setEnabled(graphicsFilter.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(graphicsFilter.isHiresBlackAndWhiteMode()); subItems[1].setSelection(graphicsFilter.isHiresColorMode()); subItems[2].setSelection(graphicsFilter.isDoubleHiresBlackAndWhiteMode()); subItems[3].setSelection(graphicsFilter.isDoubleHiresColorMode()); } }); item = new MenuItem(subMenu, SWT.RADIO); item.setText("Hi-Res B&W"); item.addSelectionListener(new SelectionAdapter() { /** * Set the appropriate graphics mode. */ public void widgetSelected(SelectionEvent event) { graphicsFilter.setMode(GraphicsFileFilter.MODE_HGR_BLACK_AND_WHITE); } }); item = new MenuItem(subMenu, SWT.RADIO); item.setText("Hi-Res Color"); item.addSelectionListener(new SelectionAdapter() { /** * Set the appropriate graphics mode. */ public void widgetSelected(SelectionEvent event) { graphicsFilter.setMode(GraphicsFileFilter.MODE_HGR_COLOR); } }); item = new MenuItem(subMenu, SWT.RADIO); item.setText("Double Hi-Res B&W"); item.addSelectionListener(new SelectionAdapter() { /** * Set the appropriate graphics mode. */ public void widgetSelected(SelectionEvent event) { graphicsFilter.setMode(GraphicsFileFilter.MODE_DHR_BLACK_AND_WHITE); } }); item = new MenuItem(subMenu, SWT.RADIO); item.setText("Double Hi-Res COLOR"); item.addSelectionListener(new SelectionAdapter() { /** * Set the appropriate graphics mode. */ public void widgetSelected(SelectionEvent event) { graphicsFilter.setMode(GraphicsFileFilter.MODE_DHR_COLOR); } }); // Add graphics formats, if any are defined. String[] formats = graphicsFilter.getFileExtensions(); if (formats != null && formats.length > 0) { item = new MenuItem(menu, SWT.CASCADE); item.setText("Format"); item.setEnabled(graphicsFilter.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= header.getMaximumWidth()) { headerWidths[i] = gc.stringExtent(header.getTitle()).x + gc.stringExtent("WW").x; } else { headerWidths[i] = gc.stringExtent("W").x * header.getMaximumWidth(); } } gc.dispose(); gc = null; columnWidths.put(new Integer(format), headerWidths); } /** * Preserve the column widths. */ protected void preserveColumnWidths() { TableColumn[] columns = fileTable.getColumns(); int[] widths = new int[columns.length]; for (int i=0; i 0) { exportToolItem.setEnabled(disk.canReadFileData()); importToolItem.setEnabled(disk.canCreateFile() && disk.canWriteFileData()); deleteToolItem.setEnabled(disk.canDeleteFile()); } else { exportToolItem.setEnabled(false); importToolItem.setEnabled(false); deleteToolItem.setEnabled(false); } } /** * Double-click handler. */ public void widgetDefaultSelected(SelectionEvent event) { // No action defined at this time } }); TableColumn column = null; List headers = disk.getFileColumnHeaders(currentFormat); int[] widths = (int[])columnWidths.get(new Integer(currentFormat)); for (int i=0; i