1+ #include <fileioc.h>
2+ #include <string.h>
3+ #include <stdbool.h>
14#include "settings.h"
25#include "printbigint.h"
36#include "inputbigint.h"
47#include "statusbar.h"
58
69#define SETTINGS_FILE_HEADER "Programmer's Calculator settings"
10+ #define SETTINGS_FILE_NAME "ProgCalc"
11+ #define VERSION_ID 1
712
813Settings_t Settings ;
914
1015
16+ typedef struct
17+ {
18+ char IdString [sizeof (SETTINGS_FILE_HEADER )];
19+ uint8_t VersionId ;
20+ size_t Size ;
21+ Settings_t Settings ;
22+ } FileSettings_t ;
23+
24+
1125void Settings_Initialize (void )
1226{
13- Settings .PrimaryBase = NO_BASE ;
14- Settings_ChangePrimaryBase (HEXADECIMAL );
27+ ti_var_t file ;
28+ FileSettings_t * fileData ;
29+ ti_CloseAll ();
30+ /* Initialize all settings to default values, then try to load settings from file.
31+ * This allows settings stored in an older version of the settings file to be loaded, while newer settings get their defaults. */
32+ Settings .PrimaryBase = HEXADECIMAL ;
1533 Settings .SecondaryBase = NO_BASE ;
1634 Settings .AlwaysShowBin = false;
1735 Settings .AlwaysShowOct = false;
1836 Settings .AlwaysShowDec = false;
1937 Settings .AlwaysShowHex = false;
20- Settings_ChangeDisplayBits (SHOW_64 );
21- StatusBar_Enable ();
38+ Settings .DisplayBits = SHOW_64 ;
39+ Settings .StatusBarEnabled = true;
40+ /* Look for settings file */
41+ file = ti_Open (SETTINGS_FILE_NAME , "r" );
42+ do
43+ {
44+ if (!file )
45+ break ;
46+ fileData = ti_GetDataPtr (file );
47+ if (strncmp (& fileData -> IdString , SETTINGS_FILE_HEADER , sizeof (SETTINGS_FILE_HEADER )))
48+ break ;
49+ memcpy (& Settings , & fileData -> Settings , fileData -> Size );
50+ } while (false);
51+ ti_Close (file );
52+ Format_ConfigureDisplaySizes ();
53+ GetBigInt_Reposition ();
54+ if (Settings .StatusBarEnabled )
55+ StatusBar_Enable ();
2256}
2357
2458
@@ -87,5 +121,50 @@ char* GetBaseLongName(Base_t base)
87121
88122void Settings_Finalize (void )
89123{
90- /* At some point, add some code here to save settings back to an appvar. */
124+ ti_var_t file ;
125+ FileSettings_t * fileData ;
126+ size_t size = sizeof (Settings_t );
127+ int archived = 0 ;
128+ file = ti_Open (SETTINGS_FILE_NAME , "r" );
129+ do
130+ {
131+ if (!file )
132+ break ;
133+ fileData = ti_GetDataPtr (file );
134+ if (strncmp (& fileData -> IdString , SETTINGS_FILE_HEADER , sizeof (SETTINGS_FILE_HEADER )))
135+ return ;
136+ archived = ti_IsArchived (file );
137+ ti_Close (file );
138+ /* Check if settings have changed. If they haven't, there's no need to update anything. */
139+ /* We're also going to use what should be a stale pointer, but it's fine, really, just trust me. */
140+ if (fileData -> VersionId == VERSION_ID && !memcmp (& Settings , & fileData -> Settings , sizeof (Settings_t )))
141+ return ;
142+ if (!ti_Delete (SETTINGS_FILE_NAME ))
143+ return ;
144+ } while (false);
145+ ti_Close (file );
146+ file = ti_Open (SETTINGS_FILE_NAME , "w" );
147+ do
148+ {
149+ if (!file )
150+ {
151+ ti_Close (file );
152+ return ;
153+ }
154+ if (!ti_Write (SETTINGS_FILE_HEADER , sizeof (SETTINGS_FILE_HEADER ), 1 , file ))
155+ break ;
156+ if (!ti_PutC (VERSION_ID , file ))
157+ break ;
158+ if (!ti_Write (& size , sizeof (size ), 1 , file ))
159+ break ;
160+ if (!ti_Write (& Settings , sizeof (Settings_t ), 1 , file ))
161+ break ;
162+ /* This gets run after closing GraphX specifically so that we don't have to worry about the Garbage Collect? dialog. */
163+ if (archived /* && ti_ArchiveHasRoom(sizeof(FileSettings_t))*/ )
164+ ti_SetArchiveStatus (true, file );
165+ ti_Close (file );
166+ return ;
167+ } while (false);
168+ ti_Close (file );
169+ ti_Delete (SETTINGS_FILE_NAME );
91170}
0 commit comments