feat: F4.6f3 the file explorer and the image viewer

Oracle FileExplorerWindowRun uses Java's explorer and viewer windows as a
person does (the right-click menu, Java's questions answered, the import
window, the viewer's open). Both windows work on the document's files
through the core's operations: the tree of folders and files, the chosen
folder's entries, Java's menu (also as buttons, no right click needed),
copy that stays and cut that goes once pasted, the import; the viewer's
picture and title. Not taken from Java: a file chosen in the tree taken
for a folder, pictures laid over each other, a text file as an empty
picture. writeFiles numbers the entries in the file system's order again
when a rename made a new key.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-03 18:13:22 +00:00
co-authored by Claude Opus 5.5
parent 2c7733b575
commit 3dc2713f81
21 changed files with 2951 additions and 39 deletions
+15 -1
View File
@@ -20,7 +20,8 @@
// is refused (Java makes such a file), a name with "/" leads into a
// folder (Java makes a file whose name holds the separator);
// - "open" opens text files only (Java shows an image as its Base64 text)
// and keeps the open file when it finds none (Java forgets it);
// and keeps the open file when it finds none (Java forgets it); the image
// viewer's opens images only (Java shows another file as an empty picture);
// - a text file's size is its length in characters (as the command line's).
import type { VirtualFileContent, VirtualFileSystem } from '../../model/virtualFileSystem.js';
@@ -259,6 +260,19 @@ export function openText(files: VirtualFileSystem, folder: string, name: string)
return entry.content.kind === 'text' ? { path: entry.path, text: entry.content.text } : 'notText';
}
/**
* The image viewer's "open" (holeDatei of the dialog's folder and name, as
* the editor's): an image file's path, bytes and media type. Java shows any
* file it finds — another as an empty picture —, and with none keeps what it
* shows; here a file that is not an image is notImage, none notFound.
*/
export function openImage(files: VirtualFileSystem, folder: string, name: string): { readonly path: string; readonly data: Uint8Array; readonly mediaType: string } | 'notFound' | 'notImage' {
// No name is the folder itself: not found.
const entry = found(files, evaluatedPath(name.startsWith('/') ? name : `${folder}/${name}`));
if (entry === undefined || entry.content.kind === 'directory') return 'notFound';
return entry.content.kind === 'image' ? { path: entry.path, data: entry.content.data, mediaType: entry.content.mediaType } : 'notImage';
}
/** The image viewer's "open": an image file's bytes and media type; none for any other file. */
export function imageFile(files: VirtualFileSystem, path: string): { readonly data: Uint8Array; readonly mediaType: string } | undefined {
const entry = found(files, path);
+15
View File
@@ -24,6 +24,7 @@ import {
saveText,
saveTextAs,
openText,
openImage,
VirtualFileSystem,
type Clipboard,
type PageLanguage,
@@ -265,4 +266,18 @@ describe('the file programs beyond the cases', () => {
expect(saveTextAs(files, '/', 'ORDNER', 'e')).toBe('isFolder');
expect(files.allEntries().map((entry) => entry.path)).toEqual(['/', '/ordner', '/ordner/d.txt']);
});
// Measured with FileExplorerWindowRun (packages/sim/test/fileExplorerWindow.java.json).
it("opens an image by the dialog's folder and name, in any case, and neither another file nor what is not there", () => {
const files = new VirtualFileSystem();
files.createDirectory('/webserver');
files.writeImageFile('/webserver/Bild.png', new Uint8Array([1, 2]), 'image/png');
files.writeTextFile('/text.txt', 'x');
expect(openImage(files, '/webserver', 'bild.PNG')).toEqual({ path: '/webserver/Bild.png', data: new Uint8Array([1, 2]), mediaType: 'image/png' });
expect(openImage(files, '/', 'webserver/Bild.png')).toEqual(openImage(files, '/text', '/webserver/Bild.png'));
expect(['fehlt.png', '', 'webserver'].map((name) => openImage(files, '/', name))).toEqual(['notFound', 'notFound', 'notFound']);
expect(openImage(files, '/', 'text.txt')).toBe('notImage');
files.writeBinaryFile('/daten.bin', new Uint8Array([3]));
expect(openImage(files, '/', 'daten.bin')).toBe('notImage');
});
});