|
|
|
@ -91,164 +91,192 @@ proc rsyncThread(list: RoutineListState) {.thread.} = |
|
|
|
|
list.redrawFromThread() |
|
|
|
|
|
|
|
|
|
method view(list: RoutineListState): Widget = |
|
|
|
|
result = gui: |
|
|
|
|
ScrolledWindow: |
|
|
|
|
result = gui: |
|
|
|
|
Box: |
|
|
|
|
orient = OrientY |
|
|
|
|
Box: |
|
|
|
|
orient = OrientY |
|
|
|
|
if list.routineModel.routineSeq().len() > 0: |
|
|
|
|
ListBox: |
|
|
|
|
for it, routine in list.routineModel.routineSeq(): |
|
|
|
|
Box: |
|
|
|
|
orient = OrientY |
|
|
|
|
margin = 6 |
|
|
|
|
spacing = 6 |
|
|
|
|
Box: |
|
|
|
|
orient = OrientX |
|
|
|
|
margin = 6 |
|
|
|
|
spacing = 6 |
|
|
|
|
Switch {.expand: false, vAlign: AlignCenter.}: |
|
|
|
|
state = sequtils.any(list.selected, proc (id: RoutineId): bool = id == routine.id) |
|
|
|
|
tooltip = "Enable/Disable this Routine for the current Bkup run." |
|
|
|
|
proc changed(state: bool) = |
|
|
|
|
if state == true: |
|
|
|
|
list.selected.add(routine.id) |
|
|
|
|
else: |
|
|
|
|
let index = list.selected.find(routine.id) |
|
|
|
|
if index != -1: |
|
|
|
|
list.selected.delete(index) |
|
|
|
|
Label: |
|
|
|
|
text = "<span size=\"large\">" & routine.name & "</span>" |
|
|
|
|
xAlign = 0 |
|
|
|
|
useMarkup = true |
|
|
|
|
# Edit Button |
|
|
|
|
Button {.expand: false.}: |
|
|
|
|
#icon = "entity-edit" |
|
|
|
|
icon = "entity-edit-dark-theme" |
|
|
|
|
tooltip = "Edit this Routine." |
|
|
|
|
proc clicked() = |
|
|
|
|
## Opens the EditRoutineDialog for updating the existing routine |
|
|
|
|
let (res, state) = list.app.open: gui: |
|
|
|
|
EditRoutineDialog: |
|
|
|
|
routine = routine |
|
|
|
|
mode = EditRoutineUpdate |
|
|
|
|
if res.kind == DialogAccept: |
|
|
|
|
# The "Update" button was clicked |
|
|
|
|
list.routineModel.update(EditRoutineDialogState(state).routine) |
|
|
|
|
list.selected = selectedPreload() |
|
|
|
|
# Delete Button |
|
|
|
|
Button {.expand: false.}: |
|
|
|
|
icon = "user-trash-symbolic" |
|
|
|
|
tooltip = "Delete this Routine. Warning: will not ask you to confirm." |
|
|
|
|
proc clicked() = |
|
|
|
|
list.routineModel.delete(routine.id) |
|
|
|
|
list.selected = selectedPreload() |
|
|
|
|
if routine.id in list.selected: |
|
|
|
|
orient = OrientY |
|
|
|
|
ScrolledWindow: |
|
|
|
|
Box: |
|
|
|
|
orient = OrientY |
|
|
|
|
if list.routineModel.routineSeq().len() > 0: |
|
|
|
|
ListBox: |
|
|
|
|
for it, routine in list.routineModel.routineSeq(): |
|
|
|
|
Box: |
|
|
|
|
orient = OrientY |
|
|
|
|
margin = 6 |
|
|
|
|
spacing = 6 |
|
|
|
|
Label: |
|
|
|
|
text = "<span color=\"#6fffa3\">Sources:</span>" |
|
|
|
|
xAlign = 0 |
|
|
|
|
useMarkup = true |
|
|
|
|
#routineSeq returns an empty string when no sources exist. |
|
|
|
|
if routine.sources.len != 0: |
|
|
|
|
for it, routineSource in routine.sources: |
|
|
|
|
Box: |
|
|
|
|
orient = OrientX |
|
|
|
|
spacing = 6 |
|
|
|
|
margin = 6 |
|
|
|
|
Label: |
|
|
|
|
text = routineSource |
|
|
|
|
xAlign = 0 |
|
|
|
|
else: |
|
|
|
|
spacing = 6 |
|
|
|
|
Box: |
|
|
|
|
orient = OrientX |
|
|
|
|
margin = 6 |
|
|
|
|
spacing = 6 |
|
|
|
|
Switch {.expand: false, vAlign: AlignCenter.}: |
|
|
|
|
state = sequtils.any(list.selected, proc (id: RoutineId): bool = id == routine.id) |
|
|
|
|
tooltip = "Enable/Disable this Routine for the current Bkup run." |
|
|
|
|
proc changed(state: bool) = |
|
|
|
|
if state == true: |
|
|
|
|
list.selected.add(routine.id) |
|
|
|
|
else: |
|
|
|
|
let index = list.selected.find(routine.id) |
|
|
|
|
if index != -1: |
|
|
|
|
list.selected.delete(index) |
|
|
|
|
Label: |
|
|
|
|
text = "<span size=\"large\">" & routine.name & "</span>" |
|
|
|
|
xAlign = 0 |
|
|
|
|
useMarkup = true |
|
|
|
|
# Edit Button |
|
|
|
|
Button {.expand: false.}: |
|
|
|
|
#icon = "entity-edit" |
|
|
|
|
icon = "entity-edit-dark-theme" |
|
|
|
|
tooltip = "Edit this Routine." |
|
|
|
|
proc clicked() = |
|
|
|
|
## Opens the EditRoutineDialog for updating the existing routine |
|
|
|
|
let (res, state) = list.app.open: gui: |
|
|
|
|
EditRoutineDialog: |
|
|
|
|
routine = routine |
|
|
|
|
mode = EditRoutineUpdate |
|
|
|
|
if res.kind == DialogAccept: |
|
|
|
|
# The "Update" button was clicked |
|
|
|
|
list.routineModel.update(EditRoutineDialogState(state).routine) |
|
|
|
|
list.selected = selectedPreload() |
|
|
|
|
# Delete Button |
|
|
|
|
Button {.expand: false.}: |
|
|
|
|
icon = "user-trash-symbolic" |
|
|
|
|
tooltip = "Delete this Routine. Warning: will not ask you to confirm." |
|
|
|
|
proc clicked() = |
|
|
|
|
list.routineModel.delete(routine.id) |
|
|
|
|
list.selected = selectedPreload() |
|
|
|
|
if routine.id in list.selected: |
|
|
|
|
Box: |
|
|
|
|
orient = OrientX |
|
|
|
|
spacing = 6 |
|
|
|
|
orient = OrientY |
|
|
|
|
margin = 6 |
|
|
|
|
Label: |
|
|
|
|
text = "<span color=\"#ff6b6b\">Routine will be ignored. Source required.</span>" |
|
|
|
|
xAlign = 0 |
|
|
|
|
useMarkup = true |
|
|
|
|
Label: |
|
|
|
|
text = "<span color=\"#6fffa3\">Destinations:</span>" |
|
|
|
|
xAlign = 0 |
|
|
|
|
useMarkup = true |
|
|
|
|
#routineSeq returns an empty string when no destinations exist. |
|
|
|
|
if routine.destinations.len != 0: |
|
|
|
|
for it, routineDestination in routine.destinations: |
|
|
|
|
Box: |
|
|
|
|
orient = OrientX |
|
|
|
|
spacing = 6 |
|
|
|
|
margin = 6 |
|
|
|
|
Label: |
|
|
|
|
text = routineDestination |
|
|
|
|
xAlign = 0 |
|
|
|
|
else: |
|
|
|
|
Box: |
|
|
|
|
orient = OrientX |
|
|
|
|
spacing = 6 |
|
|
|
|
margin = 6 |
|
|
|
|
Label: |
|
|
|
|
text = "<span color=\"#ff6b6b\">Routine will be ignored. Destination required.</span>" |
|
|
|
|
text = "<span color=\"#6fffa3\">Sources:</span>" |
|
|
|
|
xAlign = 0 |
|
|
|
|
useMarkup = true |
|
|
|
|
Box {.expand: false.}: |
|
|
|
|
orient = OrientX |
|
|
|
|
spacing = 6 |
|
|
|
|
margin = 6 |
|
|
|
|
Label {.expand: false.}: |
|
|
|
|
text = "<span size=\"large\">Status: </span>" |
|
|
|
|
xAlign = 0 |
|
|
|
|
useMarkup = true |
|
|
|
|
Label: |
|
|
|
|
if list.runStatus != "": |
|
|
|
|
text = list.runStatus |
|
|
|
|
else: |
|
|
|
|
text = "<span color=\"#6AC9FF\" size=\"large\">Waiting patiently...</span>" |
|
|
|
|
xAlign = 0 |
|
|
|
|
margin = 6 |
|
|
|
|
useMarkup = true |
|
|
|
|
# Run Button |
|
|
|
|
Button {.expand: false.}: |
|
|
|
|
Box: |
|
|
|
|
orient = OrientX |
|
|
|
|
spacing = 6 |
|
|
|
|
#routineSeq returns an empty string when no sources exist. |
|
|
|
|
if routine.sources.len != 0: |
|
|
|
|
for it, routineSource in routine.sources: |
|
|
|
|
Box: |
|
|
|
|
orient = OrientX |
|
|
|
|
spacing = 6 |
|
|
|
|
margin = 6 |
|
|
|
|
Label: |
|
|
|
|
text = routineSource |
|
|
|
|
xAlign = 0 |
|
|
|
|
else: |
|
|
|
|
Box: |
|
|
|
|
orient = OrientX |
|
|
|
|
spacing = 6 |
|
|
|
|
margin = 6 |
|
|
|
|
Label: |
|
|
|
|
text = "<span color=\"#ff6b6b\">Routine will be ignored. Source required.</span>" |
|
|
|
|
xAlign = 0 |
|
|
|
|
useMarkup = true |
|
|
|
|
Label: |
|
|
|
|
text = "<span color=\"#6fffa3\">Destinations:</span>" |
|
|
|
|
xAlign = 0 |
|
|
|
|
useMarkup = true |
|
|
|
|
#routineSeq returns an empty string when no destinations exist. |
|
|
|
|
if routine.destinations.len != 0: |
|
|
|
|
for it, routineDestination in routine.destinations: |
|
|
|
|
Box: |
|
|
|
|
orient = OrientX |
|
|
|
|
spacing = 6 |
|
|
|
|
margin = 6 |
|
|
|
|
Label: |
|
|
|
|
text = routineDestination |
|
|
|
|
xAlign = 0 |
|
|
|
|
else: |
|
|
|
|
Box: |
|
|
|
|
orient = OrientX |
|
|
|
|
spacing = 6 |
|
|
|
|
margin = 6 |
|
|
|
|
Label: |
|
|
|
|
text = "<span color=\"#ff6b6b\">Routine will be ignored. Destination required.</span>" |
|
|
|
|
xAlign = 0 |
|
|
|
|
useMarkup = true |
|
|
|
|
else: |
|
|
|
|
Box {.expand: false.}: |
|
|
|
|
orient = OrientY |
|
|
|
|
margin = 6 |
|
|
|
|
Icon: |
|
|
|
|
name = "media-floppy" |
|
|
|
|
pixelSize = 40 |
|
|
|
|
margin = 4 |
|
|
|
|
Label {.expand: false.}: |
|
|
|
|
text = "<span size=\"large\">Run Bkup!</span>" |
|
|
|
|
xAlign = 0 |
|
|
|
|
useMarkup = true |
|
|
|
|
proc clicked() = |
|
|
|
|
#check that every source and destination exists for each routine or don't run bkup and show err status. |
|
|
|
|
#locations not found will be logged. see routine.nim |
|
|
|
|
var allLocationsExist: seq[bool] |
|
|
|
|
for routine in list.routineModel.routineSeq(): |
|
|
|
|
if routine.id in list.selected: |
|
|
|
|
if locationsExist(routine) == true: |
|
|
|
|
allLocationsExist.add(true) |
|
|
|
|
else: |
|
|
|
|
allLocationsExist.add(false) |
|
|
|
|
if false in allLocationsExist: |
|
|
|
|
#show error status. |
|
|
|
|
list.runStatus = "<span color=\"#ff6b6b\" size=\"large\">Missing Source(s)/Destination(s) in selected Routine(s).</span>" |
|
|
|
|
else: |
|
|
|
|
createThread(thread, rsyncThread, list) |
|
|
|
|
else: |
|
|
|
|
spacing = 12 |
|
|
|
|
Label: |
|
|
|
|
text = "<span size=\"large\">You don't have any Bkup Routines!!! 🙂</span>" |
|
|
|
|
xAlign = 0 |
|
|
|
|
useMarkup = true |
|
|
|
|
Label: |
|
|
|
|
text = "<span size=\"large\">Please click on the + Routine button above to create your first Routine.</span>" |
|
|
|
|
xAlign = 0 |
|
|
|
|
useMarkup = true |
|
|
|
|
|
|
|
|
|
if list.routineModel.routineSeq().len() > 0: |
|
|
|
|
Box {.expand: false.}: |
|
|
|
|
orient = OrientY |
|
|
|
|
Box {.expand: false.}: |
|
|
|
|
orient = OrientY |
|
|
|
|
margin = 6 |
|
|
|
|
spacing = 12 |
|
|
|
|
Label: |
|
|
|
|
text = "<span size=\"large\">You don't have any Bkup Routines!!! 🙂</span>" |
|
|
|
|
xAlign = 0 |
|
|
|
|
useMarkup = true |
|
|
|
|
Label: |
|
|
|
|
text = "<span size=\"large\">Please click on the + Routine button above to create your first Routine.</span>" |
|
|
|
|
xAlign = 0 |
|
|
|
|
useMarkup = true |
|
|
|
|
Box {.expand: false.}: |
|
|
|
|
orient = OrientX |
|
|
|
|
spacing = 6 |
|
|
|
|
margin = 6 |
|
|
|
|
Label {.expand: false.}: |
|
|
|
|
text = "<span size=\"large\">Status: </span>" |
|
|
|
|
xAlign = 0 |
|
|
|
|
useMarkup = true |
|
|
|
|
Label: |
|
|
|
|
if list.runStatus != "": |
|
|
|
|
text = list.runStatus |
|
|
|
|
else: |
|
|
|
|
text = "<span color=\"#6AC9FF\" size=\"large\">Waiting patiently...</span>" |
|
|
|
|
xAlign = 0 |
|
|
|
|
margin = 6 |
|
|
|
|
useMarkup = true |
|
|
|
|
# Run Button |
|
|
|
|
Button {.expand: false.}: |
|
|
|
|
Box: |
|
|
|
|
orient = OrientX |
|
|
|
|
spacing = 6 |
|
|
|
|
margin = 6 |
|
|
|
|
Icon: |
|
|
|
|
name = "media-floppy" |
|
|
|
|
pixelSize = 40 |
|
|
|
|
margin = 4 |
|
|
|
|
Label {.expand: false.}: |
|
|
|
|
text = "<span size=\"large\">Run Bkup!</span>" |
|
|
|
|
xAlign = 0 |
|
|
|
|
useMarkup = true |
|
|
|
|
proc clicked() = |
|
|
|
|
#check that every source and destination exists for each routine or don't run bkup and show err status. |
|
|
|
|
#locations not found will be logged. see routine.nim |
|
|
|
|
var allLocationsExist: seq[bool] |
|
|
|
|
for routine in list.routineModel.routineSeq(): |
|
|
|
|
if routine.id in list.selected: |
|
|
|
|
if locationsExist(routine) == true: |
|
|
|
|
allLocationsExist.add(true) |
|
|
|
|
else: |
|
|
|
|
allLocationsExist.add(false) |
|
|
|
|
if false in allLocationsExist: |
|
|
|
|
#show error status. |
|
|
|
|
list.runStatus = "<span color=\"#ff6b6b\" size=\"large\">Missing Source(s)/Destination(s) in selected Routine(s).</span>" |
|
|
|
|
else: |
|
|
|
|
createThread(thread, rsyncThread, list) |
|
|
|
|
|
|
|
|
|
#[if not list.routineModel.routineSeq().len() > 0: |
|
|
|
|
Box: |
|
|
|
|
orient = OrientX |
|
|
|
|
spacing = 6 |
|
|
|
|
margin = 6 |
|
|
|
|
Box {.expand: false.}: |
|
|
|
|
orient = OrientY |
|
|
|
|
margin = 6 |
|
|
|
|
spacing = 12 |
|
|
|
|
Label: |
|
|
|
|
text = "<span size=\"large\">You don't have any Bkup Routines!!! 🙂</span>" |
|
|
|
|
xAlign = 0 |
|
|
|
|
useMarkup = true |
|
|
|
|
Label: |
|
|
|
|
text = "<span size=\"large\">Please click on the + Routine button above to create your first Routine.</span>" |
|
|
|
|
xAlign = 0 |
|
|
|
|
useMarkup = true]# |
|
|
|
|
export RoutineList |
|
|
|
|