Skip to content

Commit bec9c92

Browse files
authored
Merge pull request #4 from code4teaching/cursor/open-strk-files-293e
iOS 1.5.3: .strk-Dateien öffnen
2 parents b502db1 + 24f3557 commit bec9c92

35 files changed

Lines changed: 106 additions & 25 deletions

‎CHANGELOG.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ The format is loosely inspired by Keep a Changelog.
1515
### Added
1616

1717
- **File menu:** New, Open, Open Recent, Save, Save As, Print, and Close on the menu bar / keyboard (`Cmd+N/O/S/Shift+S/P/W`), including on Mac (Designed for iPad). Open Recent uses the same list as the toolbar.
18-
- **Files:** double-click or Open With a `.visustruct` file in Finder / Files opens it in VisuStruct. The simulation layout is unchanged.
18+
- **Files:** double-click or Open With a `.visustruct` or `.strk` file in Finder / Files opens it in VisuStruct (same XML as the Java Struktogrammeditor). The simulation layout is unchanged.
1919

2020
### Fixed
2121

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Visual **Nassi–Shneiderman** structograms for **Mac, iPad, and iPhone**. Same
1414

1515
**[visustruct.org](https://visustruct.org)** · **Build & layout:** [VisuStruct-iOS/README.md](VisuStruct-iOS/README.md) · **Changes:** [CHANGELOG.md](CHANGELOG.md)
1616

17-
The **[Java VisuStruct](https://github.com/code4teaching/VisuStruct)** editor is based on [kekru/struktogrammeditor](https://github.com/kekru/struktogrammeditor) (MIT). **Sources and releases for Java** are maintained only in that repository (always current there). This **SwiftUI** app is a **reimplementation**: same **`.visustruct`** / XML as Java, not a port of that codebase.
17+
The **[Java VisuStruct](https://github.com/code4teaching/VisuStruct)** editor is based on [kekru/struktogrammeditor](https://github.com/kekru/struktogrammeditor) (MIT). **Sources and releases for Java** are maintained only in that repository (always current there). This **SwiftUI** app is a **reimplementation**: same **`.visustruct`** / XML as Java (and it opens legacy **`.strk`** files), not a port of that codebase.
1818

1919
---
2020

‎VisuStruct-iOS/README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ The open-source **[Java / Swing editor](https://github.com/code4teaching/VisuStr
4444
## Features (current)
4545

4646
- Tabs, palette, **drag & drop**, text inspector, undo/redo
47-
- Open / save **`.visustruct`**, share **PNG**, **print** where supported
47+
- Open **`.visustruct`** / **`.strk`**, save **`.visustruct`**, share **PNG**, **print** where supported
4848
- Broad **multi-language UI** coverage via **`Localizable.strings`** + **`Settings.bundle`** (English/German maintained as authoring sources; additional locales ship as translations).
4949
- **Clipboard actions** for diagram blocks (copy/cut/paste) plus keyboard/menu shortcuts where the platform supports first-class editing commands.
5050
- **Instruction modes** with uniform prefixes across languages:

‎VisuStruct-iOS/VisuStructCore/Package.swift‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ let package = Package(
1414
.target(
1515
name: "VisuStructCore",
1616
path: "Sources/VisuStructCore"
17+
),
18+
.testTarget(
19+
name: "VisuStructCoreTests",
20+
dependencies: ["VisuStructCore"],
21+
path: "Tests/VisuStructCoreTests"
1722
)
1823
]
1924
)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import XCTest
2+
import VisuStructCore
3+
4+
final class VisuStructXMLCodecTests: XCTestCase {
5+
func testDecodesLegacyStruktogrammeditorXML() throws {
6+
let xml = """
7+
<?xml version="1.0" encoding="UTF-8"?>
8+
<struktogramm caption="Beispiel">
9+
<strelem typ="0" zx="0" zy="0">
10+
<text>x = 1</text>
11+
</strelem>
12+
</struktogramm>
13+
"""
14+
let doc = try VisuStructXMLCodec.decode(data: Data(xml.utf8))
15+
XCTAssertEqual(doc.caption, "Beispiel")
16+
XCTAssertEqual(doc.elements.count, 1)
17+
XCTAssertEqual(doc.elements[0].type, .anweisung)
18+
XCTAssertEqual(doc.elements[0].textLines, ["x = 1"])
19+
}
20+
}

‎VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct.xcodeproj/project.pbxproj‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@
468468
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
469469
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
470470
CODE_SIGN_STYLE = Automatic;
471-
CURRENT_PROJECT_VERSION = 14;
471+
CURRENT_PROJECT_VERSION = 15;
472472
DEVELOPMENT_ASSET_PATHS = "";
473473
ENABLE_PREVIEWS = YES;
474474
GENERATE_INFOPLIST_FILE = YES;
@@ -503,7 +503,7 @@
503503
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
504504
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
505505
CODE_SIGN_STYLE = Automatic;
506-
CURRENT_PROJECT_VERSION = 14;
506+
CURRENT_PROJECT_VERSION = 15;
507507
DEVELOPMENT_ASSET_PATHS = "";
508508
ENABLE_PREVIEWS = YES;
509509
GENERATE_INFOPLIST_FILE = YES;

‎VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/About/AboutVisuStructView.swift‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ struct AboutVisuStructView: View {
9292
Text(lang.tr("about_dateiformat_heading"))
9393
.font(.headline)
9494
aboutDateiformatExplainer
95+
Text(lang.tr("about_dateiformat_strk"))
96+
.font(.subheadline)
97+
.foregroundStyle(.secondary)
9598
}
9699

97100
Divider()

‎VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/ContentView.swift‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,11 +128,10 @@ struct ContentView: View {
128128
)
129129
}
130130

131-
/// Finder / Dateien: Doppelklick bzw. „Öffnen mit“ auf `.visustruct`.
131+
/// Finder / Dateien: Doppelklick bzw. „Öffnen mit“ auf `.visustruct` oder `.strk`.
132132
private func openIncomingDocument(from url: URL) {
133133
guard url.isFileURL else { return }
134-
let ext = url.pathExtension.lowercased()
135-
guard ext == "visustruct" || ext == "xml" else { return }
134+
guard VisuStructDiagramFile.isOpenableDiagram(url: url) else { return }
136135
if isSimulationMode {
137136
endSimulationMode()
138137
}

‎VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/Documents/VisuStructFileDocuments.swift‎

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,42 @@ import SwiftUI
22
import UniformTypeIdentifiers
33
import VisuStructCore
44

5-
// MARK: - FileDocument (einheitlich .visustruct / XML wie Java)
5+
// MARK: - Dateiendungen (.visustruct nativ, .strk älterer Struktogrammeditor)
6+
7+
enum VisuStructDiagramFile {
8+
static let nativeFilenameExtension = "visustruct"
9+
static let legacyFilenameExtension = "strk"
10+
11+
static func isOpenableDiagram(url: URL) -> Bool {
12+
switch url.pathExtension.lowercased() {
13+
case nativeFilenameExtension, legacyFilenameExtension, "xml":
14+
return true
15+
default:
16+
return false
17+
}
18+
}
19+
20+
static func stripKnownExtension(from name: String) -> String {
21+
let trimmed = name.trimmingCharacters(in: .whitespacesAndNewlines)
22+
let lower = trimmed.lowercased()
23+
for suffix in [".\(nativeFilenameExtension)", ".\(legacyFilenameExtension)"] {
24+
if lower.hasSuffix(suffix) {
25+
return String(trimmed.dropLast(suffix.count)).trimmingCharacters(in: .whitespacesAndNewlines)
26+
}
27+
}
28+
return trimmed
29+
}
30+
}
31+
32+
// MARK: - FileDocument (einheitlich .visustruct / XML wie Java; .strk lesbar)
633

734
struct VisuStructFileDocument: FileDocument, Sendable {
835
/// Export/Speichern: eigene Endung, damit der Dialog nicht zusätzlich `.xml` anhängt.
936
static var preferredExportContentType: UTType {
1037
if let declared = UTType("org.visustruct.diagram") {
1138
return declared
1239
}
13-
if let v = UTType(filenameExtension: "visustruct") {
40+
if let v = UTType(filenameExtension: VisuStructDiagramFile.nativeFilenameExtension) {
1441
return v
1542
}
1643
return .xml
@@ -20,13 +47,25 @@ struct VisuStructFileDocument: FileDocument, Sendable {
2047
var types: [UTType] = [.xml]
2148
if let declared = UTType("org.visustruct.diagram") {
2249
types.insert(declared, at: 0)
23-
} else if let v = UTType(filenameExtension: "visustruct") {
50+
} else if let v = UTType(filenameExtension: VisuStructDiagramFile.nativeFilenameExtension) {
2451
types.insert(v, at: 0)
2552
}
53+
if let strk = UTType(filenameExtension: VisuStructDiagramFile.legacyFilenameExtension),
54+
!types.contains(strk) {
55+
types.insert(strk, at: min(1, types.count))
56+
}
2657
return types
2758
}
2859

29-
static var writableContentTypes: [UTType] { readableContentTypes }
60+
static var writableContentTypes: [UTType] {
61+
var types: [UTType] = [.xml]
62+
if let declared = UTType("org.visustruct.diagram") {
63+
types.insert(declared, at: 0)
64+
} else if let v = UTType(filenameExtension: VisuStructDiagramFile.nativeFilenameExtension) {
65+
types.insert(v, at: 0)
66+
}
67+
return types
68+
}
3069

3170
var document: VisuStructDocument
3271

‎VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/Export/DiagramSnapshotAndExport.swift‎

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,7 @@ enum DiagramExportFilename {
88
/// Gleiche Semantik wie `DiagramSheetTabsModel.stripVisuStructExtension` — hier freistehend,
99
/// damit Dateinamen-Helfer nicht `@MainActor`-isolierte Typen aufrufen müssen.
1010
private static func stripVisuStructExtension(from name: String) -> String {
11-
let t = name.trimmingCharacters(in: .whitespacesAndNewlines)
12-
let suffix = ".visustruct"
13-
if t.lowercased().hasSuffix(suffix) {
14-
return String(t.dropLast(suffix.count)).trimmingCharacters(in: .whitespacesAndNewlines)
15-
}
16-
return t
11+
VisuStructDiagramFile.stripKnownExtension(from: name)
1712
}
1813

1914
/// Vorschlag für „Speichern unter …“ / Teilen — je nach Einstellung nur Titel oder `yyyy-MM-dd-<Titel>`.

0 commit comments

Comments
 (0)