A desktop backup program focusing on ease-of-use and simplicity, as well as quality, low resource usage, and performance.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
EZ-Bkup/views/routine_editor.nim

223 lines
9.4 KiB

#[Copyright 2023 ITwrx.
This file is part of EZ-Bkup.
EZ-Bkup is released under the General Public License 3.0.
See COPYING or <https://www.gnu.org/licenses/> for details.]#
import owlkettle
import "../models/routine", "../shared"
viewable RoutineEditor:
## A form for editing a Routine
routine: Routine ## The routine that is being edited
# Since Routine is passed by value, we need to notify the parent widget of
# any changes to the routine. The changed callback
proc changed(routine: Routine)
method view(editor: RoutineEditorState): Widget {.locks: "unknown".} =
result = gui:
#must have top level container that everything else is inside of.
Box:
orient = OrientY
margin = 12
spacing = 12
Box {.expand: false.}:
orient = OrientX
spacing = 6
Label {.expand: false.}:
text = "<span weight=\"bold\">Name:</span>"
xAlign = 0
useMarkup = true
Entry {.expand: false.}:
text = editor.routine.name
xAlign = 0
proc changed(text: string) =
editor.routine.name = text
# Call the changed callback
if not editor.changed.isNil:
editor.changed.callback(editor.routine)
Box {.expand: false.}:
orient = OrientX
spacing = 6
Label {.expand: false.}:
text = "<span weight=\"bold\" color=\"#FFF469\">Enabled by default?</span>"
tooltip = "Should this Routine be enabled for inclusion in any Bkup run by default?"
xAlign = 0
useMarkup = true
Switch {.expand: false.}:
state = editor.routine.selByDef
proc changed(state: bool) =
editor.routine.selByDef = state
if not editor.changed.isNil:
editor.changed.callback(editor.routine)
Label {.expand: false.}:
text = "<span weight=\"bold\" color=\"#FFF469\">Sources:</span>"
tooltip = "The file(s) or folder(s) you want to backup when this Routine is run."
xAlign = 0
useMarkup = true
Box {.expand: false.}:
spacing = 6
Button {.expand: false.}:
text = "+ File"
style = [ButtonSuggested]
proc clicked() =
let (res, state) = editor.app.open: gui:
FileChooserDialog:
title = "Add Source Files to Routine"
action = FileChooserOpen
selectMultiple = true
DialogButton {.addButton.}:
text = "Cancel"
res = DialogCancel
DialogButton {.addButton.}:
text = "Confirm"
res = DialogAccept
style = [ButtonSuggested]
if res.kind == DialogAccept:
for filename in FileChooserDialogState(state).filenames:
if hasCommas(filename):
discard editor.app.open: gui:
MessageDialog:
message = "Commas in Source filename/path are not supported."
style = [StyleClass("error")]
DialogButton {.addButton.}:
text = "Ok"
res = DialogAccept
elif filename in editor.routine.sources:
discard editor.app.open: gui:
MessageDialog:
message = "Duplicate Routine Source filenames (" & filename & ") are not supported."
style = [StyleClass("error")]
DialogButton {.addButton.}:
text = "Ok"
res = DialogAccept
else:
editor.routine.sources.add(filename)
if not editor.changed.isNil:
editor.changed.callback(editor.routine)
Button {.expand: false.}:
text = "+ Folder"
style = [ButtonSuggested]
proc clicked() =
let (res, state) = editor.app.open: gui:
FileChooserDialog:
title = "Add Source Folders to Routine"
action = FileChooserSelectFolder
selectMultiple = true
DialogButton {.addButton.}:
text = "Cancel"
res = DialogCancel
DialogButton {.addButton.}:
text = "Confirm"
res = DialogAccept
style = [ButtonSuggested]
if res.kind == DialogAccept:
for filename in FileChooserDialogState(state).filenames:
if hasCommas(filename):
discard editor.app.open: gui:
MessageDialog:
message = "Commas in Source filename/path are not supported."
style = [StyleClass("error")]
DialogButton {.addButton.}:
text = "Ok"
res = DialogAccept
elif filename in editor.routine.sources:
discard editor.app.open: gui:
MessageDialog:
message = "Duplicate Routine Source (" & filename & ") not supported."
style = [StyleClass("error")]
DialogButton {.addButton.}:
text = "Ok"
res = DialogAccept
else:
editor.routine.sources.add(filename)
if not editor.changed.isNil:
editor.changed.callback(editor.routine)
Box {.expand: false.}:
orient = OrientY
margin = 6
spacing = 6
#routineSeq returns an empty seq when no sources exist.
if editor.routine.sources.len != 0:
for it, routineSource in editor.routine.sources:
Box:
orient = OrientX
spacing = 6
Label:
text = routineSource
xAlign = 0
Button {.expand: false.}:
icon = "user-trash-symbolic"
tooltip = "Delete this Source. Warning: will not ask you to confirm."
proc clicked() =
editor.routine.sources.delete(it)
if not editor.changed.isNil:
editor.changed.callback(editor.routine)
Label {.expand: false.}:
text = "<span weight=\"bold\" color=\"#FFF469\">Destinations:</span>"
tooltip = "The folder(s) or drive(s) you want to backup this Routine's Sources to."
xAlign = 0
useMarkup = true
Box {.expand: false.}:
spacing = 6
Button {.expand: false.}:
text = "+ Folder/Drive"
style = [ButtonSuggested]
proc clicked() =
let (res, state) = editor.app.open: gui:
FileChooserDialog:
title = "Add Destination Folders to Routine"
action = FileChooserSelectFolder
selectMultiple = true
DialogButton {.addButton.}:
text = "Cancel"
res = DialogCancel
DialogButton {.addButton.}:
text = "Confirm"
res = DialogAccept
style = [ButtonSuggested]
if res.kind == DialogAccept:
for filename in FileChooserDialogState(state).filenames:
if hasCommas(filename):
discard editor.app.open: gui:
MessageDialog:
message = "Commas in Destination filename/path are not supported."
style = [StyleClass("error")]
DialogButton {.addButton.}:
text = "Ok"
res = DialogAccept
elif filename in editor.routine.destinations:
discard editor.app.open: gui:
MessageDialog:
message = "Duplicate Routine Destination (" & filename & ") not supported."
style = [StyleClass("error")]
DialogButton {.addButton.}:
text = "Ok"
res = DialogAccept
else:
editor.routine.destinations.add(filename)
if not editor.changed.isNil:
editor.changed.callback(editor.routine)
Box {.expand: false.}:
orient = OrientY
margin = 6
spacing = 6
#routineSeq returns an empty seq when no destinations exist.
if editor.routine.destinations.len != 0:
for it, routineDestination in editor.routine.destinations:
Box:
orient = OrientX
spacing = 6
Label:
text = routineDestination
xAlign = 0
Button {.expand: false.}:
icon = "user-trash-symbolic"
tooltip = "Delete this Destination. Warning: will not ask you to confirm."
proc clicked() =
editor.routine.destinations.delete(it)
if not editor.changed.isNil:
editor.changed.callback(editor.routine)
export RoutineEditor