summaryrefslogtreecommitdiff
path: root/src/app.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2020-08-12 10:28:02 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2020-08-12 10:28:02 +0300
commit1d54f7b990ea7f676403681577fc4df984cab0be (patch)
tree94a8ac83159f021dbbb354a6d76ecbaf83a63aad /src/app.c
parent38e09f15ff3e9c4781236016bfbb0b0f9062590b (diff)
Save and load app state (tabs, history)
Diffstat (limited to 'src/app.c')
-rw-r--r--src/app.c66
1 files changed, 65 insertions, 1 deletions
diff --git a/src/app.c b/src/app.c
index 6f076c97..7885d154 100644
--- a/src/app.c
+++ b/src/app.c
@@ -48,6 +48,7 @@ static const char *dataDir_App_ = "~/AppData/Roaming/fi.skyjake.Lagrange";
48static const char *dataDir_App_ = "~/.config/lagrange"; 48static const char *dataDir_App_ = "~/.config/lagrange";
49#endif 49#endif
50static const char *prefsFileName_App_ = "prefs.cfg"; 50static const char *prefsFileName_App_ = "prefs.cfg";
51static const char *stateFileName_App_ = "state.bin";
51 52
52struct Impl_App { 53struct Impl_App {
53 iCommandLine args; 54 iCommandLine args;
@@ -143,6 +144,67 @@ static void savePrefs_App_(const iApp *d) {
143 delete_String(cfg); 144 delete_String(cfg);
144} 145}
145 146
147static const char *magicState_App_ = "lgL1";
148static const char *magicTabDocument_App_ = "tabd";
149
150static iBool loadState_App_(iApp *d) {
151 iFile *f = iClob(newCStr_File(concatPath_CStr(dataDir_App_, stateFileName_App_)));
152 if (open_File(f, readOnly_FileMode)) {
153 char magic[4];
154 readData_File(f, 4, magic);
155 if (memcmp(magic, magicState_App_, 4)) {
156 printf("%s: format not recognized\n", cstr_String(path_File(f)));
157 return iFalse;
158 }
159 const int version = read32_File(f);
160 /* Check supported versions. */
161 if (version != 0) {
162 printf("%s: unsupported version\n", cstr_String(path_File(f)));
163 return iFalse;
164 }
165 setVersion_Stream(stream_File(f), version);
166 iDocumentWidget *doc = document_App();
167 iDocumentWidget *current = NULL;
168 while (!atEnd_File(f)) {
169 readData_File(f, 4, magic);
170 if (!memcmp(magic, magicTabDocument_App_, 4)) {
171 if (!doc) {
172 doc = newTab_App(NULL);
173 }
174 if (read8_File(f)) {
175 current = doc;
176 }
177 deserializeState_DocumentWidget(doc, stream_File(f));
178 doc = NULL;
179 }
180 else {
181 printf("%s: unrecognized data\n", cstr_String(path_File(f)));
182 return iFalse;
183 }
184 }
185 postCommandf_App("tabs.switch page:%p", current);
186 return iTrue;
187 }
188 return iFalse;
189}
190
191static void saveState_App_(const iApp *d) {
192 iFile *f = newCStr_File(concatPath_CStr(dataDir_App_, stateFileName_App_));
193 if (open_File(f, writeOnly_FileMode)) {
194 writeData_File(f, magicState_App_, 4);
195 write32_File(f, 0); /* version */
196 iWidget *tabs = findChild_Widget(d->window->root, "doctabs");
197 iConstForEach(ObjectList, i, children_Widget(findChild_Widget(tabs, "tabs.pages"))) {
198 if (isInstance_Object(i.object, &Class_DocumentWidget)) {
199 writeData_File(f, magicTabDocument_App_, 4);
200 write8_File(f, document_App() == i.object ? 1 : 0);
201 serializeState_DocumentWidget(i.object, stream_File(f));
202 }
203 }
204 }
205 iRelease(f);
206}
207
146static void init_App_(iApp *d, int argc, char **argv) { 208static void init_App_(iApp *d, int argc, char **argv) {
147 init_CommandLine(&d->args, argc, argv); 209 init_CommandLine(&d->args, argc, argv);
148 init_SortedArray(&d->tickers, sizeof(iTicker), cmp_Ticker_); 210 init_SortedArray(&d->tickers, sizeof(iTicker), cmp_Ticker_);
@@ -166,12 +228,14 @@ static void init_App_(iApp *d, int argc, char **argv) {
166 } 228 }
167#endif 229#endif
168 d->window = new_Window(); 230 d->window = new_Window();
169 /* Widget state init. */ { 231 /* Widget state init. */
232 if (!loadState_App_(d)) {
170 postCommand_App("navigate.home"); 233 postCommand_App("navigate.home");
171 } 234 }
172} 235}
173 236
174static void deinit_App(iApp *d) { 237static void deinit_App(iApp *d) {
238 saveState_App_(d);
175 savePrefs_App_(d); 239 savePrefs_App_(d);
176 save_Visited(d->visited, dataDir_App_); 240 save_Visited(d->visited, dataDir_App_);
177 delete_Visited(d->visited); 241 delete_Visited(d->visited);