void FromZoom(char **dst, float zoom, DisplayState *stateForIssue2140) { float prevZoom = *dst ? ToZoom(*dst, INVALID_ZOOM) : INVALID_ZOOM; if (prevZoom == zoom) return; if (!IsValidZoom(zoom) && stateForIssue2140) { // TODO: does issue 2140 still occur? dbglog::CrashLogF("Invalid ds->zoom: %g", zoom); const WCHAR *ext = path::GetExt(stateForIssue2140->filePath); if (!str::IsEmpty(ext)) { ScopedMem<char> extA(str::conv::ToUtf8(ext)); dbglog::CrashLogF("File type: %s", extA.Get()); } dbglog::CrashLogF("DisplayMode: %S", stateForIssue2140->displayMode); dbglog::CrashLogF("PageNo: %d", stateForIssue2140->pageNo); } CrashIf(!IsValidZoom(zoom)); free(*dst); if (ZOOM_FIT_PAGE == zoom) *dst = str::Dup("fit page"); else if (ZOOM_FIT_WIDTH == zoom) *dst = str::Dup("fit width"); else if (ZOOM_FIT_CONTENT == zoom) *dst = str::Dup("fit content"); else *dst = str::Format("%g", zoom); }
void ChmModel::SetZoomVirtual(float zoom, PointI *fixPt) { if (zoom <= 0 || !IsValidZoom(zoom)) zoom = 100.0f; ZoomTo(zoom); initZoom = zoom; }
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); }
static BencDict* SerializeGlobalPrefs(SerializableGlobalPrefs& globalPrefs) { BencDict *prefs = new BencDict(); if (!prefs) return NULL; prefs->Add(TOOLBAR_VISIBLE_STR, globalPrefs.toolbarVisible); prefs->Add(TOC_VISIBLE_STR, globalPrefs.tocVisible); prefs->Add(FAV_VISIBLE_STR, globalPrefs.favVisible); prefs->Add(SIDEBAR_DX_STR, globalPrefs.sidebarDx); prefs->Add(TOC_DY_STR, globalPrefs.tocDy); prefs->Add(PDF_ASSOCIATE_DONT_ASK_STR, globalPrefs.pdfAssociateDontAskAgain); prefs->Add(PDF_ASSOCIATE_ASSOCIATE_STR, globalPrefs.pdfAssociateShouldAssociate); prefs->Add(BG_COLOR_STR, globalPrefs.bgColor); prefs->Add(ESC_TO_EXIT_STR, globalPrefs.escToExit); prefs->Add(USE_SYS_COLORS_STR, globalPrefs.useSysColors); prefs->Add(ENABLE_AUTO_UPDATE_STR, globalPrefs.enableAutoUpdate); prefs->Add(REMEMBER_OPENED_FILES_STR, globalPrefs.rememberOpenedFiles); prefs->Add(GLOBAL_PREFS_ONLY_STR, globalPrefs.globalPrefsOnly); prefs->Add(SHOW_RECENT_FILES_STR, globalPrefs.showStartPage); const WCHAR *mode = DisplayModeConv::NameFromEnum(globalPrefs.defaultDisplayMode); prefs->Add(DISPLAY_MODE_STR, mode); CrashIf(!IsValidZoom(globalPrefs.defaultZoom)); ScopedMem<char> zoom(str::Format("%.4f", globalPrefs.defaultZoom)); prefs->AddRaw(ZOOM_VIRTUAL_STR, zoom); prefs->Add(WINDOW_STATE_STR, globalPrefs.windowState); prefs->Add(WINDOW_X_STR, globalPrefs.windowPos.x); prefs->Add(WINDOW_Y_STR, globalPrefs.windowPos.y); prefs->Add(WINDOW_DX_STR, globalPrefs.windowPos.dx); prefs->Add(WINDOW_DY_STR, globalPrefs.windowPos.dy); if (globalPrefs.inverseSearchCmdLine) prefs->Add(INVERSE_SEARCH_COMMANDLINE, globalPrefs.inverseSearchCmdLine); prefs->Add(ENABLE_TEX_ENHANCEMENTS_STR, globalPrefs.enableTeXEnhancements); if (globalPrefs.versionToSkip) prefs->Add(VERSION_TO_SKIP_STR, globalPrefs.versionToSkip); if (globalPrefs.lastUpdateTime) prefs->AddRaw(LAST_UPDATE_STR, globalPrefs.lastUpdateTime); prefs->AddRaw(UI_LANGUAGE_STR, globalPrefs.currentLanguage); if (!globalPrefs.openCountWeek) globalPrefs.openCountWeek = GetWeekCount(); prefs->Add(OPEN_COUNT_WEEK_STR, globalPrefs.openCountWeek); prefs->Add(FWDSEARCH_OFFSET, globalPrefs.fwdSearch.offset); prefs->Add(FWDSEARCH_COLOR, globalPrefs.fwdSearch.color); prefs->Add(FWDSEARCH_WIDTH, globalPrefs.fwdSearch.width); prefs->Add(FWDSEARCH_PERMANENT, globalPrefs.fwdSearch.permanent); prefs->Add(CBX_RIGHT2LEFT, globalPrefs.cbxR2L); return prefs; }
void ChmModel::SetZoomVirtual(float zoom, PointI *fixPt) { if (zoom > 0) zoom = limitValue(zoom, ZOOM_MIN, ZOOM_MAX); if (zoom <= 0 || !IsValidZoom(zoom)) zoom = 100.0f; ZoomTo(zoom); initZoom = zoom; }
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); }
/* Caller needs to prefs::CleanUp() */ bool Load() { CrashIf(gGlobalPrefs); ScopedMem<WCHAR> path(GetSettingsPath()); ScopedMem<char> prefsData(file::ReadAll(path, NULL)); gGlobalPrefs = (GlobalPrefs *)DeserializeStruct(&gGlobalPrefsInfo, prefsData); CrashAlwaysIf(!gGlobalPrefs); #ifdef DISABLE_EBOOK_UI if (!file::Exists(path)) gGlobalPrefs->ebookUI.useFixedPageUI = gGlobalPrefs->chmUI.useFixedPageUI = true; #endif #ifdef DISABLE_TABS if (!file::Exists(path)) gGlobalPrefs->useTabs = false; #endif if (!gGlobalPrefs->uiLanguage || !trans::ValidateLangCode(gGlobalPrefs->uiLanguage)) { // guess the ui language on first start str::ReplacePtr(&gGlobalPrefs->uiLanguage, trans::DetectUserLang()); } gGlobalPrefs->lastPrefUpdate = file::GetModificationTime(path); gGlobalPrefs->defaultDisplayModeEnum = conv::ToDisplayMode(gGlobalPrefs->defaultDisplayMode, DM_AUTOMATIC); gGlobalPrefs->defaultZoomFloat = conv::ToZoom(gGlobalPrefs->defaultZoom, ZOOM_ACTUAL_SIZE); CrashIf(!IsValidZoom(gGlobalPrefs->defaultZoomFloat)); int weekDiff = GetWeekCount() - gGlobalPrefs->openCountWeek; gGlobalPrefs->openCountWeek = GetWeekCount(); if (weekDiff > 0) { // "age" openCount statistics (cut in in half after every week) for (DisplayState **ds = gGlobalPrefs->fileStates->IterStart(); ds; ds = gGlobalPrefs->fileStates->IterNext()) { (*ds)->openCount >>= weekDiff; } } // make sure that zoom levels are in the order expected by DisplayModel gGlobalPrefs->zoomLevels->Sort(cmpFloat); while (gGlobalPrefs->zoomLevels->Count() > 0 && gGlobalPrefs->zoomLevels->At(0) < ZOOM_MIN) { gGlobalPrefs->zoomLevels->PopAt(0); } while (gGlobalPrefs->zoomLevels->Count() > 0 && gGlobalPrefs->zoomLevels->Last() > ZOOM_MAX) { gGlobalPrefs->zoomLevels->Pop(); } // TODO: verify that all states have a non-NULL file path? gFileHistory.UpdateStatesSource(gGlobalPrefs->fileStates); SetDefaultEbookFont(gGlobalPrefs->ebookUI.fontName, gGlobalPrefs->ebookUI.fontSize); if (!file::Exists(path)) Save(); return true; }
float ToZoom(const char *s, float defVal) { if (str::EqIS(s, "fit page")) return ZOOM_FIT_PAGE; if (str::EqIS(s, "fit width")) return ZOOM_FIT_WIDTH; if (str::EqIS(s, "fit content")) return ZOOM_FIT_CONTENT; float zoom; if (str::Parse(s, "%f", &zoom) && IsValidZoom(zoom)) return zoom; return defVal; }
static DisplayState * DeserializeDisplayState(BencDict *dict, bool globalPrefsOnly) { DisplayState *ds = new DisplayState(); if (!ds) return NULL; DeserializeStruct(gFilePrefInfo, dimof(gFilePrefInfo), ds, dict); if (!ds->filePath) { delete ds; return NULL; } // work-around https://code.google.com/p/sumatrapdf/issues/detail?id=2140 if (!IsValidZoom(ds->zoomVirtual)) ds->zoomVirtual = 100.f; return ds; }
static DisplayState * DeserializeDisplayState(BencDict *dict, bool globalPrefsOnly) { DisplayState *ds = new DisplayState(); if (!ds) return NULL; Retrieve(dict, FILE_STR, ds->filePath); if (!ds->filePath) { delete ds; return NULL; } RetrieveRaw(dict, DECRYPTION_KEY_STR, ds->decryptionKey); Retrieve(dict, OPEN_COUNT_STR, ds->openCount); Retrieve(dict, IS_PINNED_STR, ds->isPinned); if (globalPrefsOnly) { ds->useGlobalValues = TRUE; return ds; } Retrieve(dict, DISPLAY_MODE_STR, ds->displayMode); Retrieve(dict, PAGE_NO_STR, ds->pageNo); Retrieve(dict, REPARSE_IDX_STR, ds->reparseIdx); Retrieve(dict, ROTATION_STR, ds->rotation); Retrieve(dict, SCROLL_X_STR, ds->scrollPos.x); Retrieve(dict, SCROLL_Y_STR, ds->scrollPos.y); Retrieve(dict, WINDOW_STATE_STR, ds->windowState); Retrieve(dict, WINDOW_X_STR, ds->windowPos.x); Retrieve(dict, WINDOW_Y_STR, ds->windowPos.y); Retrieve(dict, WINDOW_DX_STR, ds->windowPos.dx); Retrieve(dict, WINDOW_DY_STR, ds->windowPos.dy); Retrieve(dict, TOC_VISIBLE_STR, ds->tocVisible); Retrieve(dict, SIDEBAR_DX_STR, ds->sidebarDx); Retrieve(dict, ZOOM_VIRTUAL_STR, ds->zoomVirtual); Retrieve(dict, USE_GLOBAL_VALUES_STR, ds->useGlobalValues); // work-around https://code.google.com/p/sumatrapdf/issues/detail?id=2140 if (!IsValidZoom(ds->zoomVirtual)) ds->zoomVirtual = 100.f; DeserializeToc(dict, ds); return ds; }
// Called after html document has been loaded. // Sync the state of the ui with the page (show // the right page number, select the right item in toc tree) void ChmModel::OnDocumentComplete(const WCHAR *url) { if (!url || IsBlankUrl(url)) return; if (*url == '/') ++url; int pageNo = pages.Find(ScopedMem<WCHAR>(url::GetFullPath(url))) + 1; if (pageNo) { currentPageNo = pageNo; // TODO: setting zoom before the first page is loaded seems not to work // (might be a regression from between r4593 and r4629) if (IsValidZoom(initZoom)) { SetZoomVirtual(initZoom); initZoom = INVALID_ZOOM; } if (cb) cb->PageNoChanged(pageNo); } }
static BencDict *DisplayState_Serialize(DisplayState *ds, bool globalPrefsOnly) { BencDict *prefs = new BencDict(); if (!prefs) return NULL; prefs->Add(FILE_STR, ds->filePath); if (ds->decryptionKey) prefs->AddRaw(DECRYPTION_KEY_STR, ds->decryptionKey); prefs->Add(OPEN_COUNT_STR, ds->openCount); prefs->Add(IS_PINNED_STR, ds->isPinned); if (globalPrefsOnly || ds->useGlobalValues) { prefs->Add(USE_GLOBAL_VALUES_STR, TRUE); return prefs; } const WCHAR *mode = DisplayModeConv::NameFromEnum(ds->displayMode); prefs->Add(DISPLAY_MODE_STR, mode); prefs->Add(PAGE_NO_STR, ds->pageNo); prefs->Add(REPARSE_IDX_STR, ds->reparseIdx); prefs->Add(ROTATION_STR, ds->rotation); prefs->Add(SCROLL_X_STR, ds->scrollPos.x); prefs->Add(SCROLL_Y_STR, ds->scrollPos.y); prefs->Add(WINDOW_STATE_STR, ds->windowState); prefs->Add(WINDOW_X_STR, ds->windowPos.x); prefs->Add(WINDOW_Y_STR, ds->windowPos.y); prefs->Add(WINDOW_DX_STR, ds->windowPos.dx); prefs->Add(WINDOW_DY_STR, ds->windowPos.dy); prefs->Add(TOC_VISIBLE_STR, ds->tocVisible); prefs->Add(SIDEBAR_DX_STR, ds->sidebarDx); // BUG: 2140 if (!IsValidZoom(ds->zoomVirtual)) { CrashLogFmt("Invalid ds->zoomVirtual: %.4f\n", ds->zoomVirtual); const WCHAR *ext = str::FindCharLast(ds->filePath, L'.'); if (ext) { ScopedMem<char> extA(str::conv::ToUtf8(ext)); CrashLogFmt("File type: %s\n", extA.Get()); } CrashLogFmt("DisplayMode: %d\n", ds->displayMode); CrashLogFmt("PageNo: %d\n", ds->pageNo); } CrashIf(!IsValidZoom(ds->zoomVirtual)); ScopedMem<char> zoom(str::Format("%.4f", ds->zoomVirtual)); prefs->AddRaw(ZOOM_VIRTUAL_STR, zoom); if (ds->tocState && ds->tocState->Count() > 0) { BencArray *tocState = new BencArray(); if (tocState) { for (size_t i = 0; i < ds->tocState->Count(); i++) { tocState->Add(ds->tocState->At(i)); } prefs->Add(TOC_STATE_STR, tocState); } } return prefs; }