📄 sumatrapdf.cpp.svn-base
字号:
}void LaunchBrowser(const TCHAR *url){ launch_url(url);}static BOOL pageRenderAbortCb(void *data){ PageRenderRequest *req = (PageRenderRequest*)data; if (!req->abort) return FALSE; DBG_OUT("Rendering of page %d aborted\n", req->pageNo); return TRUE;}void RenderQueue_RemoveForDisplayModel(DisplayModel *dm) { LockCache(); int reqCount = gPageRenderRequestsCount; int curPos = 0; for (int i = 0; i < reqCount; i++) { PageRenderRequest *req = &(gPageRenderRequests[i]); bool shouldRemove = (req->dm == dm); if (i != curPos) gPageRenderRequests[curPos] = gPageRenderRequests[i]; if (shouldRemove) --gPageRenderRequestsCount; else ++curPos; } UnlockCache();}/* Wait until rendering of a page beloging to <dm> has finished. *//* TODO: this might take some time, would be good to show a dialog to let the user know he has to wait until we finish */void cancelRenderingForDisplayModel(DisplayModel *dm) { DBG_OUT("cancelRenderingForDisplayModel()\n"); bool renderingFinished = false;; for (;;) { LockCache(); if (!gCurPageRenderReq || (gCurPageRenderReq->dm != dm)) renderingFinished = true; else gCurPageRenderReq->abort = TRUE; UnlockCache(); if (renderingFinished) break; /* TODO: busy loop is not good, but I don't have a better idea */ sleep_milliseconds(500); }}/* Render a bitmap for page <pageNo> in <dm>. */void RenderQueue_Add(DisplayModel *dm, int pageNo) { DBG_OUT("RenderQueue_Add(pageNo=%d)\n", pageNo); assert(dm); if (!dm) goto Exit; LockCache(); int rotation = dm->rotation(); normalizeRotation(&rotation); double zoomLevel = dm->zoomReal(); if (BitmapCache_Exists(dm, pageNo, zoomLevel, rotation)) { goto LeaveCsAndExit; } if (gCurPageRenderReq && (gCurPageRenderReq->pageNo == pageNo) && (gCurPageRenderReq->dm == dm)) { if ((gCurPageRenderReq->zoomLevel != zoomLevel) || (gCurPageRenderReq->rotation != rotation)) { /* Currently rendered page is for the same page but with different zoom or rotation, so abort it */ DBG_OUT(" aborting rendering\n"); gCurPageRenderReq->abort = TRUE; } else { /* we're already rendering exactly the same page */ DBG_OUT(" already rendering this page\n"); goto LeaveCsAndExit; } } for (int i=0; i < gPageRenderRequestsCount; i++) { PageRenderRequest* req = &(gPageRenderRequests[i]); if ((req->pageNo == pageNo) && (req->dm == dm)) { if ((req->zoomLevel == zoomLevel) && (req->rotation == rotation)) { /* Request with exactly the same parameters already queued for rendering. Move it to the top of the queue so that it'll be rendered faster. */ PageRenderRequest tmp; tmp = gPageRenderRequests[gPageRenderRequestsCount-1]; gPageRenderRequests[gPageRenderRequestsCount-1] = *req; *req = tmp; DBG_OUT(" already queued\n"); goto LeaveCsAndExit; } else { /* There was a request queued for the same page but with different zoom or rotation, so only replace this request */ DBG_OUT("Replacing request for page %d with new request\n", req->pageNo); req->zoomLevel = zoomLevel; req->rotation = rotation; goto LeaveCsAndExit; } } } PageRenderRequest* newRequest; /* add request to the queue */ if (gPageRenderRequestsCount == MAX_PAGE_REQUESTS) { /* queue is full -> remove the oldest items on the queue */ memmove(&(gPageRenderRequests[0]), &(gPageRenderRequests[1]), sizeof(PageRenderRequest)*(MAX_PAGE_REQUESTS-1)); newRequest = &(gPageRenderRequests[MAX_PAGE_REQUESTS-1]); } else { newRequest = &(gPageRenderRequests[gPageRenderRequestsCount]); gPageRenderRequestsCount++; } assert(gPageRenderRequestsCount <= MAX_PAGE_REQUESTS); newRequest->dm = dm; newRequest->pageNo = pageNo; newRequest->zoomLevel = zoomLevel; newRequest->rotation = rotation; newRequest->abort = FALSE; UnlockCache(); /* tell rendering thread there's a new request to render */ LONG prevCount; ReleaseSemaphore(gPageRenderSem, 1, &prevCount);Exit: return;LeaveCsAndExit: UnlockCache(); return;}void RenderQueue_Pop(PageRenderRequest *req){ LockCache(); assert(gPageRenderRequestsCount > 0); assert(gPageRenderRequestsCount <= MAX_PAGE_REQUESTS); --gPageRenderRequestsCount; *req = gPageRenderRequests[gPageRenderRequestsCount]; assert(gPageRenderRequestsCount >= 0); UnlockCache();}void RenderQueue_Clear(){ LockCache(); gPageRenderRequestsCount = 0; UnlockCache();}static void MenuUpdateDisplayMode(WindowInfo *win){ DisplayMode displayMode = gGlobalPrefs.m_defaultDisplayMode; if (win->dm) displayMode = win->dm->displayMode(); HMENU menuMain = GetMenu(win->hwndFrame); CheckMenuItem(menuMain, IDM_VIEW_SINGLE_PAGE, MF_BYCOMMAND | MF_UNCHECKED); CheckMenuItem(menuMain, IDM_VIEW_CONTINUOUS, MF_BYCOMMAND | MF_UNCHECKED); CheckMenuItem(menuMain, IDM_VIEW_FACING, MF_BYCOMMAND | MF_UNCHECKED); CheckMenuItem(menuMain, IDM_VIEW_CONTINUOUS_FACING, MF_BYCOMMAND | MF_UNCHECKED); UINT id; if (DM_SINGLE_PAGE == displayMode) { id = IDM_VIEW_SINGLE_PAGE; } else if (DM_FACING == displayMode) { id = IDM_VIEW_FACING; } else if (DM_CONTINUOUS == displayMode) { id = IDM_VIEW_CONTINUOUS; } else if (DM_CONTINUOUS_FACING == displayMode) { id = IDM_VIEW_CONTINUOUS_FACING; } else assert(0); CheckMenuItem(menuMain, id, MF_BYCOMMAND | MF_CHECKED);}static void SwitchToDisplayMode(WindowInfo *win, DisplayMode displayMode){ if (win->dm) win->dm->changeDisplayMode(displayMode); else { gGlobalPrefs.m_defaultDisplayMode = displayMode; } MenuUpdateDisplayMode(win);}static UINT AllocNewMenuId(void){ static UINT firstId = 1000; ++firstId; return firstId;}enum menuFlags { MF_NOT_IN_RESTRICTED = 0x1 };MenuDef menuDefFile[] = { { _TRN("&Open\tCtrl-O"), IDM_OPEN , MF_NOT_IN_RESTRICTED }, { _TRN("&Close\tCtrl-W"), IDM_CLOSE, MF_NOT_IN_RESTRICTED }, { _TRN("&Save as"), IDM_SAVEAS, MF_NOT_IN_RESTRICTED }, { _TRN("&Print\tCtrl-P"), IDM_PRINT, MF_NOT_IN_RESTRICTED }, { SEP_ITEM, 0, MF_NOT_IN_RESTRICTED }, { _TRN("Make SumatraPDF a default PDF reader"), IDM_MAKE_DEFAULT_READER, MF_NOT_IN_RESTRICTED },#ifdef _TEX_ENHANCEMENT { _TRN("Set inverse search command-line"), IDM_SET_INVERSESEARCH, 0 },#endif { SEP_ITEM , 0, MF_NOT_IN_RESTRICTED }, { _TRN("E&xit\tCtrl-Q"), IDM_EXIT, 0 }};MenuDef menuDefView[] = { { _TRN("Single page"), IDM_VIEW_SINGLE_PAGE, 0 }, { _TRN("Facing"), IDM_VIEW_FACING, 0 }, { _TRN("Continuous"), IDM_VIEW_CONTINUOUS, 0 }, { _TRN("Continuous facing"), IDM_VIEW_CONTINUOUS_FACING, 0 }, { SEP_ITEM, 0, 0 }, { _TRN("Rotate left"), IDM_VIEW_ROTATE_LEFT, 0 }, { _TRN("Rotate right"), IDM_VIEW_ROTATE_RIGHT, 0 }, { SEP_ITEM, 0, 0 }, { _TRN("Bookmarks"), IDM_VIEW_BOOKMARKS, 0 }, { SEP_ITEM, 0, 0 }, { _TRN("Fullscreen\tCtrl-L"), IDM_VIEW_FULLSCREEN, 0 }, { SEP_ITEM, 0, 0 }, { _TRN("Show toolbar"), IDM_VIEW_SHOW_HIDE_TOOLBAR, 0 },};MenuDef menuDefGoTo[] = { { _TRN("Next Page"), IDM_GOTO_NEXT_PAGE, 0 }, { _TRN("Previous Page"), IDM_GOTO_PREV_PAGE, 0 }, { _TRN("First Page\tHome"), IDM_GOTO_FIRST_PAGE, 0 }, { _TRN("Last Page\tEnd"), IDM_GOTO_LAST_PAGE, 0 }, { _TRN("Page...\tCtrl-G"), IDM_GOTO_PAGE, 0 },};MenuDef menuDefZoom[] = { { _TRN("Fit &Page\tCtrl-0"), IDM_ZOOM_FIT_PAGE, 0 }, { _TRN("Act&ual Size\tCtrl-1"), IDM_ZOOM_ACTUAL_SIZE, 0 }, { _TRN("Fit Widt&h\tCtrl-2"), IDM_ZOOM_FIT_WIDTH, 0 }, { SEP_ITEM },#ifndef BUILD_RM_VERSION { _TRN("6400%"), IDM_ZOOM_6400, 0 }, { _TRN("3200%"), IDM_ZOOM_3200, 0 }, { _TRN("1600%"), IDM_ZOOM_1600, 0 }, { _TRN("800%"), IDM_ZOOM_800, 0 },#endif { _TRN("400%"), IDM_ZOOM_400, 0 }, { _TRN("200%"), IDM_ZOOM_200, 0 }, { _TRN("150%"), IDM_ZOOM_150, 0 }, { _TRN("125%"), IDM_ZOOM_125, 0 }, { _TRN("100%"), IDM_ZOOM_100, 0 }, { _TRN("50%"), IDM_ZOOM_50, 0 }, { _TRN("25%"), IDM_ZOOM_25, 0 }, { _TRN("12.5%"), IDM_ZOOM_12_5, 0 }, { _TRN("8.33%"), IDM_ZOOM_8_33, 0 },};MenuDef menuDefLang[] = { { _TRN("Change language"), IDM_CHANGE_LANGUAGE, 0 }, { _TRN("Contribute translation"), IDM_CONTRIBUTE_TRANSLATION, 0 },};MenuDef menuDefHelp[] = { { _TRN("&Visit website"), IDM_VISIT_WEBSITE, 0 }, { _TRN("&Manual"), IDM_MANUAL, 0 }, { _TRN("&Check for new version"), IDM_CHECK_UPDATE, MF_NOT_IN_RESTRICTED }, { _TRN("&About"), IDM_ABOUT, 0 }, { SEP_ITEM , 0, MF_NOT_IN_RESTRICTED }, { _TRN("Enable auto-update"), IDM_ENABLE_AUTO_UPDATE, MF_NOT_IN_RESTRICTED }};static void AddFileMenuItem(HMENU menuFile, FileHistoryList *node){ assert(node); if (!node) return; assert(menuFile); if (!menuFile) return; UINT newId = node->menuId; if (INVALID_MENU_ID == node->menuId) newId = AllocNewMenuId(); const char* utf8 = FilePath_GetBaseName(node->state.filePath); WCHAR *uni = utf8_to_wstr(utf8); AppendMenuW(menuFile, MF_ENABLED | MF_STRING, newId, uni); free((void*)uni); node->menuId = newId;}static HMENU BuildMenuFromMenuDef(MenuDef menuDefs[], int menuItems){ HMENU m = CreateMenu(); if (NULL == m) return NULL; for (int i=0; i < menuItems; i++) { MenuDef md = menuDefs[i]; if (!gRestrictedUse || ~md.m_flags & MF_NOT_IN_RESTRICTED) { const char *title = md.m_title; int id = md.m_id; if (str_eq(title, SEP_ITEM)) { AppendMenu(m, MF_SEPARATOR, 0, NULL); continue; } const WCHAR *wtitle = Translations_GetTranslationW(title); if (wtitle) { AppendMenuW(m, MF_STRING, (UINT_PTR)id, wtitle); } } } return m;}static void AppendRecentFilesToMenu(HMENU m){ if (!gFileHistoryRoot) return; AppendMenu(m, MF_SEPARATOR, 0, NULL); int itemsAdded = 0; FileHistoryList *curr = gFileHistoryRoot; while (curr) { assert(curr->state.filePath); if (curr->state.filePath) { AddFileMenuItem(m, curr); assert(curr->menuId != INVALID_MENU_ID); ++itemsAdded; if (itemsAdded >= MAX_RECENT_FILES_IN_MENU) { DBG_OUT(" not adding, reached max %d items\n", MAX_RECENT_FILES_IN_MENU); return; } } curr = curr->next; }}static void WindowInfo_RebuildMenu(WindowInfo *win){ if (win->hMenu) { DestroyMenu(win->hMenu); win->hMenu = NULL; } HMENU mainMenu = CreateMenu(); HMENU tmp = BuildMenuFromMenuDef(menuDefFile, dimof(menuDefFile)); if (!gRestrictedUse) AppendRecentFilesToMenu(tmp); AppendMenuW(mainMenu, MF_POPUP | MF_STRING, (UINT_PTR)tmp, _TRW("&File")); tmp = BuildMenuFromMenuDef(menuDefView, dimof(menuDefView)); AppendMenuW(mainMenu, MF_POPUP | MF_STRING, (UINT_PTR)tmp, _TRW("&View")); tmp = BuildMenuFromMenuDef(menuDefGoTo, dimof(menuDefGoTo)); AppendMenuW(mainMenu, MF_POPUP | MF_STRING, (UINT_PTR)tmp, _TRW("&Go To")); tmp = BuildMenuFromMenuDef(menuDefZoom, dimof(menuDefZoom)); AppendMenuW(mainMenu, MF_POPUP | MF_STRING, (UINT_PTR)tmp, _TRW("&Zoom")); tmp = BuildMenuFromMenuDef(menuDefLang, dimof(menuDefLang)); AppendMenuW(mainMenu, MF_POPUP | MF_STRING, (UINT_PTR)tmp, _TRW("&Language")); tmp = BuildMenuFromMenuDef(menuDefHelp, dimof(menuDefHelp)); AppendMenuW(mainMenu, MF_POPUP | MF_STRING, (UINT_PTR)tmp, _TRW("&Help")); win->hMenu = mainMenu;}/* Return the full exe path of my own executable. Caller needs to free() the result. */static char *ExePathGet(void){ char buf[_MAX_PATH]; buf[0] = 0; GetModuleFileNameA(NULL, buf, dimof(buf)); return str_dup(buf);}/* Return the full exe path of my own executable. Caller needs to free() the result. */static WCHAR *ExePathGetW(void){ WCHAR buf[_MAX_PATH]; buf[0] = 0; GetModuleFileNameW(NULL, buf, dimof(buf)); return wstr_dup(buf);}static void CaptionPens_Create(void){ LOGPEN pen; assert(!ghpenWhite); pen.lopnStyle = PS_SOLID; pen.lopnWidth.x = 1; pen.lopnWidth.y = 1; pen.lopnColor = COL_WHITE; ghpenWhite = CreatePenIndirect(&pen); pen.lopnColor = COL_CAPTION_BLUE; ghpenBlue = CreatePenIndirect(&pen);}static void CaptionPens_Destroy(void){ if (ghpenWhite) { DeleteObject(ghpenWhite); ghpenWhite = NULL; } if (ghpenBlue) { DeleteObject(ghpenBlue); ghpenBlue = NULL; }}static void AddFileToHistory(const char *filePath){ FileHistoryList * node; uint32_t oldMenuId = INVALID_MENU_ID;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -