diff --git a/com.wudsn.ide.dsk/.classpath b/com.wudsn.ide.dsk/.classpath
new file mode 100644
index 00000000..e902f483
--- /dev/null
+++ b/com.wudsn.ide.dsk/.classpath
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/com.wudsn.ide.dsk/.project b/com.wudsn.ide.dsk/.project
new file mode 100644
index 00000000..194097fa
--- /dev/null
+++ b/com.wudsn.ide.dsk/.project
@@ -0,0 +1,28 @@
+
+
+ com.wudsn.ide.dsk
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+
+ org.eclipse.pde.PluginNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/com.wudsn.ide.dsk/.settings/org.eclipse.jdt.core.prefs b/com.wudsn.ide.dsk/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000..54e493c0
--- /dev/null
+++ b/com.wudsn.ide.dsk/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/com.wudsn.ide.dsk/META-INF/MANIFEST.MF b/com.wudsn.ide.dsk/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..3aaac19a
--- /dev/null
+++ b/com.wudsn.ide.dsk/META-INF/MANIFEST.MF
@@ -0,0 +1,17 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: WUDSN IDE Disk Images Plug-in
+Bundle-SymbolicName: com.wudsn.ide.dsk;singleton:=true
+Bundle-Version: 1.7.0.qualifier
+Bundle-Activator: com.wudsn.ide.dsk.DiskPlugin
+Bundle-Vendor: Peter Dell
+Require-Bundle: org.eclipse.core.resources,
+ org.eclipse.core.runtime,
+ org.eclipse.ui,
+ org.eclipse.ui.ide,
+ com.wudsn.ide.base;visibility:=reexport
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Bundle-ActivationPolicy: lazy
+Export-Package: com.webcodepro.applecommander.storage
+Bundle-ClassPath: lib/AppleCommander-1.3.5.14.jar,
+ .
diff --git a/com.wudsn.ide.dsk/OSGI-INF/l10n/bundle.properties b/com.wudsn.ide.dsk/OSGI-INF/l10n/bundle.properties
new file mode 100644
index 00000000..022aeefa
--- /dev/null
+++ b/com.wudsn.ide.dsk/OSGI-INF/l10n/bundle.properties
@@ -0,0 +1,5 @@
+#
+# Hardware: APPLE2
+#
+com.wudsn.ide.dsk.apple2.Apple2DiskImageFile.name=Apple II Disk Image
+com.wudsn.ide.dsk.apple2.Apple2DiskImageEditor.name=Apple II Disk Image Editor
diff --git a/com.wudsn.ide.dsk/OSGI-INF/l10n/bundle_de_DE.properties b/com.wudsn.ide.dsk/OSGI-INF/l10n/bundle_de_DE.properties
new file mode 100644
index 00000000..022aeefa
--- /dev/null
+++ b/com.wudsn.ide.dsk/OSGI-INF/l10n/bundle_de_DE.properties
@@ -0,0 +1,5 @@
+#
+# Hardware: APPLE2
+#
+com.wudsn.ide.dsk.apple2.Apple2DiskImageFile.name=Apple II Disk Image
+com.wudsn.ide.dsk.apple2.Apple2DiskImageEditor.name=Apple II Disk Image Editor
diff --git a/com.wudsn.ide.dsk/bin/.gitignore b/com.wudsn.ide.dsk/bin/.gitignore
new file mode 100644
index 00000000..43e58b99
--- /dev/null
+++ b/com.wudsn.ide.dsk/bin/.gitignore
@@ -0,0 +1 @@
+/com
diff --git a/com.wudsn.ide.dsk/build.properties b/com.wudsn.ide.dsk/build.properties
new file mode 100644
index 00000000..a522260d
--- /dev/null
+++ b/com.wudsn.ide.dsk/build.properties
@@ -0,0 +1,15 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ icons/,\
+ build.properties,\
+ src/,\
+ .classpath,\
+ .project,\
+ OSGI-INF/l10n/bundle.properties,\
+ OSGI-INF/,\
+ lib/AppleDos.dsk,\
+ lib/AppleCommander-1.3.5.14.jar
+
diff --git a/com.wudsn.ide.dsk/icons/editor-apple2-disk-image.gif b/com.wudsn.ide.dsk/icons/editor-apple2-disk-image.gif
new file mode 100644
index 00000000..a6978e34
Binary files /dev/null and b/com.wudsn.ide.dsk/icons/editor-apple2-disk-image.gif differ
diff --git a/com.wudsn.ide.dsk/lib/AppleCommander-1.3.5.14.jar b/com.wudsn.ide.dsk/lib/AppleCommander-1.3.5.14.jar
new file mode 100644
index 00000000..90d36810
Binary files /dev/null and b/com.wudsn.ide.dsk/lib/AppleCommander-1.3.5.14.jar differ
diff --git a/com.wudsn.ide.dsk/lib/AppleDos.dsk b/com.wudsn.ide.dsk/lib/AppleDos.dsk
new file mode 100644
index 00000000..98a30429
Binary files /dev/null and b/com.wudsn.ide.dsk/lib/AppleDos.dsk differ
diff --git a/com.wudsn.ide.dsk/plugin.xml b/com.wudsn.ide.dsk/plugin.xml
new file mode 100644
index 00000000..399dd410
--- /dev/null
+++ b/com.wudsn.ide.dsk/plugin.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/com.wudsn.ide.dsk/src/com/wudsn/ide/dsk/DiskPlugin.java b/com.wudsn.ide.dsk/src/com/wudsn/ide/dsk/DiskPlugin.java
new file mode 100644
index 00000000..bea5bb74
--- /dev/null
+++ b/com.wudsn.ide.dsk/src/com/wudsn/ide/dsk/DiskPlugin.java
@@ -0,0 +1,73 @@
+package com.wudsn.ide.dsk;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE 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.
+ *
+ * WUDSN IDE 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 WUDSN IDE. If not, see .
+ */
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class DiskPlugin extends AbstractUIPlugin {
+
+ /**
+ * The plugin id.
+ */
+ public static final String PLUGIN_ID = "com.wudsn.ide.dsk"; //$NON-NLS-1$
+
+ /**
+ * The shared instance.
+ */
+ private static DiskPlugin plugin;
+
+ /**
+ * The constructor
+ */
+ public DiskPlugin() {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Gets the shared plugin instance.
+ *
+ * @return The plug-in, not null
.
+ */
+ public static DiskPlugin getInstance() {
+ return plugin;
+ }
+
+}
diff --git a/com.wudsn.ide.dsk/src/com/wudsn/ide/dsk/Texts.java b/com.wudsn.ide.dsk/src/com/wudsn/ide/dsk/Texts.java
new file mode 100644
index 00000000..63719f29
--- /dev/null
+++ b/com.wudsn.ide.dsk/src/com/wudsn/ide/dsk/Texts.java
@@ -0,0 +1,40 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE 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.
+ *
+ * WUDSN IDE 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 WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.dsk;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Class which holds the localized text constants.
+ *
+ * @author Peter Dell
+ */
+public final class Texts extends NLS {
+
+ public static String MESSAGE_E100;
+ public static String MESSAGE_E101;
+
+ /**
+ * Initializes the constants.
+ */
+ static {
+ NLS.initializeMessages(Texts.class.getName(), Texts.class);
+ }
+}
diff --git a/com.wudsn.ide.dsk/src/com/wudsn/ide/dsk/Texts.properties b/com.wudsn.ide.dsk/src/com/wudsn/ide/dsk/Texts.properties
new file mode 100644
index 00000000..8c029410
--- /dev/null
+++ b/com.wudsn.ide.dsk/src/com/wudsn/ide/dsk/Texts.properties
@@ -0,0 +1,3 @@
+MESSAGE_E100=The editor input is not a file in the file system.
+MESSAGE_E101=The file is not a valid disk image.
+
diff --git a/com.wudsn.ide.dsk/src/com/wudsn/ide/dsk/Texts_de_DE.properties b/com.wudsn.ide.dsk/src/com/wudsn/ide/dsk/Texts_de_DE.properties
new file mode 100644
index 00000000..b0b5765b
--- /dev/null
+++ b/com.wudsn.ide.dsk/src/com/wudsn/ide/dsk/Texts_de_DE.properties
@@ -0,0 +1,2 @@
+MESSAGE_E100=Die Eingabe für den Editor ist keine Datei im Dateisystem.
+MESSAGE_E101=Die Datei ist kein gültiges Diskettenimage.
\ No newline at end of file
diff --git a/com.wudsn.ide.dsk/src/com/wudsn/ide/dsk/apple2/Apple2DiskImageEditor.java b/com.wudsn.ide.dsk/src/com/wudsn/ide/dsk/apple2/Apple2DiskImageEditor.java
new file mode 100644
index 00000000..68f58f69
--- /dev/null
+++ b/com.wudsn.ide.dsk/src/com/wudsn/ide/dsk/apple2/Apple2DiskImageEditor.java
@@ -0,0 +1,224 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE 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.
+ *
+ * WUDSN IDE 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 WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.dsk.apple2;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CTabFolder;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IPathEditorInput;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.part.EditorPart;
+
+import com.webcodepro.applecommander.storage.Disk;
+import com.webcodepro.applecommander.storage.FormattedDisk;
+import com.webcodepro.applecommander.ui.swt.DiskExplorerTab;
+import com.webcodepro.applecommander.ui.swt.DiskInfoTab;
+import com.webcodepro.applecommander.ui.swt.DiskMapTab;
+import com.webcodepro.applecommander.ui.swt.DiskWindow;
+import com.webcodepro.applecommander.ui.swt.util.ImageManager;
+import com.wudsn.ide.base.common.FileUtility;
+import com.wudsn.ide.base.common.StringUtility;
+import com.wudsn.ide.dsk.Texts;
+
+/**
+ * Editor wrapper for AppleCommander. This version is tweaked to correctly run
+ * with the SWT version included in AppleCommander-1.3.5.jar.
+ *
+ * @author Peter Dell
+ * @since 1.6.3
+ */
+public final class Apple2DiskImageEditor extends EditorPart {
+
+ private static class DummyDiskWindow extends DiskWindow {
+
+ public DummyDiskWindow() {
+ super(null, null, null);
+ }
+
+ @Override
+ public void setStandardWindowTitle() {
+
+ }
+
+ }
+
+ private ImageManager imageManager;
+ private CTabFolder tabFolder;
+ private DiskExplorerTab diskExplorerTab;
+ private DiskMapTab[] diskMapTabs;
+ private DiskInfoTab diskInfoTab;
+
+ private String diskImageFilePath;
+
+ public Apple2DiskImageEditor() {
+ }
+
+ @Override
+ public void doSave(IProgressMonitor monitor) {
+
+ }
+
+ @Override
+ public void doSaveAs() {
+
+ }
+
+ @Override
+ public void init(IEditorSite site, IEditorInput input)
+ throws PartInitException {
+ // Clear fields.
+ File ioFile;
+ IFile iFile;
+ ioFile = null;
+ iFile = null;
+
+ setSite(site);
+ setInput(input);
+
+ String fileName = "";
+ if (input instanceof IFileEditorInput) {
+ // Input file found in Eclipse Workspace.
+ iFile = ((IFileEditorInput) input).getFile();
+ ioFile = iFile.getRawLocation().toFile();
+ fileName = iFile.getName();
+ } else if (input instanceof IPathEditorInput) {
+ // Input file is outside the Eclipse Workspace
+ IPathEditorInput pathEditorInput = (IPathEditorInput) input;
+ IPath path = pathEditorInput.getPath();
+ ioFile = path.toFile();
+ fileName = ioFile.getName();
+
+ } else {
+ // Not supported.
+ }
+
+ setPartName(fileName);
+ if (ioFile != null) {
+ diskImageFilePath = FileUtility.getCanonicalFile(ioFile).getPath();
+ } else {
+ diskImageFilePath = "";
+ }
+ }
+
+ @Override
+ public boolean isDirty() {
+ return false;
+ }
+
+ @Override
+ public boolean isSaveAsAllowed() {
+ return false;
+ }
+
+ @Override
+ public void createPartControl(Composite parent) {
+ FormattedDisk[] formattedDisks;
+ String errorText;
+
+ formattedDisks = new FormattedDisk[0];
+ errorText = null;
+ if (StringUtility.isEmpty(diskImageFilePath)) {
+ // ERROR: The editor input is not a file in the file system.
+ errorText = Texts.MESSAGE_E100;
+
+ } else {
+
+ try {
+ Disk disk = new Disk(diskImageFilePath);
+ formattedDisks = disk.getFormattedDisks();
+ if (formattedDisks.length == 0) {
+ // ERROOR: The file is not a valid disk image.
+ errorText = Texts.MESSAGE_E101;
+ }
+ } catch (IOException ex) {
+ errorText = ex.getMessage();
+
+ } catch (IllegalArgumentException ex) {
+ // Caused by
+ // com.webcodepro.applecommander.storage.Disk.isProdosFormat(Disk.java:379)
+ errorText = ex.getMessage();
+ } catch (ArrayIndexOutOfBoundsException ex) {
+ // Caused by
+ // com.webcodepro.applecommander.storage.Disk.isProdosFormat(Disk.java:379)
+ errorText = Texts.MESSAGE_E101;
+ }
+ }
+
+ if (errorText != null) {
+ Text text = new Text(parent, SWT.READ_ONLY);
+ text.setText(errorText);
+ return;
+ }
+
+ imageManager = new ImageManager(parent.getDisplay());
+ tabFolder = new CTabFolder(parent, SWT.BOTTOM);
+ diskExplorerTab = new DiskExplorerTab(tabFolder, formattedDisks,
+ imageManager, new DummyDiskWindow());
+ diskMapTabs = new DiskMapTab[formattedDisks.length];
+ for (int i = 0; i < formattedDisks.length; i++) {
+ if (formattedDisks[i].supportsDiskMap()) {
+ diskMapTabs[i] = new DiskMapTab(tabFolder, formattedDisks[i]);
+ }
+ }
+ diskInfoTab = new DiskInfoTab(tabFolder, formattedDisks);
+ tabFolder.setSelection(tabFolder.getItems()[0]);
+ }
+
+ @Override
+ public void setFocus() {
+ if (tabFolder != null) {
+ tabFolder.setFocus();
+ }
+ }
+
+ @Override
+ public void dispose() {
+ if (diskExplorerTab != null) {
+ diskExplorerTab.dispose();
+ diskExplorerTab = null;
+ }
+ if (diskMapTabs != null) {
+ for (int i = 0; i < diskMapTabs.length; i++) {
+ if (diskMapTabs[i] != null)
+ diskMapTabs[i].dispose();
+ }
+ diskMapTabs = null;
+ }
+ if (diskInfoTab != null) {
+ diskInfoTab.dispose();
+ diskInfoTab = null;
+ }
+ if (imageManager != null) {
+ imageManager.dispose();
+ imageManager = null;
+ }
+ }
+
+}