forked from Leak_Technologies/VideoTools
Fix file dialog and drag-and-drop loading issues
File dialog improvements: - Add video file filters (*.mp4, *.mkv, etc.) so files are visible - Add "All Files" filter as fallback - Make dialog modal with Cancel button - Improve usability with proper MIME type filtering Drag-and-drop improvements: - Use net/url.Parse for proper URL decoding (%20 for spaces, etc.) - Handle file:// URIs correctly with localhost stripping - Add comprehensive debug logging throughout load chain Debug logging added to: - uriToPath() - shows URI parsing - loadIntoPane() - tracks load progress and MPV errors - drag-data-received - shows received URIs - file dialog - logs selected files These changes should fix both file navigation in dialogs and drag-and-drop video loading from file managers. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
a026f723ed
commit
42c1f32647
|
|
@ -3,6 +3,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"net/url"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -222,10 +223,41 @@ func buildControls(win *gtk.Window, left, right *pane) *gtk.Box {
|
||||||
}
|
}
|
||||||
|
|
||||||
func chooseAndLoad(win *gtk.Window, p *pane) {
|
func chooseAndLoad(win *gtk.Window, p *pane) {
|
||||||
dlg, _ := gtk.FileChooserDialogNewWith1Button("Open Video", win, gtk.FILE_CHOOSER_ACTION_OPEN, "Open", gtk.RESPONSE_ACCEPT)
|
dlg, _ := gtk.FileChooserDialogNewWith2Buttons(
|
||||||
|
"Open Video",
|
||||||
|
win,
|
||||||
|
gtk.FILE_CHOOSER_ACTION_OPEN,
|
||||||
|
"Cancel", gtk.RESPONSE_CANCEL,
|
||||||
|
"Open", gtk.RESPONSE_ACCEPT,
|
||||||
|
)
|
||||||
|
dlg.SetModal(true)
|
||||||
|
|
||||||
|
// Add file filter for video files
|
||||||
|
filter, _ := gtk.FileFilterNew()
|
||||||
|
filter.SetName("Video Files")
|
||||||
|
filter.AddMimeType("video/*")
|
||||||
|
filter.AddPattern("*.mp4")
|
||||||
|
filter.AddPattern("*.mkv")
|
||||||
|
filter.AddPattern("*.avi")
|
||||||
|
filter.AddPattern("*.mov")
|
||||||
|
filter.AddPattern("*.webm")
|
||||||
|
filter.AddPattern("*.flv")
|
||||||
|
filter.AddPattern("*.wmv")
|
||||||
|
filter.AddPattern("*.m4v")
|
||||||
|
filter.AddPattern("*.mpg")
|
||||||
|
filter.AddPattern("*.mpeg")
|
||||||
|
dlg.AddFilter(filter)
|
||||||
|
|
||||||
|
// Add "All Files" filter as fallback
|
||||||
|
allFilter, _ := gtk.FileFilterNew()
|
||||||
|
allFilter.SetName("All Files")
|
||||||
|
allFilter.AddPattern("*")
|
||||||
|
dlg.AddFilter(allFilter)
|
||||||
|
|
||||||
if resp := dlg.Run(); resp == gtk.RESPONSE_ACCEPT {
|
if resp := dlg.Run(); resp == gtk.RESPONSE_ACCEPT {
|
||||||
filename := dlg.GetFilename()
|
filename := dlg.GetFilename()
|
||||||
if filename != "" {
|
if filename != "" {
|
||||||
|
log.Printf("Selected file: %s", filename)
|
||||||
loadIntoPane(p, filename)
|
loadIntoPane(p, filename)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -233,15 +265,21 @@ func chooseAndLoad(win *gtk.Window, p *pane) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadIntoPane(p *pane, filename string) {
|
func loadIntoPane(p *pane, filename string) {
|
||||||
|
log.Printf("loadIntoPane: filename=%q", filename)
|
||||||
if !ensurePaneReady(p) {
|
if !ensurePaneReady(p) {
|
||||||
|
log.Printf("loadIntoPane: pane not ready")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
p.path = filename
|
p.path = filename
|
||||||
p.id = getOrAddVideoID(filename)
|
p.id = getOrAddVideoID(filename)
|
||||||
|
log.Printf("loadIntoPane: calling mpv loadfile command")
|
||||||
if err := p.mpv.Command("loadfile", filename, "replace"); err != nil {
|
if err := p.mpv.Command("loadfile", filename, "replace"); err != nil {
|
||||||
log.Printf("loadfile %s: %v", filename, err)
|
log.Printf("loadfile %s: ERROR: %v", filename, err)
|
||||||
|
} else {
|
||||||
|
log.Printf("loadfile %s: success", filename)
|
||||||
}
|
}
|
||||||
_ = p.mpv.SetPropertyBool("pause", false)
|
_ = p.mpv.SetPropertyBool("pause", false)
|
||||||
|
log.Printf("loadIntoPane: complete")
|
||||||
}
|
}
|
||||||
|
|
||||||
func metaSummary(a, b *pane) string {
|
func metaSummary(a, b *pane) string {
|
||||||
|
|
@ -312,10 +350,13 @@ func setupDragDest(targetPane *pane, left, right *pane) {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
if data == nil {
|
if data == nil {
|
||||||
|
log.Printf("drag-data-received: data is nil")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Printf("drag-data-received: got data")
|
||||||
uris := parseURIs(data)
|
uris := parseURIs(data)
|
||||||
|
log.Printf("drag-data-received: parsed URIs: %v", uris)
|
||||||
for _, u := range uris {
|
for _, u := range uris {
|
||||||
if u == "" {
|
if u == "" {
|
||||||
continue
|
continue
|
||||||
|
|
@ -377,10 +418,26 @@ func uriToPath(u string) string {
|
||||||
if u == "" {
|
if u == "" {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
// text/uri-list format: file:///path or path\n
|
log.Printf("uriToPath: input=%q", u)
|
||||||
if len(u) >= 7 && u[:7] == "file://" {
|
|
||||||
u = u[7:]
|
// text/uri-list format: file:///path
|
||||||
|
if strings.HasPrefix(u, "file://") {
|
||||||
|
// Use url.Parse to properly handle URL encoding
|
||||||
|
parsed, err := url.Parse(u)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("uriToPath: url.Parse error: %v", err)
|
||||||
|
// Fallback: just strip file://
|
||||||
|
u = strings.TrimPrefix(u, "file://")
|
||||||
|
// Handle localhost
|
||||||
|
u = strings.TrimPrefix(u, "localhost")
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
path := parsed.Path
|
||||||
|
log.Printf("uriToPath: parsed path=%q", path)
|
||||||
|
return path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Not a file:// URI, return as-is
|
||||||
return u
|
return u
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user