diff options
-rw-r--r-- | freshdeck.gpr | 5 | ||||
-rw-r--r-- | freshdeck_gui.gpr | 37 | ||||
-rw-r--r-- | src/deck_convert_gui.adb | 361 | ||||
-rw-r--r-- | src/deck_convert_gui.ads | 16 | ||||
-rw-r--r-- | src/gui_main.adb | 16 |
5 files changed, 431 insertions, 4 deletions
diff --git a/freshdeck.gpr b/freshdeck.gpr index d5b0450..41d0bf8 100644 --- a/freshdeck.gpr +++ b/freshdeck.gpr @@ -1,6 +1,5 @@ --- with "fltkada"; with "gnatcoll"; with "zipada_lib"; @@ -14,12 +13,11 @@ project Freshdeck is for Source_Dirs use ("src/**"); for Object_Dir use "obj"; for Exec_Dir use "bin"; - for Main use ("deck_convert.adb"); -- , "deck_convert_gui.adb"); + for Main use ("deck_convert.adb"); package Builder is for Executable ("deck_convert.adb") use "deckconv"; - -- for Executable ("deck_convert_gui.adb") use "gdeckconv"; end Builder; @@ -29,7 +27,6 @@ project Freshdeck is package Linker is - -- for Default_Switches("Ada") use ("-lfltk", "-lfltk_images"); for Default_Switches ("Ada") use ("-lsqlite3"); end Linker; diff --git a/freshdeck_gui.gpr b/freshdeck_gui.gpr new file mode 100644 index 0000000..2e9804e --- /dev/null +++ b/freshdeck_gui.gpr @@ -0,0 +1,37 @@ + + +with "fltkada"; +with "gnatcoll"; +with "zipada_lib"; + + +project Freshdeck_GUI is + + + for Languages use ("Ada"); + + + for Source_Dirs use ("src/**"); + for Object_Dir use "obj"; + for Exec_Dir use "bin"; + for Main use ("gui_main.adb"); + + + package Builder is + for Executable ("gui_main.adb") use "gdeckconv"; + end Builder; + + + package Compiler is + for Default_Switches ("Ada") use ("-gnaty4aAbcefhiklM100nprt"); + end Compiler; + + + package Linker is + for Default_Switches ("Ada") use ("-lsqlite3", "-lfltk", "-lfltk_images"); + end Linker; + + +end Freshdeck_GUI; + + diff --git a/src/deck_convert_gui.adb b/src/deck_convert_gui.adb new file mode 100644 index 0000000..0c352ed --- /dev/null +++ b/src/deck_convert_gui.adb @@ -0,0 +1,361 @@ + + +with + + Ada.Characters.Handling, + Ada.Directories, + Ada.Exceptions, + Ada.Strings.Unbounded, + Ada.Text_IO, + Datatypes, + Deck_IO, + 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, + Datatypes; + + +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; + + + + + procedure Strip_Formatting + (Notes : in out Note_Vector) + is + procedure Strip + (Text : in out Note; + Item : in String) + is + Position : Natural; + begin + for F of Text.Fields loop + loop + Position := SU.Index + (Source => SU.Unbounded_String (F), + Pattern => Item, + Going => Ada.Strings.Forward, + Mapping => Charhand.To_Lower'Access); + exit when Position = 0; + SU.Delete (SU.Unbounded_String (F), Position, Position + Item'Length - 1); + end loop; + end loop; + end Strip; + + Formatting : array (Positive range <>) of SU.Unbounded_String := + (+"<b>", +"</b>", +"<strong>", +"</strong>", +"<i>", +"</i>", +"<em>", +"</em>", + +"<mark>", +"</mark>", +"<small>", +"</small>", +"<del>", +"</del>", + +"<ins>", +"</ins>", +"<sub>", +"</sub>", +"<sup>", +"</sup>"); + begin + for N of Notes loop + for S of Formatting loop + Strip (N, -S); + end loop; + end loop; + end Strip_Formatting; + + + + + 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 : Deck_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; + Deck_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; + Deck_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; + Deck_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; + Deck_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; + 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; + Deck_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; + Deck_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; + Deck_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; + + diff --git a/src/deck_convert_gui.ads b/src/deck_convert_gui.ads new file mode 100644 index 0000000..3273060 --- /dev/null +++ b/src/deck_convert_gui.ads @@ -0,0 +1,16 @@ + + +package Deck_Convert_GUI is + + procedure Show; + procedure Hide; + +private + + task Worker is + entry Start_Process; + end Worker; + +end Deck_Convert_GUI; + + diff --git a/src/gui_main.adb b/src/gui_main.adb new file mode 100644 index 0000000..914093f --- /dev/null +++ b/src/gui_main.adb @@ -0,0 +1,16 @@ + + +with + + Deck_Convert_GUI, + FLTK; + + +function GUI_Main + return Integer is +begin + Deck_Convert_GUI.Show; + return FLTK.Run; +end GUI_Main; + + |