diff options
Diffstat (limited to 'gui/internal/ui/window.go')
| -rw-r--r-- | gui/internal/ui/window.go | 48 |
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 } |
