aboutsummaryrefslogtreecommitdiff
path: root/gui/internal/ui/window.go
diff options
context:
space:
mode:
Diffstat (limited to 'gui/internal/ui/window.go')
-rw-r--r--gui/internal/ui/window.go48
1 files changed, 44 insertions, 4 deletions
diff --git a/gui/internal/ui/window.go b/gui/internal/ui/window.go
index 3d40441..a8a087e 100644
--- a/gui/internal/ui/window.go
+++ b/gui/internal/ui/window.go
@@ -34,6 +34,8 @@ type Window struct {
plan *planView
history *historyView
rules *rulesView
+ notebook *gtk.Notebook
+ settings *gtk.Button
status *gtk.Label
prefs model.Prefs
leaving bool
@@ -50,6 +52,7 @@ func NewWindow(app *gtk.Application, e *engine.Engine) *Window {
w.win.SetDefaultSize(1200, 720)
notebook := gtk.NewNotebook()
+ w.notebook = notebook
w.plan = newPlanView(w)
notebook.AppendPage(w.plan.root, gtk.NewLabel("Plan"))
w.history = newHistoryView(w)
@@ -77,6 +80,7 @@ func NewWindow(app *gtk.Application, e *engine.Engine) *Window {
settings.SetTooltipText("krino's defaults, and how this window behaves")
settings.SetMarginEnd(6)
settings.ConnectClicked(func() { w.showSettings() })
+ w.settings = settings
notebook.SetActionWidget(settings, gtk.PackEnd)
w.status = gtk.NewLabel("")
@@ -105,9 +109,12 @@ func NewWindow(app *gtk.Application, e *engine.Engine) *Window {
w.confirmLeaving()
return true
}
- w.plan.closeTab()
+ // An apply in flight keeps its lock and its log: closing the
+ // window under it would move files nothing records.
+ if !w.plan.closeTab() || !w.history.closeTab() {
+ return true
+ }
w.plan.closePreview()
- w.history.closeTab()
return false
})
themeColours(w.win)
@@ -118,17 +125,50 @@ func NewWindow(app *gtk.Application, e *engine.Engine) *Window {
// Show puts the window on screen.
func (w *Window) Show() { w.win.Show() }
+// setApplying greys out everything that would pull the directory lock or
+// the log away from a running apply: the other tabs, and Settings. The
+// model refuses those anyway, but a button that cannot work should say so
+// by being unavailable rather than by an error afterwards.
+func (w *Window) setApplying(busy bool) {
+ if w.settings != nil {
+ w.settings.SetSensitive(!busy)
+ }
+ if w.notebook == nil {
+ return
+ }
+ current := int(w.notebook.CurrentPage())
+ for i := 0; i < int(w.notebook.NPages()); i++ {
+ if i == current {
+ continue
+ }
+ if page, ok := w.notebook.NthPage(i).(interface{ SetSensitive(bool) }); ok {
+ page.SetSensitive(!busy)
+ }
+ }
+}
+
// reloadEngine re-reads the configuration, after the rules editor saves, so
// every tab works from the rules the user just wrote. An open plan came
// from the old ones, so it is closed and its lock released.
+//
+// It refuses while an apply is running. Saving rules, saving settings and
+// adding a directory all come through here, and every one of them is
+// reachable from the window while files are being moved; closing the plan
+// then releases the directory lock and shuts the log under the engine, so a
+// file moves that no krino undo can see and the rest of the plan is
+// abandoned.
func (w *Window) reloadEngine() error {
+ if w.plan.busyApplying() || w.history.busyApplying() {
+ return model.ErrApplying
+ }
e, diags := engine.Load(w.engine.MainFile)
if len(diags) > 0 {
return diags[0]
}
e.CacheDir = w.engine.CacheDir
- w.plan.closeTab()
- w.history.closeTab()
+ if !w.plan.closeTab() || !w.history.closeTab() {
+ return model.ErrApplying
+ }
w.engine = e
return nil
}