feat(ui): drag-and-drop to open .nest files in Database mode

Open browses server records in Database mode, with no way to load a local
file. Dragging .nest files onto the window (or an open plate) now opens
them from disk in either storage mode; PlateView forwards file drops via a
new FilesDropped event instead of swallowing them, gated on having a
listener so other PlateView hosts are unaffected. A dropped document is
unbound, so Save in Database mode creates a new record on first save via
the existing storage-mode logic.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
ajandClaude Sonnet 5 committed 2026-10-05 14:50:36 -04:00
1 parent 3a9bd08f39
commit 3fc32e56e1
3 files changed
+60

No files matched your search

+14
View File
@@ -78,6 +78,12 @@ namespace OpenNest.Controls
public event EventHandler<ItemRemovedEventArgs<Part>> PartRemoved;
public event EventHandler StatusChanged;
/// <summary>
/// Raised when files are dropped on the plate and something is listening (see
/// <see cref="OnDragEnter"/>); callers decide which paths to act on.
/// </summary>
public event EventHandler<string[]> FilesDropped;
public event EventHandler SelectionChanged
{
add => selection.SelectionChanged += value;
@@ -305,10 +311,18 @@ namespace OpenNest.Controls
{
if (drgevent.Data.GetData(typeof(Drawing)) != null)
drgevent.Effect = DragDropEffects.Copy;
else if (FilesDropped != null && drgevent.Data.GetDataPresent(DataFormats.FileDrop))
drgevent.Effect = DragDropEffects.Copy;
}
protected override void OnDragDrop(DragEventArgs drgevent)
{
if (drgevent.Data.GetDataPresent(DataFormats.FileDrop))
{
FilesDropped?.Invoke(this, (string[])drgevent.Data.GetData(DataFormats.FileDrop));
return;
}
var dwg = drgevent.Data.GetData(typeof(Drawing)) as Drawing;
if (dwg == null)
+39
View File
@@ -69,6 +69,7 @@ namespace OpenNest.Forms
clickUpdateLocation = true;
this.SetBevel(false);
AllowDrop = true;
LoadPosts();
EnableCheck();
@@ -173,6 +174,7 @@ namespace OpenNest.Forms
if (remoteId != Guid.Empty)
editForm.Document.BindRemote(remoteId, serverUrl);
editForm.MdiParent = this;
editForm.PlateView.FilesDropped += (sender, paths) => OpenDroppedNestFiles(paths);
editForm.PlateChanged += (sender, e) =>
{
NavigationEnableCheck();
@@ -552,6 +554,43 @@ namespace OpenNest.Forms
Settings.Default.Save();
}
protected override void OnDragEnter(DragEventArgs e)
{
base.OnDragEnter(e);
e.Effect = HasDroppedNestFile(e.Data) ? DragDropEffects.Copy : DragDropEffects.None;
}
protected override void OnDragDrop(DragEventArgs e)
{
base.OnDragDrop(e);
if (e.Data.GetData(DataFormats.FileDrop) is string[] paths)
OpenDroppedNestFiles(paths);
}
private static bool HasDroppedNestFile(IDataObject data) =>
data.GetData(DataFormats.FileDrop) is string[] paths
&& paths.Any(path => string.Equals(
Path.GetExtension(path), NestFormat.FileExtension, StringComparison.OrdinalIgnoreCase));
/// <summary>
/// Opens dropped .nest files locally regardless of storage mode. Loaded documents are
/// not bound to a server record, so Save/Save As follow the normal storage-mode rules
/// (File mode writes to disk; Database mode creates a new record on first save).
/// </summary>
private void OpenDroppedNestFiles(IEnumerable<string> paths)
{
foreach (var path in paths)
{
if (!string.Equals(Path.GetExtension(path), NestFormat.FileExtension, StringComparison.OrdinalIgnoreCase))
continue;
var reader = new NestReader(path);
var nest = reader.Read();
LoadNest(nest);
ShowNestWarnings(reader);
}
}
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
base.OnClosing(e);
+7
View File
@@ -18,6 +18,13 @@ The desktop app can save nests two ways:
modes) for producing a local file to share or back up. Export does not change
the document's file save path or database record association.
Dragging one or more `.nest` files onto the main window (or onto an open
plate) opens them from disk directly, in either mode — this is the only way
to open a local file while in Database mode, since Open there browses server
records instead of showing a file dialog. A document opened this way is not
bound to a server record, so a subsequent Save in Database mode creates a new
record on first save, same as any other unbound document.
The mode and server address are stored per-PC at `%APPDATA%\OpenNest\storage.json`
(`OpenNest.Data.NestStorageSettings`), defaulting to File mode so existing
installs are unaffected until an operator opts in via **File > Storage Mode...**.