static BencDict *DisplayState_Serialize(DisplayState *ds, bool globalPrefsOnly) { if (ds->isMissing && (globalPrefsOnly || ds->useGlobalValues) && !ds->decryptionKey && !ds->isPinned) { // forget about missing documents without valuable state return NULL; } // BUG: 2140 if (!IsValidZoom(ds->zoomVirtual)) { dbglog::CrashLogF("Invalid ds->zoomVirtual: %.4f", ds->zoomVirtual); const WCHAR *ext = path::GetExt(ds->filePath); if (!str::IsEmpty(ext)) { ScopedMem<char> extA(str::conv::ToUtf8(ext)); dbglog::CrashLogF("File type: %s", extA.Get()); } dbglog::CrashLogF("DisplayMode: %d", ds->displayMode); dbglog::CrashLogF("PageNo: %d", ds->pageNo); CrashIf(true); } // don't include common values in order to keep the preference file size down uint32_t bitmask = (globalPrefsOnly || ds->useGlobalValues ? Ds_OnlyGlobal : Ds_NotGlobal) | (ds->openCount > 0 ? Ds_IsRecent : 0) | (ds->isPinned ? Ds_IsPinned : 0) | (ds->isMissing ? Ds_IsMissing : 0) | (ds->tocState && ds->tocState->Count() > 0 ? Ds_HasTocState : 0); return SerializeStruct(gFilePrefInfo, dimof(gFilePrefInfo), ds, NULL, bitmask); }
// called whenever global preferences change or a file is // added or removed from gFileHistory (in order to keep // the list of recently opened documents in sync) bool Save() { // don't save preferences without the proper permission if (!HasPermission(Perm_SavePreferences)) return false; /* mark currently shown files as visible */ for (size_t i = 0; i < gWindows.Count(); i++) { UpdateCurrentFileDisplayStateForWin(gWindows.At(i)); } // remove entries which should (no longer) be remembered gFileHistory.Purge(!gGlobalPrefs->rememberStatePerDocument); // update display mode and zoom fields from internal values str::ReplacePtr(&gGlobalPrefs->defaultDisplayMode, conv::FromDisplayMode(gGlobalPrefs->defaultDisplayModeEnum)); conv::FromZoom(&gGlobalPrefs->defaultZoom, gGlobalPrefs->defaultZoomFloat); ScopedMem<WCHAR> path(GetSettingsPath()); CrashIf(!path); if (!path) return false; size_t prevPrefsDataSize; ScopedMem<char> prevPrefsData(file::ReadAll(path, &prevPrefsDataSize)); if (!gGlobalPrefs->rememberStatePerDocument || !gGlobalPrefs->rememberOpenedFiles) { for (DisplayState **ds = gGlobalPrefs->fileStates->IterStart(); ds; ds = gGlobalPrefs->fileStates->IterNext()) { (*ds)->useDefaultState = true; } // prevent unnecessary settings from being written out uint16_t fieldCount = 0; while (++fieldCount <= dimof(gFileStateFields)) { // count the number of fields up to and including useDefaultState if (gFileStateFields[fieldCount - 1].offset == offsetof(FileState, useDefaultState)) break; } // restore the correct fieldCount ASAP after serialization gFileStateInfo.fieldCount = fieldCount; } size_t prefsDataSize; ScopedMem<char> prefsData(SerializeStruct(&gGlobalPrefsInfo, gGlobalPrefs, prevPrefsData, &prefsDataSize)); if (!gGlobalPrefs->rememberStatePerDocument || !gGlobalPrefs->rememberOpenedFiles) gFileStateInfo.fieldCount = dimof(gFileStateFields); CrashIf(!prefsData || 0 == prefsDataSize); if (!prefsData || 0 == prefsDataSize) return false; // only save if anything's changed at all if (prevPrefsDataSize == prefsDataSize && str::Eq(prefsData, prevPrefsData)) return true; FileTransaction trans; bool ok = trans.WriteAll(path, prefsData, prefsDataSize) && trans.Commit(); if (!ok) return false; gGlobalPrefs->lastPrefUpdate = file::GetModificationTime(path); return true; }
static BencDict* SerializeGlobalPrefs(SerializableGlobalPrefs& globalPrefs) { CrashIf(!IsValidZoom(globalPrefs.defaultZoom)); if (!globalPrefs.openCountWeek) globalPrefs.openCountWeek = GetWeekCount(); BencDict *prevDict = NULL; if (globalPrefs.prevSerialization) prevDict = BencDict::Decode(globalPrefs.prevSerialization, NULL); return SerializeStruct(gGlobalPrefInfo, dimof(gGlobalPrefInfo), &globalPrefs, prevDict); }
char *SerializeGlobalPrefs(GlobalPrefs *gp, const char *prevData, size_t *sizeOut) { if (!gp->rememberStatePerDocument || !gp->rememberOpenedFiles) { for (DisplayState *ds : *gp->fileStates) { ds->useDefaultState = true; } // prevent unnecessary settings from being written out uint16_t fieldCount = 0; while (++fieldCount <= dimof(gFileStateFields)) { // count the number of fields up to and including useDefaultState if (gFileStateFields[fieldCount - 1].offset == offsetof(FileState, useDefaultState)) break; } // restore the correct fieldCount ASAP after serialization gFileStateInfo.fieldCount = fieldCount; } char *serialized = SerializeStruct(&gGlobalPrefsInfo, gp, prevData, sizeOut); if (!gp->rememberStatePerDocument || !gp->rememberOpenedFiles) gFileStateInfo.fieldCount = dimof(gFileStateFields); return serialized; }