📄 xpdfcore.cc
字号:
if (currentSelection) { delete currentSelection; } currentSelection = extractText(pg, ulx, uly, lrx, lry); currentSelectionOwner = this; XtOwnSelection(drawArea, XA_PRIMARY, XtLastTimestampProcessed(display), &convertSelectionCbk, NULL, NULL); }}Boolean XPDFCore::convertSelectionCbk(Widget widget, Atom *selection, Atom *target, Atom *type, XtPointer *value, unsigned long *length, int *format) { Atom *array; // send back a list of supported conversion targets if (*target == targetsAtom) { if (!(array = (Atom *)XtMalloc(sizeof(Atom)))) { return False; } array[0] = XA_STRING; *value = (XtPointer)array; *type = XA_ATOM; *format = 32; *length = 1; return True; // send the selected text } else if (*target == XA_STRING) { //~ for multithreading: need a mutex here *value = XtNewString(currentSelection->getCString()); *length = currentSelection->getLength(); *type = XA_STRING; *format = 8; // 8-bit elements return True; } return False;}//------------------------------------------------------------------------// hyperlinks//------------------------------------------------------------------------void XPDFCore::doAction(LinkAction *action) { LinkActionKind kind; LinkDest *dest; GString *namedDest; char *s; GString *fileName, *fileName2; GString *cmd; GString *actionName; Object movieAnnot, obj1, obj2; GString *msg; int i; switch (kind = action->getKind()) { // GoTo / GoToR action case actionGoTo: case actionGoToR: if (kind == actionGoTo) { dest = NULL; namedDest = NULL; if ((dest = ((LinkGoTo *)action)->getDest())) { dest = dest->copy(); } else if ((namedDest = ((LinkGoTo *)action)->getNamedDest())) { namedDest = namedDest->copy(); } } else { dest = NULL; namedDest = NULL; if ((dest = ((LinkGoToR *)action)->getDest())) { dest = dest->copy(); } else if ((namedDest = ((LinkGoToR *)action)->getNamedDest())) { namedDest = namedDest->copy(); } s = ((LinkGoToR *)action)->getFileName()->getCString(); //~ translate path name for VMS (deal with '/') if (isAbsolutePath(s)) { fileName = new GString(s); } else { fileName = appendToPath(grabPath(doc->getFileName()->getCString()), s); } if (loadFile(fileName) != errNone) { if (dest) { delete dest; } if (namedDest) { delete namedDest; } delete fileName; return; } delete fileName; } if (namedDest) { dest = doc->findDest(namedDest); delete namedDest; } if (dest) { displayDest(dest, zoom, rotate, gTrue); delete dest; } else { if (kind == actionGoToR) { displayPage(1, zoom, 0, gFalse, gTrue); } } break; // Launch action case actionLaunch: fileName = ((LinkLaunch *)action)->getFileName(); s = fileName->getCString(); if (!strcmp(s + fileName->getLength() - 4, ".pdf") || !strcmp(s + fileName->getLength() - 4, ".PDF")) { //~ translate path name for VMS (deal with '/') if (isAbsolutePath(s)) { fileName = fileName->copy(); } else { fileName = appendToPath(grabPath(doc->getFileName()->getCString()), s); } if (loadFile(fileName) != errNone) { delete fileName; return; } delete fileName; displayPage(1, zoom, rotate, gFalse, gTrue); } else { fileName = fileName->copy(); if (((LinkLaunch *)action)->getParams()) { fileName->append(' '); fileName->append(((LinkLaunch *)action)->getParams()); }#ifdef VMS fileName->insert(0, "spawn/nowait ");#elif defined(__EMX__) fileName->insert(0, "start /min /n ");#else fileName->append(" &");#endif msg = new GString("About to execute the command:\n"); msg->append(fileName); if (doQuestionDialog("Launching external application", msg)) { system(fileName->getCString()); } delete fileName; delete msg; } break; // URI action case actionURI: if (!(cmd = globalParams->getURLCommand())) { error(-1, "No urlCommand defined in config file"); break; } runCommand(cmd, ((LinkURI *)action)->getURI()); break; // Named action case actionNamed: actionName = ((LinkNamed *)action)->getName(); if (!actionName->cmp("NextPage")) { gotoNextPage(1, gTrue); } else if (!actionName->cmp("PrevPage")) { gotoPrevPage(1, gTrue, gFalse); } else if (!actionName->cmp("FirstPage")) { if (topPage != 1) { displayPage(1, zoom, rotate, gTrue, gTrue); } } else if (!actionName->cmp("LastPage")) { if (topPage != doc->getNumPages()) { displayPage(doc->getNumPages(), zoom, rotate, gTrue, gTrue); } } else if (!actionName->cmp("GoBack")) { goBackward(); } else if (!actionName->cmp("GoForward")) { goForward(); } else if (!actionName->cmp("Quit")) { if (actionCbk) { (*actionCbk)(actionCbkData, actionName->getCString()); } } else { error(-1, "Unknown named action: '%s'", actionName->getCString()); } break; // Movie action case actionMovie: if (!(cmd = globalParams->getMovieCommand())) { error(-1, "No movieCommand defined in config file"); break; } if (((LinkMovie *)action)->hasAnnotRef()) { doc->getXRef()->fetch(((LinkMovie *)action)->getAnnotRef()->num, ((LinkMovie *)action)->getAnnotRef()->gen, &movieAnnot); } else { //~ need to use the correct page num here doc->getCatalog()->getPage(topPage)->getAnnots(&obj1); if (obj1.isArray()) { for (i = 0; i < obj1.arrayGetLength(); ++i) { if (obj1.arrayGet(i, &movieAnnot)->isDict()) { if (movieAnnot.dictLookup("Subtype", &obj2)->isName("Movie")) { obj2.free(); break; } obj2.free(); } movieAnnot.free(); } obj1.free(); } } if (movieAnnot.isDict()) { if (movieAnnot.dictLookup("Movie", &obj1)->isDict()) { if (obj1.dictLookup("F", &obj2)) { if ((fileName = LinkAction::getFileSpecName(&obj2))) { if (!isAbsolutePath(fileName->getCString())) { fileName2 = appendToPath( grabPath(doc->getFileName()->getCString()), fileName->getCString()); delete fileName; fileName = fileName2; } runCommand(cmd, fileName); delete fileName; } obj2.free(); } obj1.free(); } } movieAnnot.free(); break; // unknown action type case actionUnknown: error(-1, "Unknown link action type: '%s'", ((LinkUnknown *)action)->getAction()->getCString()); break; }}// Run a command, given a <cmdFmt> string with one '%s' in it, and an// <arg> string to insert in place of the '%s'.void XPDFCore::runCommand(GString *cmdFmt, GString *arg) { GString *cmd; char *s; if ((s = strstr(cmdFmt->getCString(), "%s"))) { cmd = mungeURL(arg); cmd->insert(0, cmdFmt->getCString(), s - cmdFmt->getCString()); cmd->append(s + 2); } else { cmd = cmdFmt->copy(); }#ifdef VMS cmd->insert(0, "spawn/nowait ");#elif defined(__EMX__) cmd->insert(0, "start /min /n ");#else cmd->append(" &");#endif system(cmd->getCString()); delete cmd;}// Escape any characters in a URL which might cause problems when// calling system().GString *XPDFCore::mungeURL(GString *url) { static char *allowed = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789" "-_.~/?:@&=+,#%"; GString *newURL; char c; char buf[4]; int i; newURL = new GString(); for (i = 0; i < url->getLength(); ++i) { c = url->getChar(i); if (strchr(allowed, c)) { newURL->append(c); } else { sprintf(buf, "%%%02x", c & 0xff); newURL->append(buf); } } return newURL;}//------------------------------------------------------------------------// find//------------------------------------------------------------------------GBool XPDFCore::find(char *s, GBool caseSensitive, GBool next, GBool backward, GBool onePageOnly) { if (!PDFCore::find(s, caseSensitive, next, backward, onePageOnly)) { XBell(display, 0); return gFalse; }#ifndef NO_TEXT_SELECT copySelection();#endif return gTrue;}GBool XPDFCore::findU(Unicode *u, int len, GBool caseSensitive, GBool next, GBool backward, GBool onePageOnly) { if (!PDFCore::findU(u, len, caseSensitive, next, backward, onePageOnly)) { XBell(display, 0); return gFalse; }#ifndef NO_TEXT_SELECT copySelection();#endif return gTrue;}//------------------------------------------------------------------------// misc access//------------------------------------------------------------------------void XPDFCore::setBusyCursor(GBool busy) { setCursor(busy ? busyCursor : None);}void XPDFCore::takeFocus() { XmProcessTraversal(drawArea, XmTRAVERSE_CURRENT);}//------------------------------------------------------------------------// GUI code//------------------------------------------------------------------------void XPDFCore::setupX(GBool installCmap, int rgbCubeSizeA) { XVisualInfo visualTempl; XVisualInfo *visualList; Gulong mask; int nVisuals; XColor xcolor; XColor *xcolors; int r, g, b, n, m; GBool ok; // for some reason, querying XmNvisual doesn't work (even if done // after the window is mapped) visual = DefaultVisual(display, screenNum); XtVaGetValues(shell, XmNcolormap, &colormap, NULL); // check for TrueColor visual //~ this should scan the list, not just look at the first one visualTempl.visualid = XVisualIDFromVisual(visual); visualList = XGetVisualInfo(display, VisualIDMask, &visualTempl, &nVisuals); if (nVisuals < 1) { // this shouldn't happen XFree((XPointer)visualList); visualList = XGetVisualInfo(display, VisualNoMask, &visualTempl, &nVisuals); } depth = visualList->depth; if (visualList->c_class == TrueColor) { trueColor = gTrue; for (mask = visualList->red_mask, rShift = 0; mask && !(mask & 1); mask >>= 1, ++rShift) ; for (rDiv = 8; mask; mask >>= 1, --rDiv) ; for (mask = visualList->green_mask, gShift = 0; mask && !(mask & 1); mask >>= 1, ++gShift) ; for (gDiv = 8; mask; mask >>= 1, --gDiv) ; for (mask = visualList->blue_mask, bShift = 0; mask && !(mask & 1); mask >>= 1, ++bShift) ; for (bDiv = 8; mask; mask >>= 1, --bDiv) ; } else { trueColor = gFalse; } XFree((XPointer)visualList); // allocate a color cube if (!trueColor) { // set colors in private colormap if (installCmap) { for (rgbCubeSize = xMaxRGBCube; rgbCubeSize >= 2; --rgbCubeSize) { m = rgbCubeSize * rgbCubeSize * rgbCubeSize; if (XAllocColorCells(display, colormap, False, NULL, 0, colors, m)) { break; } } if (rgbCubeSize >= 2) { m = rgbCubeSize * rgbCubeSize * rgbCubeSize; xcolors = (XColor *)gmallocn(m, sizeof(XColor)); n = 0; for (r = 0; r < rgbCubeSize; ++r) { for (g = 0; g < rgbCubeSize; ++g) { for (b = 0; b < rgbCubeSize; ++b) { xcolors[n].pixel = colors[n]; xcolors[n].red = (r * 65535) / (rgbCubeSize - 1); xcolors[n].green = (g * 65535) / (rgbCubeSize - 1); xcolors[n].blue = (b * 65535) / (rgbCubeSize - 1); xcolors[n].flags = DoRed | DoGreen | DoBlue; ++n; } } } XStoreColors(display, colormap, xcolors, m);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -