Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

- A command panel now docks under the panes (View menu or F4): type a command and it runs in the active pane's folder through PowerShell (or the Command Prompt where PowerShell is absent), with its output shown in the panel as it runs, a stop button for the running command, and Up/Down recall of earlier commands. The panel follows the active pane, so its folder is always the folder you are looking at. It runs commands and shows their output; programs that wait for typed answers still belong in a full terminal — "Open terminal here" remains for those.

- The Recycle Bin is now browsable like a folder: a Places entry in the sidebar opens it in a pane, showing every item in the signed-in user's bin across all drives with its original location and deletion time. Items can be restored to where they were deleted from (with the name numbered if something already sits there), deleted permanently after a confirmation, or the whole bin emptied; file operations that cannot apply to recycled items step aside while a pane shows the bin, and a tab left on the bin reopens on it.

- The dark theme is now charcoal with a crimson accent: layered charcoal surfaces (#232323 window, #2B2B2B panels, #333333 raised areas, #404040 borders) replace the near-black ones, the default accent is crimson (#DC143C, listed as "Crimson" in Settings; a saved "Red" choice lands on it), the panel hairlines carry the same crimson, and text on the accent is now white. The red-gray selection, green readouts, and the light theme's surfaces are unchanged.

- Each pane now keeps its own folder tabs, living in the path-bar area: inactive tabs sit as compact chips above the bar, the active tab is the breadcrumb bar itself, and new-tab and close-tab buttons sit at the bar's right end. Every tab remembers its own back/forward history, the session restores both panes' tabs, and the shortcuts are Ctrl+T (new tab), Ctrl+W (close tab) and Ctrl+Tab / Ctrl+Shift+Tab (cycle); middle-clicking a chip closes that tab. Closed tabs are remembered (the last 50, with their history) and Ctrl+Shift+T reopens the most recently closed one.
Expand Down
7 changes: 4 additions & 3 deletions docs/ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ See [STATUS.md](STATUS.md) for the dated implemented/CI/runtime inventory. Check

Meridian's feature target is KDE's Dolphin, adapted to Windows. Already at parity: dual-pane (split) browsing, per-pane tabs with closed-tab history, clickable breadcrumbs, view modes remembered per folder, a Places-style sidebar, previews, batch rename, sorting and grouping, and content search. The remaining parity work, in planned order:

1. **Virtual locations** — one location layer under the panes, so the Recycle Bin, recent files, search results, and archives browse like folders (builds on Phase 6's archive-as-folder and virtual-view items).
1. **Virtual locations** — one location layer under the panes, so the Recycle Bin, recent files, search results, and archives browse like folders (builds on Phase 6's archive-as-folder and virtual-view items). _Started: the Recycle Bin browses as a virtual location with restore, permanent delete, and empty._
2. **Indexed search** — a USN-journal-backed index for instant name search, growing toward content (Phase 4).
3. **Embedded terminal panel** that follows the current folder (Phase 7).
3. **Embedded terminal panel** that follows the current folder (Phase 7). _Started: a docked command panel (F4) runs commands in the active pane's folder and streams their output; a fully interactive terminal remains._
4. **Tags, ratings, and comments** stored locally and searchable, with optional NTFS alternate-data-stream storage investigated for portability (Phase 2).
5. **Network protocols** — SMB browsing first, then optional SFTP, FTP/FTPS, WebDAV, and SCP clients and optional cloud providers, all behind provider interfaces; local file management never depends on them (Phase 6).

Expand Down Expand Up @@ -222,10 +222,11 @@ Avoid starting large Phase 2/3 experiments until these release blockers are reso
- [ ] Improve Android MTP/PTP and supported Apple-device browsing/transfers where Windows APIs permit
- [ ] WSL distribution navigation and \wsl$ support; investigate safe read/browse support for EXT4 VHDX images (distribution navigation and \wsl$ browsing delivered; EXT4 VHDX investigation remains)
- [ ] Investigate virtual views for Windows Registry hives and running processes, with strict read-only defaults and prominent warnings
- [x] Recycle Bin as a browsable virtual location, with restore, permanent delete, and empty (the first virtual location; Registry/process views remain under the investigation item above)

## Phase 7 — Developer and power-user tools

- [ ] Embedded terminal panel for PowerShell, Command Prompt, Git Bash, or WSL, with explicit working-directory synchronization
- [ ] Embedded terminal panel for PowerShell, Command Prompt, Git Bash, or WSL, with explicit working-directory synchronization (command panel delivered: PowerShell/Command Prompt commands run in the active pane's folder with streamed output and working-directory follow; a fully interactive terminal, Git Bash, and WSL remain open)
- [ ] Git repository badges/columns for branch, working-tree status, staged/unstaged changes, ahead/behind, and diff actions (per-file working-tree status column delivered; branch display, ahead/behind counts, and diff actions remain)
- [x] Path-copy utilities: Windows, POSIX, UNC, quoted path, filename, directory, file URI, and SHA-256
- [ ] Integrated side-by-side text diff and practical binary comparison
Expand Down
5 changes: 5 additions & 0 deletions src/Meridian.App/MainWindow.BatchRename.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ public sealed partial class MainWindow
/// single-item rename exactly as it was, warning included.</summary>
private async Task RenameEntryAsync(PaneState pane)
{
if (pane.IsRecycleBin)
{
SetStatus("Recycled items keep the name they were deleted with — restore an item to rename it.", StatusSeverity.Warning);
return;
}
if (pane.SelectionList.SelectedItems.Count >= 2)
await BatchRenameAsync(pane);
else
Expand Down
4 changes: 2 additions & 2 deletions src/Meridian.App/MainWindow.Clipboard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ private void ApplyCutDimming()
/// </summary>
private async Task PasteClipboardAsFileAsync(PaneState pane)
{
if (pane.IsHome || string.IsNullOrWhiteSpace(pane.CurrentPath))
if (pane.IsHome || pane.IsRecycleBin || string.IsNullOrWhiteSpace(pane.CurrentPath))
{
SetStatus("Open a folder to paste into.", StatusSeverity.Warning);
return;
Expand Down Expand Up @@ -195,7 +195,7 @@ private async Task SetClipboardFromPaneAsync(PaneState pane, bool cut)

private async Task PasteIntoPaneAsync(PaneState pane)
{
if (pane.IsHome || string.IsNullOrWhiteSpace(pane.CurrentPath))
if (pane.IsHome || pane.IsRecycleBin || string.IsNullOrWhiteSpace(pane.CurrentPath))
{
SetStatus("Open a folder to paste into.", StatusSeverity.Warning);
return;
Expand Down
13 changes: 13 additions & 0 deletions src/Meridian.App/MainWindow.Preview.cs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,13 @@ private async Task PopulatePreviewPanelAsync(FileEntry selected, StackPanel pane
private async Task OpenSelectedAsync(PaneState pane)
{
if (pane.SelectionList.SelectedItem is not FileEntry selected) return;
if (pane.IsRecycleBin)
{
// Opening a recycled item restores it — its bin data path is
// never launched or navigated into directly.
await RestoreSelectedAsync(pane);
return;
}
if (selected.IsDirectory)
{
// In the columns layout a selected folder is already cascaded into
Expand Down Expand Up @@ -186,6 +193,11 @@ private async Task MoveSelectedAsync(PaneState source, PaneState destination)
SetStatus("Open a folder in the other pane first — Home is not a move destination.", StatusSeverity.Warning);
return;
}
if (source.IsRecycleBin || destination.IsRecycleBin)
{
SetStatus("Recycled items cannot be moved directly — restore an item to bring it back, or delete it permanently.", StatusSeverity.Warning);
return;
}
if (string.IsNullOrWhiteSpace(destination.CurrentPath)) return;

var confirmedPaths = selection.Select(item => item.FullPath).ToArray();
Expand Down Expand Up @@ -243,6 +255,7 @@ private async Task CopySelectedAsync(PaneState source, PaneState destination)
var selection = GetSelectedEntries(source);
if (selection.Count == 0) { SetStatus($"Select an item in the {source.Name.ToLowerInvariant()} pane first.", StatusSeverity.Warning); return; }
if (destination.IsHome) { SetStatus("Open a folder in the other pane first \u2014 Home is not a copy destination.", StatusSeverity.Warning); return; }
if (source.IsRecycleBin || destination.IsRecycleBin) { SetStatus("Recycled items cannot be copied directly — restore an item to bring it back, or delete it permanently.", StatusSeverity.Warning); return; }
if (string.IsNullOrWhiteSpace(destination.CurrentPath)) return;

var sourcePaths = selection.Select(item => item.FullPath).ToArray();
Expand Down
Loading