📄 sumatrapdf.cpp.svn-base
字号:
assert(filePath); if (!filePath) return; /* if a history entry with the same name already exists, then delete it. That way we don't have duplicates and the file moves to the front of the list */ node = FileHistoryList_Node_FindByFilePath(&gFileHistoryRoot, filePath); if (node) { oldMenuId = node->menuId; FileHistoryList_Node_RemoveAndFree(&gFileHistoryRoot, node); } node = FileHistoryList_Node_CreateFromFilePath(filePath); if (!node) return; node->menuId = oldMenuId; FileHistoryList_Node_InsertHead(&gFileHistoryRoot, node);}extern "C" char *GetPasswordForFile(WindowInfo *win, const WCHAR *fileName);/* Get password for a given 'fileName', can be NULL if user cancelled the dialog box. Caller needs to free() the result. */char *GetPasswordForFile(WindowInfo *win, const WCHAR *fileName){ fileName = FilePathW_GetBaseName(fileName); return Dialog_GetPassword(win, fileName);}/* Return true if this program has been started from "Program Files" directory (which is an indicator that it has been installed */static bool runningFromProgramFiles(void){ char programFilesDir[MAX_PATH]; BOOL fOk = SHGetSpecialFolderPath(NULL, programFilesDir, CSIDL_PROGRAM_FILES, FALSE); char *exePath = ExePathGet(); if (!exePath) return true; // again, assume it is bool fromProgramFiles = false; if (fOk) { if (str_startswithi(exePath, programFilesDir)) fromProgramFiles = true; } else { // SHGetSpecialFolderPath() might fail on win95/98 so need a different check if (strstr(exePath, "Program Files")) fromProgramFiles = true; } free(exePath); return fromProgramFiles;}static bool IsRunningInPortableMode(void){ return !runningFromProgramFiles();}static void AppGetAppDir(DString* pDs){ char dir[MAX_PATH]; SHGetSpecialFolderPath(NULL, dir, CSIDL_APPDATA, TRUE); DStringSprintf(pDs, "%s/%s", dir, APP_SUB_DIR); _mkdir(pDs->pString);}/* Generate the full path for a filename used by the app in the userdata path. */static void AppGenDataFilename(char* pFilename, DString* pDs){ assert(0 == pDs->length); assert(pFilename); if (!pFilename) return; assert(pDs); if (!pDs) return; bool portable = IsRunningInPortableMode(); if (portable) { /* Use the same path as the binary */ char *exePath = ExePathGet(); if (!exePath) return; char *dir = FilePath_GetDir(exePath); if (dir) DStringSprintf(pDs, "%s", dir); free((void*)exePath); free((void*)dir); } else { AppGetAppDir(pDs); } if (!char_is_dir_sep(pDs->pString[strlen(pDs->pString)]) && !char_is_dir_sep(pFilename[0])) { DStringAppend(pDs, DIR_SEP_STR, -1); } DStringAppend(pDs, pFilename, -1);}static void Prefs_GetFileName(DString* pDs){ assert(0 == pDs->length); AppGenDataFilename(PREFS_FILE_NAME, pDs);}/* Load preferences from the preferences file. Returns true if preferences file was loaded, false if there was an error.*/static bool Prefs_Load(void){ char * prefsTxt; bool ok = false;#ifdef DEBUG static bool loaded = false; assert(!loaded); loaded = true;#endif DString path; DStringInit(&path); Prefs_GetFileName(&path); uint64_t prefsFileLen; prefsTxt = file_read_all(path.pString, &prefsFileLen); if (!str_empty(prefsTxt)) { ok = Prefs_Deserialize(prefsTxt, prefsFileLen, &gFileHistoryRoot); assert(ok); } DStringFree(&path); free((void*)prefsTxt); return ok;}unsigned short gItemId[] = { IDM_ZOOM_6400, IDM_ZOOM_3200, IDM_ZOOM_1600, IDM_ZOOM_800, IDM_ZOOM_400, IDM_ZOOM_200, IDM_ZOOM_150, IDM_ZOOM_125, IDM_ZOOM_100, IDM_ZOOM_50, IDM_ZOOM_25, IDM_ZOOM_12_5, IDM_ZOOM_8_33, IDM_ZOOM_FIT_PAGE, IDM_ZOOM_FIT_WIDTH, IDM_ZOOM_ACTUAL_SIZE };double gItemZoom[] = { 6400.0, 3200.0, 1600.0, 800.0, 400.0, 200.0, 150.0, 125.0, 100.0, 50.0, 25.0, 12.5, 8.33, ZOOM_FIT_PAGE, ZOOM_FIT_WIDTH, IDM_ZOOM_ACTUAL_SIZE };static UINT MenuIdFromVirtualZoom(double virtualZoom){ for (size_t i=0; i < dimof(gItemZoom); i++) { if (virtualZoom == gItemZoom[i]) return gItemId[i]; } return IDM_ZOOM_ACTUAL_SIZE;}static double ZoomMenuItemToZoom(UINT menuItemId){ for (size_t i=0; i<dimof(gItemId); i++) { if (menuItemId == gItemId[i]) { return gItemZoom[i]; } } assert(0); return 100.0;}static void ZoomMenuItemCheck(HMENU hmenu, UINT menuItemId){ BOOL found = FALSE; for (size_t i=0; i<dimof(gItemId); i++) { UINT checkState = MF_BYCOMMAND | MF_UNCHECKED; if (menuItemId == gItemId[i]) { assert(!found); found = TRUE; checkState = MF_BYCOMMAND | MF_CHECKED; } CheckMenuItem(hmenu, gItemId[i], checkState); } assert(found);}static void MenuUpdateZoom(WindowInfo* win){ double zoomVirtual = gGlobalPrefs.m_defaultZoom; if (win->dm) zoomVirtual = win->dm->zoomVirtual(); UINT menuId = MenuIdFromVirtualZoom(zoomVirtual); ZoomMenuItemCheck(GetMenu(win->hwndFrame), menuId);}static void MenuUpdateFullscreen(WindowInfo* win){ if (win->dm) return; // don't bother for windows with PDF /* show default state */ HMENU menu = GetMenu(win->hwndFrame); UINT state = MF_BYCOMMAND | MF_UNCHECKED; if (gGlobalPrefs.m_windowState == WIN_STATE_FULLSCREEN) state = MF_BYCOMMAND | MF_CHECKED; CheckMenuItem(menu, IDM_VIEW_FULLSCREEN, state);}static void SeeLastError(void) { char *msgBuf = NULL; FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR) &msgBuf, 0, NULL); if (!msgBuf) return; printf("SeeLastError(): %s\n", msgBuf); OutputDebugStringA(msgBuf); LocalFree(msgBuf);}static void UpdateDisplayStateWindowRect(WindowInfo *win, DisplayState *ds){ RECT r; if (GetWindowRect(win->hwndFrame, &r)) { ds->windowX = r.left; ds->windowY = r.top; ds->windowDx = rect_dx(&r); ds->windowDy = rect_dy(&r); } else { ds->windowX = 0; ds->windowY = 0; ds->windowDx = 0; ds->windowDy = 0; }}static void UpdateCurrentFileDisplayStateForWin(WindowInfo *win){ DisplayState ds; const WCHAR * fileName = NULL; FileHistoryList* node = NULL; if (!win) return; if (WS_SHOWING_PDF != win->state || !win->dm) { // update global windowState for next default launch when no pdf opened gGlobalPrefs.m_windowState = WIN_STATE_NORMAL; if (IsZoomed(win->hwndFrame)) gGlobalPrefs.m_windowState = WIN_STATE_MAXIMIZED; } if (WS_SHOWING_PDF != win->state) return; if (!win->dm) return; fileName = win->dm->fileName(); assert(fileName); if (!fileName) return; const char *fileNameUtf8 = wstr_to_utf8(fileName); node = FileHistoryList_Node_FindByFilePath(&gFileHistoryRoot, fileNameUtf8); free((void*)fileNameUtf8); assert(node); if (!node) return; DisplayState_Init(&ds); // Update pdf-specific windowState ds.windowState = WIN_STATE_NORMAL; if (IsZoomed(win->hwndFrame)) ds.windowState = WIN_STATE_MAXIMIZED; if (win->dm->_fullScreen) ds.windowState = WIN_STATE_FULLSCREEN; if (!displayStateFromDisplayModel(&ds, win->dm)) return; UpdateDisplayStateWindowRect(win, &ds); DisplayState_Free(&(node->state)); node->state = ds; node->state.visible = TRUE;}static void UpdateCurrentFileDisplayState(void){ WindowInfo * currWin; FileHistoryList * currFile; currFile = gFileHistoryRoot; while (currFile) { currFile->state.visible = FALSE; currFile = currFile->next; } currWin = gWindowList; while (currWin) { UpdateCurrentFileDisplayStateForWin(currWin); currWin = currWin->next; }}static bool Prefs_Save(void){ DString path; size_t dataLen; bool ok = false; DStringInit(&path); /* mark currently shown files as visible */ UpdateCurrentFileDisplayState(); const char *data = Prefs_Serialize(&gFileHistoryRoot, &dataLen); if (!data) goto Exit; assert(dataLen > 0); Prefs_GetFileName(&path); /* TODO: consider 2-step process: * write to a temp file * rename temp file to final file */ if (write_to_file(path.pString, (void*)data, dataLen)) ok = true;Exit: free((void*)data); DStringFree(&path); return ok;}static void WindowInfo_Refresh(WindowInfo* win, bool autorefresh) { if (win->pdfsync) win->pdfsync->discard_index(); DisplayState ds; DisplayState_Init(&ds); if (!win->dm || !displayStateFromDisplayModel(&ds, win->dm)) return; UpdateDisplayStateWindowRect(win, &ds); const char *fileNameUtf8 = win->watcher.filepath(); WCHAR* fileName = utf8_to_wstr(fileNameUtf8); RefreshPdfDocument(fileName, win, &ds, true, autorefresh, true); free((void*)fileName);}#ifndef THREAD_BASED_FILEWATCHstatic void WindowInfo_RefreshUpdatedFiles(bool autorefresh) { WindowInfo* curr = gWindowList; while (curr) { if (curr->watcher.HasChanged()) WindowInfo_Refresh(curr, autorefresh); curr = curr->next; }}#endifstatic bool WindowInfo_Dib_Init(WindowInfo *win) { assert(NULL == win->dibInfo); win->dibInfo = (BITMAPINFO*)malloc(sizeof(BITMAPINFO) + 12); if (!win->dibInfo) return false; win->dibInfo->bmiHeader.biSize = sizeof(win->dibInfo->bmiHeader); win->dibInfo->bmiHeader.biPlanes = 1; win->dibInfo->bmiHeader.biBitCount = 24; win->dibInfo->bmiHeader.biCompression = BI_RGB; win->dibInfo->bmiHeader.biXPelsPerMeter = 2834; win->dibInfo->bmiHeader.biYPelsPerMeter = 2834; win->dibInfo->bmiHeader.biClrUsed = 0; win->dibInfo->bmiHeader.biClrImportant = 0; return true;}static void WindowInfo_Dib_Deinit(WindowInfo *win) { free((void*)win->dibInfo); win->dibInfo = NULL;}static void WindowInfo_DoubleBuffer_Delete(WindowInfo *win) { if (win->bmpDoubleBuffer) { DeleteObject(win->bmpDoubleBuffer); win->bmpDoubleBuffer = NULL; } if (win->hdcDoubleBuffer) { DeleteDC(win->hdcDoubleBuffer); win->hdcDoubleBuffer = NULL; } win->hdcToDraw = NULL;}static bool WindowInfo_DoubleBuffer_New(WindowInfo *win){ WindowInfo_DoubleBuffer_Delete(win); win->hdc = GetDC(win->hwndCanvas); win->hdcToDraw = win->hdc; win->GetCanvasSize(); if (!gUseDoubleBuffer || (0 == win->winDx()) || (0 == win->winDy())) return true; win->hdcDoubleBuffer = CreateCompatibleDC(win->hdc); if (!win->hdcDoubleBuffer) return false; win->bmpDoubleBuffer = CreateCompatibleBitmap(win->hdc, win->winDx(), win->winDy()); if (!win->bmpDoubleBuffer) { WindowInfo_DoubleBuffer_Delete(win); return false; } /* TODO: do I need this ? */ SelectObject(win->hdcDoubleBuffer, win->bmpDoubleBuffer); /* fill out everything with background color */ RECT r = {0}; r.bottom = win->winDy(); r.right = win->winDx(); FillRect(win->hdcDoubleBuffer, &r, gBrushBg); win->hdcToDraw = win->hdcDoubleBuffer; return TRUE;}static void WindowInfo_DoubleBuffer_Show(WindowInfo *win, HDC hdc){ if (win->hdc != win->hdcToDraw) { assert(win->hdcToDraw == win->hdcDoubleBuffer); BitBlt(hdc, 0, 0, win->winDx(), win->winDy(), win->hdcDoubleBuffer, 0, 0, SRCCOPY); }}static void WindowInfo_Delete(WindowInfo *win){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -