From 835e373b3eeaabcd0621ed6798ab500f37982fae Mon Sep 17 00:00:00 2001 From: Calvin Morrison Date: Wed, 5 Apr 2023 14:13:39 -0400 Subject: xpdf-no-select-disable --- xpdf-qt/XpdfApp.cc | 499 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 499 insertions(+) create mode 100644 xpdf-qt/XpdfApp.cc (limited to 'xpdf-qt/XpdfApp.cc') diff --git a/xpdf-qt/XpdfApp.cc b/xpdf-qt/XpdfApp.cc new file mode 100644 index 0000000..fdcaea5 --- /dev/null +++ b/xpdf-qt/XpdfApp.cc @@ -0,0 +1,499 @@ +//======================================================================== +// +// XpdfApp.cc +// +// Copyright 2015 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#include +#include +#include +#include +#ifdef _WIN32 +# include +#endif +#include "config.h" +#include "parseargs.h" +#include "GString.h" +#include "GList.h" +#include "gfile.h" +#include "GlobalParams.h" +#include "XpdfViewer.h" +#include "XpdfApp.h" +#include "gmempp.h" + +//------------------------------------------------------------------------ +// command line options +//------------------------------------------------------------------------ + +static GBool openArg = gFalse; +static GBool reverseVideoArg = gFalse; +static char paperColorArg[256] = ""; +static char matteColorArg[256] = ""; +static char fsMatteColorArg[256] = ""; +static char initialZoomArg[256] = ""; +static int rotateArg = 0; +static char antialiasArg[16] = ""; +static char vectorAntialiasArg[16] = ""; +static char textEncArg[128] = ""; +static char passwordArg[33] = ""; +static GBool fullScreen = gFalse; +static char remoteServerArg[256] = ""; +static char tabStateFile[256] = ""; +static char cfgFileArg[256] = ""; +static GBool printCommandsArg = gFalse; +static GBool printVersionArg = gFalse; +static GBool printHelpArg = gFalse; + +static ArgDesc argDesc[] = { + {"-open", argFlag, &openArg, 0, "open file using a default remote server"}, + {"-rv", argFlag, &reverseVideoArg, 0, "reverse video"}, + {"-papercolor", argString, paperColorArg, sizeof(paperColorArg), "color of paper background"}, + {"-mattecolor", argString, matteColorArg, sizeof(matteColorArg), "color of matte background"}, + {"-fsmattecolor", argString, fsMatteColorArg, sizeof(fsMatteColorArg), "color of matte background in full-screen mode"}, + {"-z", argString, initialZoomArg, sizeof(initialZoomArg), "initial zoom level (percent, 'page', 'width')"}, + {"-rot", argInt, &rotateArg, 0, "initial page rotation: 0, 90, 180, or 270"}, + {"-aa", argString, antialiasArg, sizeof(antialiasArg), "enable font anti-aliasing: yes, no"}, + {"-aaVector", argString, vectorAntialiasArg, sizeof(vectorAntialiasArg), "enable vector anti-aliasing: yes, no"}, + {"-enc", argString, textEncArg, sizeof(textEncArg), "output text encoding name"}, + {"-pw", argString, passwordArg, sizeof(passwordArg), "password (for encrypted files)"}, + {"-fullscreen", argFlag, &fullScreen, 0, "run in full-screen (presentation) mode"}, + {"-remote", argString, remoteServerArg, sizeof(remoteServerArg), "remote server mode - remaining args are commands"}, + {"-cmd", argFlag, &printCommandsArg, 0, "print commands as they're executed"}, + {"-tabstate", argString, tabStateFile, sizeof(tabStateFile), "file for saving/loading tab state"}, + {"-cfg", argString, cfgFileArg, sizeof(cfgFileArg), "configuration file to use in place of .xpdfrc"}, + {"-v", argFlag, &printVersionArg, 0, "print copyright and version info"}, + {"-h", argFlag, &printHelpArg, 0, "print usage information"}, + {"-help", argFlag, &printHelpArg, 0, "print usage information"}, + {"--help", argFlag, &printHelpArg, 0, "print usage information"}, + {"-?", argFlag, &printHelpArg, 0, "print usage information"}, + {NULL} +}; + +//------------------------------------------------------------------------ +// XpdfApp +//------------------------------------------------------------------------ + +static void mungeOpenFileName(const char *fileName, GString *cmd); + +XpdfApp::XpdfApp(int &argc, char **argv): + QApplication(argc, argv) +{ + XpdfViewer *viewer; + QLocalSocket *sock; + QString sockName; + const char *fileName, *dest; + GString *color, *cmd; + GBool ok; + int pg, i; + + setApplicationName("XpdfReader"); + setApplicationVersion(xpdfVersion); + + ok = parseArgs(argDesc, &argc, argv); + if (!ok || printVersionArg || printHelpArg) { + fprintf(stderr, "xpdf version %s [www.xpdfreader.com]\n", xpdfVersion); + fprintf(stderr, "%s\n", xpdfCopyright); + if (!printVersionArg) { + printUsage("xpdf", "[ [: | +]] ...", argDesc); + } + ::exit(99); + } + + //--- set up GlobalParams; handle command line arguments + GlobalParams::defaultTextEncoding = "UCS-2"; + globalParams = new GlobalParams(cfgFileArg); +#ifdef _WIN32 + QString dir = applicationDirPath(); + globalParams->setBaseDir(dir.toLocal8Bit().constData()); + dir += "/t1fonts"; + globalParams->setupBaseFonts(dir.toLocal8Bit().constData()); +#else + globalParams->setupBaseFonts(NULL); +#endif + if (initialZoomArg[0]) { + globalParams->setInitialZoom(initialZoomArg); + } + reverseVideo = reverseVideoArg; + if (paperColorArg[0]) { + paperColor = QColor(paperColorArg); + } else { + color = globalParams->getPaperColor(); + paperColor = QColor(color->getCString()); + delete color; + } + if (reverseVideo) { + paperColor = QColor(255 - paperColor.red(), + 255 - paperColor.green(), + 255 - paperColor.blue()); + } + if (matteColorArg[0]) { + matteColor = QColor(matteColorArg); + } else { + color = globalParams->getMatteColor(); + matteColor = QColor(color->getCString()); + delete color; + } + if (fsMatteColorArg[0]) { + fsMatteColor = QColor(fsMatteColorArg); + } else { + color = globalParams->getFullScreenMatteColor(); + fsMatteColor = QColor(color->getCString()); + delete color; + } + color = globalParams->getSelectionColor(); + selectionColor = QColor(color->getCString()); + delete color; + if (antialiasArg[0]) { + if (!globalParams->setAntialias(antialiasArg)) { + fprintf(stderr, "Bad '-aa' value on command line\n"); + } + } + if (vectorAntialiasArg[0]) { + if (!globalParams->setVectorAntialias(vectorAntialiasArg)) { + fprintf(stderr, "Bad '-aaVector' value on command line\n"); + } + } + if (textEncArg[0]) { + globalParams->setTextEncoding(textEncArg); + } + if (tabStateFile[0]) { + globalParams->setTabStateFile(tabStateFile); + } + if (printCommandsArg) { + globalParams->setPrintCommands(gTrue); + } + + errorEventType = QEvent::registerEventType(); + + viewers = new GList(); + + //--- remote server mode + if (remoteServerArg[0]) { + sock = new QLocalSocket(this); + sockName = "xpdf_"; + sockName += remoteServerArg; + sock->connectToServer(sockName, QIODevice::WriteOnly); + if (sock->waitForConnected(5000)) { + for (i = 1; i < argc; ++i) { + sock->write(argv[i]); + sock->write("\n"); + } + while (sock->bytesToWrite()) { + sock->waitForBytesWritten(5000); + } + delete sock; + ::exit(0); + } else { + delete sock; + viewer = newWindow(gFalse, remoteServerArg); + for (i = 1; i < argc; ++i) { + viewer->execCmd(argv[i], NULL); + } + return; + } + } + + //--- default remote server + if (openArg) { + sock = new QLocalSocket(this); + sockName = "xpdf_default"; + sock->connectToServer(sockName, QIODevice::WriteOnly); + if (sock->waitForConnected(5000)) { + if (argc >= 2) { + cmd = new GString("openFileIn("); + mungeOpenFileName(argv[1], cmd); + cmd->append(",tab)\nraise\n"); + sock->write(cmd->getCString()); + delete cmd; + while (sock->bytesToWrite()) { + sock->waitForBytesWritten(5000); + } + } + delete sock; + ::exit(0); + } else { + delete sock; + if (argc >= 2) { + // on Windows: xpdf.cc converts command line args to UTF-8 + // on Linux: command line args are in the local 8-bit charset +#ifdef _WIN32 + QString qFileName = QString::fromUtf8(argv[1]); +#else + QString qFileName = QString::fromLocal8Bit(argv[1]); +#endif + openInNewWindow(qFileName, 1, "", rotateArg, passwordArg, + fullScreen, "default"); + } else { + newWindow(fullScreen, "default"); + } + return; + } + } + + //--- load PDF file(s) requested on the command line + if (argc >= 2) { + i = 1; + while (i < argc) { + pg = -1; + dest = ""; + if (i+1 < argc && argv[i+1][0] == ':') { + fileName = argv[i]; + pg = atoi(argv[i+1] + 1); + i += 2; + } else if (i+1 < argc && argv[i+1][0] == '+') { + fileName = argv[i]; + dest = argv[i+1] + 1; + i += 2; + } else { + fileName = argv[i]; + ++i; + } + // on Windows: xpdf.cc converts command line args to UTF-8 + // on Linux: command line args are in the local 8-bit charset +#ifdef _WIN32 + QString qFileName = QString::fromUtf8(fileName); +#else + QString qFileName = QString::fromLocal8Bit(fileName); +#endif + if (viewers->getLength() > 0) { + ok = ((XpdfViewer *)viewers->get(0)) + ->openInNewTab(qFileName, pg, dest, rotateArg, + passwordArg, gFalse); + } else { + ok = openInNewWindow(qFileName, pg, dest, rotateArg, + passwordArg, fullScreen); + } + } + } else { + newWindow(fullScreen); + } +} + +// Process the file name for the "-open" flag: convert a relative path +// to absolute, and add escape chars as needed. Append the modified +// name to [cmd]. +static void mungeOpenFileName(const char *fileName, GString *cmd) { + GString *path = new GString(fileName); + makePathAbsolute(path); + for (int i = 0; i < path->getLength(); ++i) { + char c = path->getChar(i); + if (c == '(' || c == ')' || c == ',' || c == '\x01') { + cmd->append('\x01'); + } + cmd->append(c); + } + delete path; +} + +XpdfApp::~XpdfApp() { + delete viewers; + delete globalParams; +} + +int XpdfApp::getNumViewers() { + return viewers->getLength(); +} + +XpdfViewer *XpdfApp::newWindow(GBool fullScreen, + const char *remoteServerName) { + XpdfViewer *viewer = new XpdfViewer(this, fullScreen); + viewers->append(viewer); + if (remoteServerName) { + viewer->startRemoteServer(remoteServerName); + } + viewer->tweakSize(); + viewer->show(); + return viewer; +} + +GBool XpdfApp::openInNewWindow(QString fileName, int page, QString dest, + int rotate, QString password, GBool fullScreen, + const char *remoteServerName) { + XpdfViewer *viewer; + + viewer = XpdfViewer::create(this, fileName, page, dest, rotate, + password, fullScreen); + if (!viewer) { + return gFalse; + } + viewers->append(viewer); + if (remoteServerName) { + viewer->startRemoteServer(remoteServerName); + } + viewer->tweakSize(); + viewer->show(); + return gTrue; +} + +void XpdfApp::closeWindowOrQuit(XpdfViewer *viewer) { + int i; + + viewer->close(); + for (i = 0; i < viewers->getLength(); ++i) { + if ((XpdfViewer *)viewers->get(i) == viewer) { + viewers->del(i); + break; + } + } +} + +void XpdfApp::quit() { + XpdfViewer *viewer; + + while (viewers->getLength()) { + viewer = (XpdfViewer *)viewers->del(0); + viewer->close(); + } + QApplication::quit(); +} + +//------------------------------------------------------------------------ + +void XpdfApp::startUpdatePagesFile() { + if (!globalParams->getSavePageNumbers()) { + return; + } + readPagesFile(); + savedPagesFileChanged = gFalse; +} + +void XpdfApp::updatePagesFile(const QString &fileName, int pageNumber) { + if (!globalParams->getSavePageNumbers()) { + return; + } + if (fileName.isEmpty()) { + return; + } + QString canonicalFileName = QFileInfo(fileName).canonicalFilePath(); + if (canonicalFileName.isEmpty()) { + return; + } + XpdfSavedPageNumber s(canonicalFileName, pageNumber); + for (int i = 0; i < maxSavedPageNumbers; ++i) { + XpdfSavedPageNumber next = savedPageNumbers[i]; + savedPageNumbers[i] = s; + if (next.fileName == canonicalFileName) { + break; + } + s = next; + } + savedPagesFileChanged = gTrue; +} + +void XpdfApp::finishUpdatePagesFile() { + if (!globalParams->getSavePageNumbers()) { + return; + } + if (savedPagesFileChanged) { + writePagesFile(); + } +} + +int XpdfApp::getSavedPageNumber(const QString &fileName) { + if (!globalParams->getSavePageNumbers()) { + return 1; + } + readPagesFile(); + QString canonicalFileName = QFileInfo(fileName).canonicalFilePath(); + if (canonicalFileName.isEmpty()) { + return 1; + } + for (int i = 0; i < maxSavedPageNumbers; ++i) { + if (savedPageNumbers[i].fileName == canonicalFileName) { + return savedPageNumbers[i].pageNumber; + } + } + return 1; +} + +void XpdfApp::readPagesFile() { + // construct the file name (first time only) + if (savedPagesFileName.isEmpty()) { +#ifdef _WIN32 + char path[MAX_PATH]; + if (SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, + SHGFP_TYPE_CURRENT, path) != S_OK) { + return; + } + savedPagesFileName = QString::fromLocal8Bit(path); + savedPagesFileName.append("/xpdf"); + CreateDirectory(savedPagesFileName.toLocal8Bit().constData(), NULL); + savedPagesFileName.append("/xpdf.pages"); +#else + GString *path = getHomeDir(); + savedPagesFileName = QString::fromUtf8(path->getCString()); + delete path; + savedPagesFileName.append("/.xpdf.pages"); +#endif + } + + // no change since last read, so no need to re-read + if (savedPagesFileTimestamp.isValid() && + QFileInfo(savedPagesFileName).lastModified() == savedPagesFileTimestamp) { + return; + } + + // mark all entries invalid + for (int i = 0; i < maxSavedPageNumbers; ++i) { + savedPageNumbers[i].fileName.clear(); + savedPageNumbers[i].pageNumber = 1; + } + + // read the file + FILE *f = openFile(savedPagesFileName.toUtf8().constData(), "rb"); + if (!f) { + return; + } + char buf[1024]; + if (!fgets(buf, sizeof(buf), f) || + strcmp(buf, "xpdf.pages-1\n") != 0) { + fclose(f); + return; + } + int i = 0; + while (i < maxSavedPageNumbers && fgets(buf, sizeof(buf), f)) { + int n = (int)strlen(buf); + if (n > 0 && buf[n-1] == '\n') { + buf[n-1] = '\0'; + } + char *p = buf; + while (*p != ' ' && *p) { + ++p; + } + if (!*p) { + continue; + } + *p++ = '\0'; + savedPageNumbers[i].pageNumber = atoi(buf); + savedPageNumbers[i].fileName = QString::fromUtf8(p); + ++i; + } + fclose(f); + + // save the timestamp + savedPagesFileTimestamp = QFileInfo(savedPagesFileName).lastModified(); +} + +void XpdfApp::writePagesFile() { + if (savedPagesFileName.isEmpty()) { + return; + } + FILE *f = openFile(savedPagesFileName.toUtf8().constData(), "wb"); + if (!f) { + return; + } + fprintf(f, "xpdf.pages-1\n"); + for (int i = 0; i < maxSavedPageNumbers; ++i) { + if (!savedPageNumbers[i].fileName.isEmpty()) { + fprintf(f, "%d %s\n", + savedPageNumbers[i].pageNumber, + savedPageNumbers[i].fileName.toUtf8().constData()); + } + } + fclose(f); + savedPagesFileTimestamp = QFileInfo(savedPagesFileName).lastModified(); +} -- cgit v1.2.3