Bakker: 1 to 1 backup copier

Share your advanced PureBasic knowledge/code with the community.
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4791
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Bakker: 1 to 1 backup copier

Post by Fangbeast »

A friend in an office wanted a simple backup copier that generated 1 to 1 copies in directories either dated by ddmmyyyy or ddmmyyyy-hhmm, any time you pressed a button.

The admin module generates the backup (and can perform it itself), save config and file lists to the same file. Can automatically reload the backup file when you restart the program. Whinges if the parameters are not set and you try to save or run etc.

The client is s simple big button that can run the backup each time you hit it. It also reloads the admin created backup list if found, whinges and exits if not. The button shows the number of files being processed while running. The small window background changes to red if there was a file error at all (will make a log soon).

Do what you like with it. Get your own icons!! If i've missed someone's copyright on a procedure, put it in and repost.

admin module

Code: Select all

;============================================================================================================================
; 
;============================================================================================================================

Declare   SearchEngine(SearchDir.s)                         ; Recursive file path searcher

Declare   MyBalloonTips(btWindow.l, btGadget.l, btText.s)   ; Custom balloon tooltips.
Declare.s AddDateSuffix(Date.s)                             ; Add the abbreviated date suffix
Declare   GetDayOfWeek(Gadget.l)                            ; Get the day of the week in name form
Declare   SetDate(Windowid.l)                               ; Set the current date in the title bar
Declare   SetStat(Field.l, Message.s)                       ; Shortcut to setting text on the status bar
Declare.s GetDriveLabel(drivename.s)                        ; Get the drive label for a drive name

;============================================================================================================================
; 
;============================================================================================================================

Enumeration 1
  #Window_bakker
EndEnumeration

#WindowIndex = #PB_Compiler_EnumerationValue

Enumeration 1
  #Gadget_bakker_dirtree
  #Gadget_bakker_filetree
  #Gadget_bakker_filebackup
  #Gadget_bakker_bsave
  #Gadget_bakker_brun
  #Gadget_bakker_blocation
  #Gadget_bakker_fmain
  #Gadget_bakker_cbdateyear
  #Gadget_bakker_cbdayhour
  #Gadget_bakker_cblocation
  #Gadget_bakker_flocation
  #Gadget_bakker_llocation
  #Gadget_bakker_location
  #Gadget_bakker_lvolume
EndEnumeration

#GadgetIndex = #PB_Compiler_EnumerationValue

Enumeration 1
  #StatusBar_bakker
  #StatusBar_bakker_messages = 0
  #StatusBar_bakker_records  = 1
EndEnumeration

#StatusBarIndex = #PB_Compiler_EnumerationValue

Enumeration 1
  #Image_bakker_bsave
  #Image_bakker_brun
  #Image_bakker_blocation
EndEnumeration

#ImageIndex = #PB_Compiler_EnumerationValue

;============================================================================================================================
; 
;============================================================================================================================

