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 :=
(+"", +"", +"", +"", +"", +"", +"", +"",
+"", +"", +"", +"", +"", +"",
+"", +"", +"", +"", +"", +"");
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;