-- This source is licensed under the Sunset License v1.0 with Ada.Characters.Handling, Ada.Directories, Ada.Exceptions, Ada.Strings.Unbounded, Ada.Text_IO, Deckdata.IO, Deckdata.Process, FLTK.Dialogs, FLTK.Widgets.Boxes, FLTK.Widgets.Buttons.Enter, FLTK.Widgets.Buttons.Light.Check, FLTK.Widgets.Inputs.File, FLTK.Widgets.Groups.Input_Choices, FLTK.Widgets.Groups.Windows.Double, FLTK.Widgets.Progress_Bars; use Ada.Text_IO, Deckdata; package body Deck_Convert_GUI is package Charhand renames Ada.Characters.Handling; package FD renames Ada.Directories; package SU renames Ada.Strings.Unbounded; function "+" (S : in String) return SU.Unbounded_String renames SU.To_Unbounded_String; function "-" (US : in SU.Unbounded_String) return String renames SU.To_String; My_Window : FLTK.Widgets.Groups.Windows.Double.Double_Window := FLTK.Widgets.Groups.Windows.Double.Forge.Create (500, 280, "Anki to Fresh Memory Deck Converter"); Deck_Input : FLTK.Widgets.Inputs.File.File_Input := FLTK.Widgets.Inputs.File.Forge.Create (120, 20, 300, 40, "Input filename:"); Basename_Input : FLTK.Widgets.Inputs.File.File_Input := FLTK.Widgets.Inputs.File.Forge.Create (120, 80, 350, 40, "Output base:"); Fileload_Button : FLTK.Widgets.Buttons.Button := FLTK.Widgets.Buttons.Forge.Create (430, 25, 30, 30, "+"); Force_Check : FLTK.Widgets.Buttons.Light.Check.Check_Button := FLTK.Widgets.Buttons.Light.Check.Forge.Create (50, 150, 20, 20, "Overwrite"); Strip_Check : FLTK.Widgets.Buttons.Light.Check.Check_Button := FLTK.Widgets.Buttons.Light.Check.Forge.Create (50, 180, 20, 20, "Strip Formatting"); Type_Choice : FLTK.Widgets.Groups.Input_Choices.Input_Choice := FLTK.Widgets.Groups.Input_Choices.Forge.Create (250, 160, 60, 30); Start_Button : FLTK.Widgets.Buttons.Enter.Enter_Button := FLTK.Widgets.Buttons.Enter.Forge.Create (370, 160, 80, 30, "Start"); Status_Box : FLTK.Widgets.Boxes.Box := FLTK.Widgets.Boxes.Forge.Create (0, 220, 500, 40, "STATUS: Awaiting orders, sir!"); My_Progress : FLTK.Widgets.Progress_Bars.Progress_Bar := FLTK.Widgets.Progress_Bars.Forge.Create (0, 260, 500, 20); Status_Black : FLTK.Color := FLTK.No_Color; Status_Green : FLTK.Color := 16#00550000#; Status_Red : FLTK.Color := FLTK.Red_Color; Bar_Blue : FLTK.Color := 16#00005500#; procedure Activate_All is begin Deck_Input.Activate; Basename_Input.Activate; Fileload_Button.Activate; Force_Check.Activate; Strip_Check.Activate; Type_Choice.Activate; Start_Button.Activate; end Activate_All; procedure Deactivate_All is begin Deck_Input.Deactivate; Basename_Input.Deactivate; Fileload_Button.Deactivate; Force_Check.Deactivate; Strip_Check.Deactivate; Type_Choice.Deactivate; Start_Button.Deactivate; end Deactivate_All; procedure Fileload_Callback (Item : in out FLTK.Widgets.Widget'Class) is Filename : String := FLTK.Dialogs.File_Chooser ("Select File?", "*", "", True); begin Deck_Input.Set_Value (Filename); Basename_Input.Set_Value (FD.Base_Name (Filename)); exception when Fail : FD.Name_Error => Ada.Text_IO.Put_Line (Standard_Error, "WARNING: Invalid filename selected"); end Fileload_Callback; procedure Start_Callback (Item : in out FLTK.Widgets.Widget'Class) is begin Deactivate_All; My_Window.Redraw; Worker.Start_Process; end Start_Callback; procedure Quit_Callback (Item : in out FLTK.Widgets.Widget'Class) is begin abort Worker; Hide; end Quit_Callback; procedure Show is begin My_Window.Show; end Show; procedure Hide is begin My_Window.Hide; end Hide; task body Worker is use type FLTK.Widgets.Buttons.State; use type SU.Unbounded_String; Deck_Format : SU.Unbounded_String; Input_Name : SU.Unbounded_String; Output_Name : SU.Unbounded_String; Overwrite : Boolean; Strip_Form : Boolean; Deck : Deckdata.IO.Deck_Handle; Models : Model_Map; Notes : Note_Vector; Media : Media_Collection; begin loop accept Start_Process; My_Progress.Set_Value (0.0); My_Progress.Redraw; Models.Clear; Notes.Clear; Media.Map.Clear; Deck_Format := +Type_Choice.Get_Input; Input_Name := +Deck_Input.Get_Value; Output_Name := +Basename_Input.Get_Value; Overwrite := Force_Check.Get_State = FLTK.Widgets.Buttons.On; Strip_Form := Strip_Check.Get_State = FLTK.Widgets.Buttons.On; if Deck_Format = "" then Put_Line (Standard_Error, "WARNING: No output deck format selected. " & "Proceeding with FMD as default."); Deck_Format := +"fmd"; else Deck_Format := +(Charhand.To_Lower (-Deck_Format)); end if; if Deck_Format /= "csv" and Deck_Format /= "fmd" then Status_Box.Set_Label ("ERROR: Output deck format must be csv or fmd"); Status_Box.Set_Label_Color (Status_Red); Status_Box.Redraw_Label; elsif Input_Name = "" then Status_Box.Set_Label ("ERROR: No input deck provided"); Status_Box.Set_Label_Color (Status_Red); Status_Box.Redraw_Label; elsif not FD.Exists (-Input_Name) then Status_Box.Set_Label ("ERROR: Input deck does not exist"); Status_Box.Set_Label_Color (Status_Red); Status_Box.Redraw_Label; elsif Output_Name = "" then Status_Box.Set_Label ("ERROR: No output base name provided"); Status_Box.Set_Label_Color (Status_Red); Status_Box.Redraw_Label; elsif FD.Exists ((-Output_Name) & "." & (-Deck_Format)) and not Overwrite then Status_Box.Set_Label ("ERROR: Output deck file name already exists"); Status_Box.Set_Label_Color (Status_Red); Status_Box.Redraw_Label; else Status_Box.Set_Label_Color (Status_Black); Status_Box.Set_Label ("MESSAGE: Opening input deck database..."); Status_Box.Redraw_Label; Deckdata.IO.Open_Database (-Input_Name, Deck); My_Progress.Set_Value (15.0); My_Progress.Redraw; Status_Box.Set_Label ("MESSAGE: Querying models..."); Status_Box.Redraw_Label; Deckdata.IO.Query_Models (Deck, Models); My_Progress.Set_Value (30.0); My_Progress.Redraw; Status_Box.Set_Label ("MESSAGE: Querying notes..."); Status_Box.Redraw_Label; Deckdata.IO.Query_Notes (Deck, Notes); My_Progress.Set_Value (45.0); My_Progress.Redraw; Status_Box.Set_Label ("MESSAGE: Closing database..."); Status_Box.Redraw_Label; Deckdata.IO.Close_Database (Deck); My_Progress.Set_Value (60.0); My_Progress.Redraw; if Strip_Form then Status_Box.Set_Label ("MESSAGE: Stripping formatting from notes..."); Status_Box.Redraw_Label; Deckdata.Process.Strip_Formatting (Notes); My_Progress.Set_Value (70.0); My_Progress.Redraw; end if; declare Contain_Dir : String := FD.Containing_Directory (-Output_Name); Simple_Name : String := FD.Simple_Name (-Output_Name); begin if Deck_Format = "csv" then Status_Box.Set_Label ("MESSAGE: Writing output to csv..."); Status_Box.Redraw_Label; Deckdata.IO.Write_CSV (Contain_Dir, Simple_Name, Models, Notes, Overwrite); My_Progress.Set_Value (100.0); My_Progress.Redraw; Status_Box.Set_Label ("STATUS: Complete success!"); Status_Box.Set_Label_Color (Status_Green); Status_Box.Redraw_Label; elsif Deck_Format = "fmd" then Status_Box.Set_Label ("MESSAGE: Reading media..."); Status_Box.Redraw_Label; Deckdata.IO.Read_Media_Collection (-Input_Name, Media); My_Progress.Set_Value (85.0); My_Progress.Redraw; Status_Box.Set_Label ("MESSAGE: Writing output to fmd..."); Status_Box.Redraw_Label; Deckdata.IO.Write_FMD (Contain_Dir, Simple_Name, Models, Notes, Media, Overwrite); My_Progress.Set_Value (100.0); My_Progress.Redraw; Status_Box.Set_Label ("STATUS: Complete success!"); Status_Box.Set_Label_Color (Status_Green); Status_Box.Redraw_Label; else Status_Box.Set_Label ("ERROR: This shouldn't happen!?"); Status_Box.Set_Label_Color (Status_Red); Status_Box.Redraw_Label; end if; end; end if; Activate_All; My_Window.Redraw; end loop; end Worker; begin My_Window.Add (Deck_Input); My_Window.Add (Basename_Input); Fileload_Button.Set_Callback (Fileload_Callback'Access); My_Window.Add (Fileload_Button); My_Window.Add (Force_Check); My_Window.Add (Strip_Check); Type_Choice.Menu_Button.Add ("fmd"); Type_Choice.Menu_Button.Add ("csv"); My_Window.Add (Type_Choice); Status_Box.Set_Box (FLTK.No_Box); Status_Box.Set_Label_Color (Status_Green); My_Window.Add (Status_Box); Start_Button.Set_Callback (Start_Callback'Access); My_Window.Add (Start_Button); My_Progress.Set_Selection_Color (Bar_Blue); My_Progress.Set_Minimum (0.0); My_Progress.Set_Maximum (100.0); My_Window.Add (My_Progress); My_Window.Set_Callback (Quit_Callback'Access); end Deck_Convert_GUI;