CatchImage(#Image_bakker_bsave,     ?_OPT_bakker_bsave)
CatchImage(#Image_bakker_brun,      ?_OPT_bakker_brun)
CatchImage(#Image_bakker_blocation, ?_OPT_bakker_blocation)

;============================================================================================================================
; 
;============================================================================================================================

DataSection
  _OPT_bakker_bsave:      IncludeBinary "\Development\Resources\Forms\Images\savelist48x48.ico"
  _OPT_bakker_brun:       IncludeBinary "\Development\Resources\Forms\Images\run48x48.ico"
  _OPT_bakker_blocation:  IncludeBinary "\Development\Resources\Forms\Images\file48x48.ico"
EndDataSection

;============================================================================================================================
; 
;============================================================================================================================

Procedure.l Window_bakker()
  If OpenWindow(#Window_bakker,56,67,800,600,#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered|#PB_Window_Invisible,"FileBakker")
    If CreateGadgetList(WindowID(#Window_bakker))
      ExplorerTreeGadget(#Gadget_bakker_dirtree,0,0,200,260,"",#PB_Explorer_NoFiles|#PB_Explorer_NoDriveRequester|#PB_Explorer_AutoSort)
      ExplorerListGadget(#Gadget_bakker_filetree,205,0,595,260,"",#PB_Explorer_MultiSelect|#PB_Explorer_GridLines|#PB_Explorer_FullRowSelect|#PB_Explorer_NoFolders|#PB_Explorer_NoParentFolder|#PB_Explorer_NoDirectoryChange|#PB_Explorer_NoDriveRequester|#PB_Explorer_AutoSort)
      ListIconGadget(#Gadget_bakker_filebackup,0,265,800,255,"Filename",690,#PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect|#PB_ListIcon_AlwaysShowSelection|#PB_ListIcon_MultiSelect)
        AddGadgetColumn(#Gadget_bakker_filebackup,1,"Status",80)
      ButtonImageGadget(#Gadget_bakker_bsave,0,525,55,55,ImageID(#Image_bakker_bsave))
      ButtonImageGadget(#Gadget_bakker_brun,55,525,55,55,ImageID(#Image_bakker_brun))
      ButtonImageGadget(#Gadget_bakker_blocation,110,525,55,55,ImageID(#Image_bakker_blocation))
      Frame3DGadget(#Gadget_bakker_fmain,170,518,630,30,"")
      OptionGadget(#Gadget_bakker_cbdateyear,175,530,130,15,"Backup as ddmmyyyy")
      OptionGadget(#Gadget_bakker_cbdayhour,305,530,160,15,"Backup as ddmmyyyy-hhmm")
      CheckBoxGadget(#Gadget_bakker_cblocation,465,530,170,15,"Backup only to named volume")
      Frame3DGadget(#Gadget_bakker_flocation,170,543,630,35,"")
      TextGadget(#Gadget_bakker_llocation,175,560,85,15,"Backup location")
      StringGadget(#Gadget_bakker_location,260,555,535,20,"",#PB_String_ReadOnly)
      TextGadget(#Gadget_bakker_lvolume,645,530,150,15,"")
      CreateStatusBar(#StatusBar_bakker,WindowID(#Window_bakker))
        AddStatusBarField(670)
        AddStatusBarField(130)
      HideWindow(#Window_bakker,0)
      ProcedureReturn WindowID(#Window_bakker)
    EndIf
  EndIf
EndProcedure

;============================================================================================================================
; My personal constants
;============================================================================================================================

#Version                      = "v0.00"                                                         ; Program version
#CopyRight                    = "<°)))o><²³ Baker Admin(c) 2006, PeriTek Visions  " + #Version  ; Copyright string
#Eol                          = Chr(10) + Chr(13)                                               ; End of line marker

;============================================================================================================================
; Custom date routine structure
;============================================================================================================================

Structure DateStructure ; Custom date routine
  Year.w
  Month.w
  DayOfWeek.w
  Day.w
  Hour.w
  Minute.w
  Second.w
  Milliseconds.w
EndStructure

;============================================================================================================================
; Window data structure
;============================================================================================================================

Structure windowdata   ; Window structure data
  winhandle.l           ; Main window handle
  statushandle.l        ; Statusbar handle
  mutex.l               ; Prevent multiple windows from opening
EndStructure

;==============================================================================================================================
; Program data structure
;==============================================================================================================================

Structure programdata  ; Program data structure
  curdir.s              ; Current program startup directory
  progquit.l            ; User quit the program, so set the quit value to allow program to end repeat loop
  inifile.s             ; Name and path of the options file
  curline.l             ; Always the current line in the list object
  daynum.l              ; Numerical day of the week mapped to word format
  weekday.s             ; Named day of the week
  ;---------------------------------------------------------
  backupto.s
  volume.s
  dateformat.s
  volforce.s
  ;---------------------------------------------------------
  fileid.l
  filecounter.l
  curfile.s
  dirdate.s
  newpath.s
  oldpath.s
EndStructure

;==============================================================================================================================
; All global variables
;==============================================================================================================================

Global program.programdata, form.windowdata

;==============================================================================================================================
; Get current direectory and store it for later
;==============================================================================================================================

program\curdir = Space(512)                                          ; Give the variable enough space

If GetCurrentDirectory_(Len(program\curdir), @program\curdir) <> 0   ; Get the current directory
  If Right(program\curdir, 1) <> "\"                                 ; Each O/S does it differently so check for backspace
    program\curdir + "\"
  EndIf
EndIf

;==============================================================================================================================
; Create local picture and icon directory variables
;==============================================================================================================================

;==============================================================================================================================
; Setup day and month literal names
;==============================================================================================================================

Global Dim NameOfDay.s(7)                                        ; Fill an array with the names of the days (Terry Hough I think)

  NameOfDay(0)      = "Sunday"
  NameOfDay(1)      = "Monday"
  NameOfDay(2)      = "Tuesday"
  NameOfDay(3)      = "Wednesday"  
  NameOfDay(4)      = "Thursday"
  NameOfDay(5)      = "Friday"
  NameOfDay(6)      = "Saturday"

Global Dim DaysPerMonth(12)                                      ; Fill an array on how many days per month there are

  For X = 0 To 11     
    DaysPerMonth(X) = 31 
  Next

  DaysPerMonth(1)   = 28
  DaysPerMonth(3)   = 30
  DaysPerMonth(5)   = 30
  DaysPerMonth(8)   = 30

  DaysPerMonth(10)  = 30

Global Dim NameOfMonth.s(12)                                    ; fill an array with the names of the months

  NameOfMonth(0)    = "January"
  NameOfMonth(1)    = "February"
  NameOfMonth(2)    = "March" 
  NameOfMonth(3)    = "April"
  NameOfMonth(4)    = "May"
  NameOfMonth(5)    = "June" 
  NameOfMonth(6)    = "July"
  NameOfMonth(7)    = "August"
  NameOfMonth(8)    = "September"
  NameOfMonth(9)    = "October"
  NameOfMonth(10)   = "November"
  NameOfMonth(11)   = "December"

Global Dim Years.s(7)                                           ; fill an array with the years

  Years(0)          = "2002"
  Years(1)          = "2003"
  Years(2)          = "2004"
  Years(3)          = "2005"
  Years(4)          = "2006" 
  Years(5)          = "2007"
  Years(6)          = "2008"

;==============================================================================================================================
; 
;==============================================================================================================================

Enumeration #GadgetIndex
  #Shortcut_bakker_Delete
  #Splitter_Bakker_Vertical
  #Splitter_Bakker_Horizontal
EndEnumeration

;==============================================================================================================================
; 
;==============================================================================================================================

Enumeration #ImageIndex   ; Use last image enumeration, continued from purevision created form
  #Image_bakker_messages   ; This is the mssages in the status bar
  #Image_bakker_records    ; This is the number of records in the status bar
  #Image_bakker_listfiles  ; This is the icon used in the main items list
EndEnumeration

;==============================================================================================================================
; Grab the images to memory for use
;==============================================================================================================================

CatchImage(#Image_bakker_messages,   ?_PTK_bakker_messages)
CatchImage(#Image_bakker_records,    ?_PTK_bakker_records)
CatchImage(#Image_bakker_listfiles,  ?_PTK_bakker_listfiles)

;==============================================================================================================================
; All processable data
;==============================================================================================================================

DataSection
  _PTK_bakker_messages   : IncludeBinary "C:\Development\Resources\Forms\Images\messages16x16.ico"
  _PTK_bakker_records    : IncludeBinary "C:\Development\Resources\Forms\Images\records16x16.ico"
  _PTK_bakker_listfiles  : IncludeBinary "C:\Development\Resources\Forms\Images\files16x16.ico"
EndDataSection


;============================================================================================================================
; Universal, recursive search engine used by many functions
;============================================================================================================================

Procedure SearchEngine(SearchDir.s)
  NewList FoundDirs.s()
  If SearchDir.s <> ""
    If Right(SearchDir.s, 1) = "\"
      SearchDir.s = Left(SearchDir.s, Len(SearchDir.s) - 1)
    EndIf
    AddElement(FoundDirs.s())
    FoundDirs.s() = SearchDir.s
    Index = 0
    Repeat
      SelectElement(FoundDirs.s(), Index)
      If ExamineDirectory(0, FoundDirs.s(), "*.*")
        Path.s = FoundDirs.s() + "\"
        While NextDirectoryEntry(0)
          Filename.s = DirectoryEntryName(0)
          Select DirectoryEntryType(0)
            Case 1
              program\filecounter + 1
              DiskFile.s = Path.s + Filename.s            ; Add path and file together (file\path, file\file)
              While WindowEvent() : Wend                ; Clear the window buffer to avoid forms greying out
              AddGadgetItem(#Gadget_bakker_filebackup, -1, DiskFile.s + Chr(10) + "", ImageID(#Image_bakker_listfiles))
              SendMessage_(GadgetID(#Gadget_bakker_filebackup), #LVM_ENSUREVISIBLE, program\filecounter -1, 0) ; Make sure the current line is visible
              StatusBarText(#StatusBar_bakker, #StatusBar_bakker_messages, "Processing: " + DiskFile.s)
              StatusBarText(#StatusBar_bakker, #StatusBar_bakker_records,  "File: "       + Str(program\filecounter))
            Case 2
              Filename.s = DirectoryEntryName(0)
              If Filename.s <> ".." And Filename.s <> "."
                AddElement(FoundDirs())
                FoundDirs() = Path + Filename.s
              EndIf
          EndSelect
        Wend
      EndIf
      Index + 1
    Until Index > CountList(FoundDirs()) -1
  EndIf
EndProcedure

;============================================================================================================================
; Personal balloon tooltip window, colourful and not boring at all.
;============================================================================================================================

Procedure MyBalloonTips(btWindow.l, btGadget.l, btText.s)
  ToolTipControl = CreateWindowEx_(0, "ToolTips_Class32", "", $D0000000 | $40, 0, 0, 0, 0, WindowID(btWindow), 0, GetModuleHandle_(0), 0)
  SendMessage_(ToolTipControl, 1044, 0, 0)
  SendMessage_(ToolTipControl, 1043, $F3D97A, 0)
  SendMessage_(ToolTipControl, 1048, 0, 180)
  Button.TOOLINFO\cbSize = SizeOf(TOOLINFO)
  Button\uFlags   = $11
  Button\hWnd     = GadgetID(btGadget)
  Button\uId      = GadgetID(btGadget)
  Button\lpszText = @btText
  SendMessage_(ToolTipControl, $0404, 0, Button)
EndProcedure

;============================================================================================================================
; Adds a suffix To the End of a <= 31 numeral 'date'
;============================================================================================================================

Procedure.s AddDateSuffix(Date.s)
  If Date = "1" Or Date = "21" Or Date = "31"
    Date = Date + "st"
  ElseIf Date = "2" Or Date = "22"
    Date = Date + "nd"
  ElseIf Date = "3" Or Date = "23"
    Date = Date + "rd"
  Else
    Date = Date + "th"
  EndIf
  ProcedureReturn Date
EndProcedure

;============================================================================================================================
; Get the current date and the day of the week in word form
;============================================================================================================================

Procedure GetDayOfWeek(Gadget.l)
  program\daynum = DayOfWeek(ParseDate("%dd/%mm/%yyyy", GetGadgetText(Gadget.l)))
  Select program\daynum
    Case 0 : program\weekday = "Sunday"
    Case 1 : program\weekday = "Monday" 
    Case 2 : program\weekday = "Tuesday" 
    Case 3 : program\weekday = "Wednesday"
    Case 4 : program\weekday = "Thursday"
    Case 5 : program\weekday = "Friday"
    Case 6 : program\weekday = "Saturday"
  EndSelect
EndProcedure

;============================================================================================================================
; Sort out the date and display it
;============================================================================================================================

Procedure SetDate(Windowid.l)
  newDate.dateStructure
  GetSystemTime_(@newDate)
  WeekDay.b = newDate\DayOfWeek
  Day.b     = newDate\Day
  Month.b   = newDate\Month
  Year.w    = newDate\Year
  CurrentDate.s = NameOfDay(WeekDay) + ", " + AddDateSuffix(Str(Day)) + ", " + NameOfMonth(Month - 1) + ", " + Str(Year)
  SetWindowTitle(Windowid.l, #CopyRight + "   --   Today is " + CurrentDate.s)
EndProcedure

;============================================================================================================================
; Custom statusbar routine
;============================================================================================================================

Procedure SetStat(Field.l, Message.s)
  StatusBarText(#StatusBar_bakker, Field.l, Message.s, 0)
EndProcedure

;============================================================================================================================
; 
;============================================================================================================================

Procedure.s GetDriveLabel(drivename.s)
  lpRootPathName.s          = drivename.s
  pVolumeNameBuffer.s       = Space(256)
  nVolumeNameSize.l         = 256
  lpVolumeSerialNumber.l
  lpMaximumComponentLength.l
  lpFileSystemFlags.l
  lpFileSystemNameBuffer.s  = Space(256)
  nFileSystemNameSize.l     = 256
  Result = GetVolumeInformation_(lpRootPathName, pVolumeNameBuffer, 256, @lpVolumeSerialNumber, @lpMaximumComponentLength, @lpFileSystemFlags, lpFileSystemNameBuffer, 256)
  ProcedureReturn LTrim(pVolumeNameBuffer)
EndProcedure

;============================================================================================================================
; See if an INI file exists in the program directory and create one if not
;============================================================================================================================

   OsVer = OSVersion()                                               ; Get current OS Version variable
 
   Select OsVer
     Case #PB_OS_Windows_NT3_51      :  disableanimate = 0          ; API Animate window not supported
     Case #PB_OS_Windows_95          :  disableanimate = 0          ; API Animate window not supported
     Case #PB_OS_Windows_NT_4        :  disableanimate = 0          ; API Animate window not supported
     Case #PB_OS_Windows_98          :  disableanimate = 1          ; API Animate window supported
     Case #PB_OS_Windows_ME          :  disableanimate = 1          ; API Animate window supported
     Case #PB_OS_Windows_2000        :  disableanimate = 1          ; API Animate window supported
     Case #PB_OS_Windows_XP          :  disableanimate = 1          ; API Animate window supported
     Case #PB_OS_Windows_Server_2003 :  disableanimate = 1          ; API Animate window supported
     Case #PB_OS_Windows_Future      :  disableanimate = 1          ; API Animate window supported
   EndSelect

;============================================================================================================================
; 
;============================================================================================================================

If Window_bakker()

  ;----------------------------------------------------------------------------------------------------------
  ; Setup window date and copyright
  ;---------------------------------------------------------------------------------------------------------- 
  SetDate(#Window_bakker)
  
  ;----------------------------------------------------------------------------------------------------------
  ; Setup statusbar colours and icons
  ;---------------------------------------------------------------------------------------------------------- 
  StatusBarIcon(#StatusBar_bakker, #StatusBar_bakker_messages, ImageID(#Image_bakker_messages))    ; Add the message and record statusbar icons
  StatusBarIcon(#StatusBar_bakker, #StatusBar_bakker_records,  ImageID(#Image_bakker_records))

  ;----------------------------------------------------------------------------------------------------------
  ; Setup screen and object tooltips now
  ;----------------------------------------------------------------------------------------------------------
  MyBalloonTips(#Window_bakker, #Gadget_bakker_dirtree,     "Single left click on an item in this tree to show files in that selected directory in the list to the right and double left click to send all files recursively to the backup list below")
  MyBalloonTips(#Window_bakker, #Gadget_bakker_filetree,    "Double left click to send the highlighted file to the backup list and double right click to launch it with the system associated shortcut")
  MyBalloonTips(#Window_bakker, #Gadget_bakker_filebackup,  "Double left click on an item in this list to delete it from the backup list")
  MyBalloonTips(#Window_bakker, #Gadget_bakker_bsave,       "Click this button to save all the selected files and setting to a backup control file")
  MyBalloonTips(#Window_bakker, #Gadget_bakker_brun,        "Click this button to run the backup job now")
  MyBalloonTips(#Window_bakker, #Gadget_bakker_blocation,   "Click this button to set the location for the backup job")
  MyBalloonTips(#Window_bakker, #Gadget_bakker_cbdateyear,  "Check this radio button to set the base backup name using the format ddmmyyyy")
  MyBalloonTips(#Window_bakker, #Gadget_bakker_cbdayhour,   "Check this radio button to set the base backup name using the format ddmmyyyy:hhmm")
  MyBalloonTips(#Window_bakker, #Gadget_bakker_cblocation,  "Check this radio button to allow the backup to only be performed to the named volume")
  MyBalloonTips(#Window_bakker, #Gadget_bakker_location,    "This is the drive and directory that the backup job is currently set to and will only work if filled!")
  MyBalloonTips(#Window_bakker, #Gadget_bakker_lvolume,     "This is the label of the drive to which you are allowed to backup to")

  AddKeyboardShortcut(#Window_bakker, #PB_Shortcut_Delete, #Shortcut_bakker_Delete)
  
  SplitterGadget(#Splitter_Bakker_Vertical, 0, 0, 800, 260, #Gadget_bakker_dirtree, #Gadget_bakker_filetree, #PB_Splitter_Vertical|#PB_Splitter_Separator)
  SetGadgetState(#Splitter_Bakker_Vertical, 203)
  SplitterGadget(#Splitter_Bakker_Horizontal, 0, 0, 800, 520, #Splitter_Bakker_Vertical, #Gadget_bakker_filebackup, #PB_Splitter_Separator)
  
  SetActiveWindow(#Window_bakker)
  
  ;----------------------------------------------------------------------------------------------------------
  ; Read in config items if present
  ;---------------------------------------------------------------------------------------------------------- 
  If FileSize("Bakker batch job.txt") <> -1
  
    program\fileid = ReadFile(#PB_Any, "Bakker batch job.txt")
    
    ReadString(program\fileid) ; Read config start heading, just junk string
                              
    program\backupto    =     StringField(ReadString(program\fileid), 2, "=")

    SetGadgetText(#Gadget_bakker_location, program\backupto)
      
    program\dateformat  =     StringField(ReadString(program\fileid), 2, "=")

    If program\dateformat  = "ddmmyyyy-hhmm"
      SetGadgetState(#Gadget_bakker_cbdayhour, 1)
    ElseIf program\dateformat  = "ddmmyyyy"
      SetGadgetState(#Gadget_bakker_cbdateyear, 1)
    EndIf
      
    program\volforce    =     StringField(ReadString(program\fileid), 2, "=")

    If program\volforce = "Yes"
      SetGadgetState(#Gadget_bakker_cblocation, 1)
    Else
      SetGadgetState(#Gadget_bakker_cblocation, 0)
    EndIf
      
    program\volume      =     StringField(ReadString(program\fileid), 2, "=")

    SetGadgetText(#Gadget_bakker_lvolume, "Volume: [" + program\volume + "]")
      
    program\filecounter = Val(StringField(ReadString(program\fileid), 2, "=")) : 
                                  
    ReadString(program\fileid) ; Read config end heading, just junk string
                                  
    ClearGadgetItemList(#Gadget_bakker_filebackup)    
    
    For FilesIn.l = 0 To program\filecounter - 1
        program\curfile = ReadString(program\fileid)
       AddGadgetItem(#Gadget_bakker_filebackup, -1, program\curfile + Chr(10) + "Loaded")
       SetGadgetItemColor(#Gadget_bakker_filebackup, FilesIn, #PB_Gadget_FrontColor, $7CE383, 1)
       SendMessage_(GadgetID(#Gadget_bakker_filebackup), #LVM_ENSUREVISIBLE, FilesIn.l, 0)
       While WindowEvent() : Wend
       SetStat(#StatusBar_bakker_messages, "Loaded: " + program\curfile)                        ; Show failed in statusbar
       SetStat(#StatusBar_bakker_records,  "File: "   + Str(FilesIn))                           ;
    Next FilesIn.l
    
    CloseFile(program\fileid)
    
    program\fileid = -1
  EndIf

  ;----------------------------------------------------------------------------------------------------------
  ; Set the program quit semaphore
  ;---------------------------------------------------------------------------------------------------------- 
  program\progquit = 0
  
  ;----------------------------------------------------------------------------------------------------------
  ; Now start monitoring events
  ;---------------------------------------------------------------------------------------------------------- 
  Repeat

    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        If EventWindow() = #Window_bakker
          program\progquit = 1
        EndIf
      Case #PB_Event_Menu
        Select EventMenu()
          Case #Shortcut_bakker_Delete              : Gosub DeleteFromBackup
        EndSelect
      Case #PB_Event_Gadget
        Select EventGadget()
          Case #Gadget_bakker_dirtree               
            Select EventType()
              Case #PB_EventType_LeftClick          : Gosub ShowFilesFromTree
              Case #PB_EventType_LeftDoubleClick    : Gosub GetDirsFromTree
              Case #PB_EventType_RightDoubleClick   : 
              Case #PB_EventType_RightClick         : 
            EndSelect
          Case #Gadget_bakker_filetree
            Select EventType()
              ;Case #PB_EventType_LeftClick
              Case #PB_EventType_LeftDoubleClick    : Gosub GetFilesFromList
              Case #PB_EventType_RightDoubleClick   : Gosub RunAFile
              Case #PB_EventType_RightClick         : 
            EndSelect
          Case #Gadget_bakker_filebackup
            Select EventType()
              ;Case #PB_EventType_LeftClick
              Case #PB_EventType_LeftDoubleClick    : Gosub DeleteFileFromList
              Case #PB_EventType_RightDoubleClick   : 
              Case #PB_EventType_RightClick         : 
            EndSelect
          Case #Gadget_bakker_bsave                 : Gosub SaveSettingsAndFiles
          Case #Gadget_bakker_brun                  : Gosub RunBackupJob
          Case #Gadget_bakker_blocation             : Gosub GetBackupLocation
          Case #Gadget_bakker_cbdateyear            : Gosub GetDateFormat
          Case #Gadget_bakker_cbdayhour             : Gosub GetDateFormat
          Case #Gadget_bakker_cblocation            : Gosub GetVolumeForce
        EndSelect

    EndSelect
  Until program\progquit
  CloseWindow(#Window_bakker)
EndIf
End

;============================================================================================================================
ShowFilesFromTree:                ; 
;============================================================================================================================

  SetGadgetText(#Gadget_bakker_filetree, GetGadgetText(#Gadget_bakker_dirtree))
  
Return

;============================================================================================================================
GetDirsFromTree:                  ; 
;============================================================================================================================

  SearchEngine(GetGadgetText(#Gadget_bakker_dirtree))
  
Return

;============================================================================================================================
GetFilesFromList:                 ; 
;============================================================================================================================

  If GetGadgetState(#Gadget_bakker_filetree) <> -1
    program\filecounter + 1
    program\curfile = GetGadgetText(#Gadget_bakker_filetree) + GetGadgetItemText(#Gadget_bakker_filetree, GetGadgetState(#Gadget_bakker_filetree),0)
    AddGadgetItem(#Gadget_bakker_filebackup, -1, program\curfile + Chr(10) + "", ImageID(#Image_bakker_listfiles))
    SetStat(#StatusBar_bakker_messages, "Added: "  + program\curfile)
    SetStat(#StatusBar_bakker_records,  "File: "   + Str(program\filecounter))
  EndIf
  
Return

;============================================================================================================================
RunAFile:                         ; 
;============================================================================================================================

  If GetGadgetState(#Gadget_bakker_filetree) <> -1
    program\curfile = GetGadgetText(#Gadget_bakker_filetree) + GetGadgetItemText(#Gadget_bakker_filetree, GetGadgetState(#Gadget_bakker_filetree),0)
    RunProgram(program\curfile, "", "", 1 | 2)
  EndIf
  
Return

;============================================================================================================================
DeleteFileFromList:               ; 
;============================================================================================================================

  If GetGadgetState(#Gadget_bakker_filebackup) <> -1
    program\curfile = GetGadgetText(#Gadget_bakker_filebackup)
    If DeleteFile(program\curfile) <> 0
      program\filecounter -1
      SendMessage_(GadgetID(#Gadget_bakker_filebackup), #LVM_DELETEITEM, GetGadgetState(#Gadget_bakker_filebackup), 0) ; Delete it now
      SetStat(#StatusBar_bakker_messages, "Deleted: "    + program\curfile)
      SetStat(#StatusBar_bakker_records,  "File: "       + Str(program\filecounter))
    EndIf
  EndIf

Return

;============================================================================================================================
GetBackupLocation:                ; 
;============================================================================================================================

  program\backupto = PathRequester("Select backup path", "")

  If program\backupto <> ""
    program\volume   = GetDriveLabel(Left(program\backupto, 3))
    SetGadgetText(#Gadget_bakker_lvolume, "Volume: [" + program\volume + "]")
    SetGadgetText(#Gadget_bakker_location, program\backupto)
  EndIf

Return

;============================================================================================================================
GetDateFormat:                    ;
;============================================================================================================================

  If GetGadgetState(#Gadget_bakker_cbdateyear) = 1
    program\dateformat = "ddmmyyyy"
  ElseIf GetGadgetState(#Gadget_bakker_cbdayhour) = 1
    program\dateformat = "ddmmyyyy-hhmm"
  EndIf

Return

;============================================================================================================================
GetVolumeForce:
;============================================================================================================================

  If GetGadgetState(#Gadget_bakker_cblocation) = 1
    program\volforce = "Yes"
  EndIf

Return

;============================================================================================================================
SaveSettingsAndFiles:             ; 
;============================================================================================================================

  Gosub GetDateFormat
  
  Gosub GetVolumeForce
  
  If program\backupto = ""
    SetStat(#StatusBar_bakker_messages, "Error: Backup location has not been set, nothing saved")
    Return
  EndIf

  If program\dateformat = ""
    SetStat(#StatusBar_bakker_messages, "Error: Output date format has not been selected, nothing saved")
    Return
  EndIf

  If program\filecounter = 0
    SetStat(#StatusBar_bakker_messages, "Error: There are no files in the backup list, nothing saved")
    Return
  EndIf

  program\fileid = CreateFile(#PB_Any, "Bakker batch job.txt")
  
  WriteStringN(program\fileid, "[Begin Config]")
  WriteStringN(program\fileid, "Backup To       =" + program\backupto)
  WriteStringN(program\fileid, "Date Format     =" + program\dateformat)
  WriteStringN(program\fileid, "Volume Force    =" + program\volforce)
  WriteStringN(program\fileid, "Volume Name     =" + program\volume)
  WriteStringN(program\fileid, "Number Of Files =" + Str(program\filecounter))
  WriteStringN(program\fileid, "[End Config]")
  
  For FilesOut.l = 0 To program\filecounter - 1
    program\curfile = GetGadgetItemText(#Gadget_bakker_filebackup, FilesOut, 0)
    WriteStringN(program\fileid, program\curfile)
    SetStat(#StatusBar_bakker_messages, "Saved: "  + program\curfile)
    SetStat(#StatusBar_bakker_records,  "File: "   + Str(FilesOut))
  Next FilesOut.l
  
  CloseFile(program\fileid)
  
  program\fileid = -1
  
  SetStat(#StatusBar_bakker_messages, "Information: All configuration options and backup filenames have been saved")

Return

;============================================================================================================================
RunBackupJob:
;============================================================================================================================

  Gosub GetDateFormat
  
  Gosub GetVolumeForce

  If program\backupto = ""
    SetStat(#StatusBar_bakker_messages, "Error: Backup location has not been set, nothing saved")
    Return
  EndIf

  If program\dateformat = ""
    SetStat(#StatusBar_bakker_messages, "Error: Output date format has not been selected, nothing saved")
    Return
  EndIf

  If program\filecounter = 0
    SetStat(#StatusBar_bakker_messages, "Error: There are no files in the backup list, nothing saved")
    Return
  EndIf

  If program\volforce = "Yes" And program\volume <> GetDriveLabel(Left(program\backupto, 3))
    SetStat(#StatusBar_bakker_messages, "Error: Designated volume label doesn't match current inserted media")
    Return
  EndIf
  
  If program\dateformat = "ddmmyyyy"
    program\dirdate = FormatDate("%dd%mm%yyyy", Date())
  ElseIf program\dateformat = "ddmmyyyy-hhmm"
    program\dirdate = FormatDate("%dd%mm%yyyy-%hh%ii", Date())
  EndIf

  program\newpath = program\backupto + program\dirdate
  
  MakeSureDirectoryPathExists_(program\newpath)

  SendMessage_(GadgetID(#Gadget_bakker_filebackup), #LVM_ENSUREVISIBLE, 0, 0)
  
   For FilesOut.l = 0 To program\filecounter - 1
   
     program\curfile = GetGadgetItemText(#Gadget_bakker_filebackup, FilesOut, 0) ; C:\Stuff\Jobs.txt
     program\oldpath = GetPathPart(program\curfile)                              ; C:\Stuff\
     program\oldpath = Mid(program\curfile, 3, Len(program\curfile) - 2)         ;   \Stuff\
     
     MakeSureDirectoryPathExists_(program\newpath + program\oldpath)
      
     If CopyFile(program\curfile, program\newpath + program\oldpath + GetFilePart(program\curfile)) <> 0
       SetGadgetItemText(#Gadget_bakker_filebackup, FilesOut.l, "Processed", 1)
       SetGadgetItemColor(#Gadget_bakker_filebackup, FilesOut, #PB_Gadget_FrontColor, $D3592C, 1)
       SendMessage_(GadgetID(#Gadget_bakker_filebackup), #LVM_ENSUREVISIBLE, FilesOut.l, 0)
       While WindowEvent() : Wend
       SetStat(#StatusBar_bakker_messages, "Copied: " + program\curfile)
       SetStat(#StatusBar_bakker_records,  "File: "   + Str(FilesOut))
     Else
       SetGadgetItemText(#Gadget_bakker_filebackup, FilesOut.l, "Not Copied", 1)                    ; Failed to copy
       SetGadgetItemColor(#Gadget_bakker_filebackup, FilesOut, #PB_Gadget_FrontColor, $0613F9, 1)   ; Show in red
       While WindowEvent() : Wend                                                                  ; Flush events
       SendMessage_(GadgetID(#Gadget_bakker_filebackup), #LVM_ENSUREVISIBLE, FilesOut.l, 0)         ; Line always visible
       SetStat(#StatusBar_bakker_messages, "Not Copied: " + program\curfile)                        ; Show failed in statusbar
       SetStat(#StatusBar_bakker_records,  "File: "   + Str(FilesOut))                              ;
     EndIf
   Next
  
Return

;============================================================================================================================
DeleteFromBackup:
;============================================================================================================================

  For FilesDel.l = program\filecounter To 0 Step -1
    If GetGadgetItemState(#Gadget_bakker_filebackup, FilesDel) & #PB_ListIcon_Selected
      RemoveGadgetItem(#Gadget_bakker_filebackup, FilesDel.l)
      SendMessage_(GadgetID(#Gadget_bakker_filebackup), #LVM_ENSUREVISIBLE, FilesDel.l, 0)
      program\filecounter - 1
      SetStat(#StatusBar_bakker_records,  "File: "   + Str(program\filecounter))
    EndIf
  Next

Return

client module

Code: Select all

;============================================================================================================================
; 
;============================================================================================================================

Declare   MyBalloonTips(btWindow.l, btGadget.l, btText.s)   ; Custom balloon tooltips.
Declare.s GetDriveLabel(drivename.s)                        ; Get the drive label for a drive name

;============================================================================================================================
; 
;============================================================================================================================

Enumeration 1
  #Window_bclient
EndEnumeration

#WindowIndex = #PB_Compiler_EnumerationValue

Enumeration 1
  #Gadget_bclient_bbackup
  #Shortcut_bclient_exit
EndEnumeration

#GadgetIndex = #PB_Compiler_EnumerationValue

;============================================================================================================================
; My personal constants
;============================================================================================================================

#Version                      = "v0.00"                                                          ; Program version
#CopyRight                    = "<°)))o><²³ Baker Client(c) 2006, PeriTek Visions  " + #Version  ; Copyright string
#Eol                          = Chr(10) + Chr(13)                                                ; End of line marker

;============================================================================================================================
; Window data structure
;============================================================================================================================

Structure windowdata   ; Window structure data
  winhandle.l           ; Main window handle
  statushandle.l        ; Statusbar handle
  mutex.l               ; Prevent multiple windows from opening
EndStructure

;==============================================================================================================================
; Program data structure
;==============================================================================================================================

Structure programdata  ; Program data structure
  curdir.s              ; Current program startup directory
  progquit.l            ; User quit the program, so set the quit value to allow program to end repeat loop
  curline.l             ; Always the current line in the list object
  daynum.l              ; Numerical day of the week mapped to word format
  backupto.s
  volume.s
  dateformat.s
  volforce.s
  fileid.l
  filecounter.l
  dirdate.s
  newpath.s
  oldpath.s
  backup.s
EndStructure

;==============================================================================================================================
; All global variables
;==============================================================================================================================

Global program.programdata, form.windowdata, NewList FileList.s()

;==============================================================================================================================
; Get current direectory and store it for later
;==============================================================================================================================

program\curdir = Space(512)                                          ; Give the variable enough space

If GetCurrentDirectory_(Len(program\curdir), @program\curdir) <> 0   ; Get the current directory
  If Right(program\curdir, 1) <> "\"                                 ; Each O/S does it differently so check for backspace
    program\curdir + "\"
  EndIf
EndIf

;============================================================================================================================
; 
;============================================================================================================================

Procedure.l Window_bclient()
  If OpenWindow(#Window_bclient,205,235,160,140,#PB_Window_BorderLess|#PB_Window_ScreenCentered|#PB_Window_Invisible,"Bakker Client")
    If CreateGadgetList(WindowID(#Window_bclient))
      ButtonGadget(#Gadget_bclient_bbackup,10,10,140,120,"Backup")
        SetGadgetFont(#Gadget_bclient_bbackup,LoadFont(#Gadget_bclient_bbackup,"Arial",26,256))
      HideWindow(#Window_bclient,0)
      ProcedureReturn WindowID(#Window_bclient)
    EndIf
  EndIf
EndProcedure

;============================================================================================================================
; Personal balloon tooltip window, colourful and not boring at all
;============================================================================================================================

Procedure MyBalloonTips(btWindow.l, btGadget.l, btText.s)
  ToolTipControl = CreateWindowEx_(0, "ToolTips_Class32", "", $D0000000 | $40, 0, 0, 0, 0, WindowID(btWindow), 0, GetModuleHandle_(0), 0)
  SendMessage_(ToolTipControl, 1044, 0, 0)
  SendMessage_(ToolTipControl, 1043, $F3D97A, 0)
  SendMessage_(ToolTipControl, 1048, 0, 180)
  Button.TOOLINFO\cbSize = SizeOf(TOOLINFO)
  Button\uFlags   = $11
  Button\hWnd     = GadgetID(btGadget)
  Button\uId      = GadgetID(btGadget)
  Button\lpszText = @btText
  SendMessage_(ToolTipControl, $0404, 0, Button)
EndProcedure

;============================================================================================================================
; 
;============================================================================================================================

Procedure.s GetDriveLabel(drivename.s)
  lpRootPathName.s          = drivename.s
  pVolumeNameBuffer.s       = Space(256)
  nVolumeNameSize.l         = 256
  lpVolumeSerialNumber.l
  lpMaximumComponentLength.l
  lpFileSystemFlags.l
  lpFileSystemNameBuffer.s  = Space(256)
  nFileSystemNameSize.l     = 256
  Result = GetVolumeInformation_(lpRootPathName, pVolumeNameBuffer, 256, @lpVolumeSerialNumber, @lpMaximumComponentLength, @lpFileSystemFlags, lpFileSystemNameBuffer, 256)
  ProcedureReturn LTrim(pVolumeNameBuffer)
EndProcedure

;============================================================================================================================
; 
;============================================================================================================================

If Window_bclient()
 
  AddKeyboardShortcut(#Window_bclient, #PB_Shortcut_Alt | #PB_Shortcut_X, #Shortcut_bclient_exit)
 
  program\progquit = 0
 
  MyBalloonTips(#Window_bclient, #Gadget_bclient_bbackup, "Press this button to start the backup. Click and hold on the button's grey borders to move this button and press ALT + X to exit this window")
 
  SetActiveGadget(#Gadget_bclient_bbackup)

  ;----------------------------------------------------------------------------------------------------------
  ; Read in config items if present
  ;---------------------------------------------------------------------------------------------------------- 
  If FileSize("Bakker batch job.txt") <> -1
    program\fileid = ReadFile(#PB_Any, "Bakker batch job.txt")
    ReadString(program\fileid)
    program\backupto    =     StringField(ReadString(program\fileid), 2, "=")
    program\dateformat  =     StringField(ReadString(program\fileid), 2, "=")
    program\volforce    =     StringField(ReadString(program\fileid), 2, "=")
    program\volume      =     StringField(ReadString(program\fileid), 2, "=")
    program\filecounter = Val(StringField(ReadString(program\fileid), 2, "="))
    ReadString(program\fileid)
    For FilesIn.l = 0 To program\filecounter - 1
       AddElement(FileList.s())
       FileList.s() = ReadString(program\fileid)
    Next FilesIn.l
    CloseFile(program\fileid)
    program\fileid = -1
    MessageRequester("Information","Configuration file and list of files loaded. Backup is ready to go", #PB_MessageRequester_Ok | #MB_ICONINFORMATION)
  Else
    MessageRequester("Error","Configuration file and list of files not found. Program will now exit", #PB_MessageRequester_Ok | #MB_ICONERROR)
    End
  EndIf

  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        If EventWindow() = #Window_bclient
          program\progquit = 1
        EndIf
      Case #WM_LBUTTONDOWN
        SendMessage_(WindowID(#Window_bclient), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)
      Case #PB_Event_Menu
        Select EventMenu()
          Case #Shortcut_bclient_exit   : program\progquit = 1
        EndSelect
      Case #PB_Event_Gadget
        Select EventGadget()
          Case #Gadget_bclient_bbackup  : Gosub RunBackupJob
        EndSelect
    EndSelect
  Until program\progquit
  CloseWindow(#Window_bclient)
EndIf
End

;============================================================================================================================
RunBackupJob:
;============================================================================================================================
  
  If program\backup = "Done"
    If MessageRequester("Error","Backup has already been done, are you sure you want to do it again?", #PB_MessageRequester_YesNo | #MB_ICONERROR) = #PB_MessageRequester_Yes
      program\backup = ""
    Else
      Return
    EndIf
  EndIf
  
  If program\backupto = ""
    MessageRequester("Error","Configuration file has nowhere to backup to specified. Program will now exit", #PB_MessageRequester_Ok | #MB_ICONERROR)
    End
  EndIf

  If program\dateformat = ""
    MessageRequester("Error","Configuration file does not have the backup date format se. Program will now exit", #PB_MessageRequester_Ok | #MB_ICONERROR)
    End
  EndIf

  If program\filecounter = 0
    MessageRequester("Error","Configuration file has has no files to process, file counter was 0. Program will now exit", #PB_MessageRequester_Ok | #MB_ICONERROR)
    End
  EndIf

  If program\volforce = "Yes" And program\volume <> GetDriveLabel(Left(program\backupto, 3))
    MessageRequester("Error","Designated volume label doesn't match current inserted media. Program will now exit", #PB_MessageRequester_Ok | #MB_ICONERROR)
    End
  EndIf
  
  If program\dateformat = "ddmmyyyy"
    program\dirdate = FormatDate("%dd%mm%yyyy", Date())
  ElseIf program\dateformat = "ddmmyyyy-hhmm"
    program\dirdate = FormatDate("%dd%mm%yyyy-%hh%ii", Date())
  EndIf

  program\newpath = program\backupto + program\dirdate
  
  MakeSureDirectoryPathExists_(program\newpath)
  
   ForEach FileList.s()
    FilesOut.l = ListIndex(FileList.s())
    program\oldpath = GetPathPart(FileList.s())                              ; C:\Stuff\
    program\oldpath = Mid(FileList.s(), 3, Len(FileList.s()) - 2)            ;   \Stuff\
    MakeSureDirectoryPathExists_(program\newpath + program\oldpath)
    If CopyFile(FileList.s(), program\newpath + program\oldpath + GetFilePart(FileList.s())) <> 0
      SetGadgetText(#Gadget_bclient_bbackup, Str(FilesOut.l))
      SetGadgetColor(#Gadget_bclient_bbackup, #PB_Gadget_FrontColor, $D3592C)
      While WindowEvent() : Wend
    Else
      SetGadgetText(#Gadget_bclient_bbackup, Str(FilesOut.l))                                      ; Failed to copy
      SetGadgetColor(#Gadget_bclient_bbackup, #PB_Gadget_FrontColor, $0613F9)                      ; Show in red
      SetWindowColor(#Window_bclient, $0613F9)
      While WindowEvent() : Wend                                                                  ; Flush events
    EndIf
  Next
  SetGadgetText(#Gadget_bclient_bbackup, "Backup")
  MessageRequester("Information","File backup finished successfully. Have a nice day!", #PB_MessageRequester_Ok | #MB_ICONINFORMATION)
  program\backup = "Done"
Return

Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4791
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

New version, shareware v1.03beta

Post by Fangbeast »

As a copy of this has been sold to a small police department, I closed the source for security. You can still have the original code above but further changes made will be released only as an exe to protect their functions..

If anyone is interested, there is a small update here for everyone else. Please read the text file.

http://www.penguinbyte.com/apps/pbwebst ... ka103b.rar
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
User avatar
Joakim Christiansen
Addict
Addict
Posts: 2452
Joined: Wed Dec 22, 2004 4:12 pm
Location: Norway
Contact:

Post by Joakim Christiansen »

Cool, so how much do you sell things like this for? :P (don't need to answer)
I like logic, hence I dislike humans but love computers.
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4791
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

G'day

Post by Fangbeast »

Most of my shareware sells for between 10 and 20 dollars. This one was an exception, a special deal between me and an officer for ongoing support.

Mind you, most people ignore my software or don't pay me. Between U3.com and local downloads, I've had 2649 downloads of my Addresser program and have yet to see a single dollar or a comment.

Don't know what that says about it.
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
Pantcho!!
Enthusiast
Enthusiast
Posts: 538
Joined: Tue Feb 24, 2004 3:43 am
Location: Israel
Contact:

Post by Pantcho!! »

It says nothing at all

I have 400 unique visitors to my website every day and you know what?
60% of them just get out in the same time they got in.

its all about marketing to the right people.
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4791
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Post by Fangbeast »

Pantcho, this was a specific reply to Joakim Christiansen, not a request to be instructed about my lack of marketing skills, go and hijaak someone else's thread

:D :D :D :D :evil: :evil: :evil: :evil: :evil:
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
Pantcho!!
Enthusiast
Enthusiast
Posts: 538
Joined: Tue Feb 24, 2004 3:43 am
Location: Israel
Contact:

Post by Pantcho!! »

Schnitzel!
thefool
Always Here
Always Here
Posts: 5875
Joined: Sat Aug 30, 2003 5:58 pm
Location: Denmark

Post by thefool »

Pantcho!! wrote:Schnitzel!
Who calls?
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Post by rsts »

Always some nice 'tips/techniques' in your code.

Thanks for sharing/teaching.

cheers
Post Reply