новые иконки в OpenBoard
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
OpenBoard/thirdparty/xpdf/xpdf-3.02/xpdf/XPDFViewer.cc

3488 lines
105 KiB

//========================================================================
//
// XPDFViewer.cc
//
// Copyright 2002-2003 Glyph & Cog, LLC
//
//========================================================================
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <X11/keysym.h>
#include <X11/cursorfont.h>
#ifdef HAVE_X11_XPM_H
#include <X11/xpm.h>
#endif
#if defined(__sgi) && (XmVERSION <= 1)
#define Object XtObject
#include <Sgm/HPanedW.h>
#undef Object
#endif
#include "gmem.h"
#include "gfile.h"
#include "GString.h"
#include "GList.h"
#include "Error.h"
#include "GlobalParams.h"
#include "PDFDoc.h"
#include "Link.h"
#include "ErrorCodes.h"
#include "Outline.h"
#include "UnicodeMap.h"
#ifndef DISABLE_OUTLINE
#define Object XtObject
#include "XPDFTree.h"
#undef Object
#endif
#include "XPDFApp.h"
#include "XPDFViewer.h"
#include "PSOutputDev.h"
#include "config.h"
// these macro defns conflict with xpdf's Object class
#ifdef LESSTIF_VERSION
#undef XtDisplay
#undef XtScreen
#undef XtWindow
#undef XtParent
#undef XtIsRealized
#endif
#if XmVERSION <= 1
#define XmSET True
#define XmUNSET False
#endif
// hack around old X includes which are missing these symbols
#ifndef XK_Page_Up
#define XK_Page_Up 0xFF55
#endif
#ifndef XK_Page_Down
#define XK_Page_Down 0xFF56
#endif
#ifndef XK_KP_Home
#define XK_KP_Home 0xFF95
#endif
#ifndef XK_KP_Left
#define XK_KP_Left 0xFF96
#endif
#ifndef XK_KP_Up
#define XK_KP_Up 0xFF97
#endif
#ifndef XK_KP_Right
#define XK_KP_Right 0xFF98
#endif
#ifndef XK_KP_Down
#define XK_KP_Down 0xFF99
#endif
#ifndef XK_KP_Prior
#define XK_KP_Prior 0xFF9A
#endif
#ifndef XK_KP_Page_Up
#define XK_KP_Page_Up 0xFF9A
#endif
#ifndef XK_KP_Next
#define XK_KP_Next 0xFF9B
#endif
#ifndef XK_KP_Page_Down
#define XK_KP_Page_Down 0xFF9B
#endif
#ifndef XK_KP_End
#define XK_KP_End 0xFF9C
#endif
#ifndef XK_KP_Begin
#define XK_KP_Begin 0xFF9D
#endif
#ifndef XK_KP_Insert
#define XK_KP_Insert 0xFF9E
#endif
#ifndef XK_KP_Delete
#define XK_KP_Delete 0xFF9F
#endif
//------------------------------------------------------------------------
// GUI includes
//------------------------------------------------------------------------
#include "xpdfIcon.xpm"
#include "leftArrow.xbm"
#include "leftArrowDis.xbm"
#include "dblLeftArrow.xbm"
#include "dblLeftArrowDis.xbm"
#include "rightArrow.xbm"
#include "rightArrowDis.xbm"
#include "dblRightArrow.xbm"
#include "dblRightArrowDis.xbm"
#include "backArrow.xbm"
#include "backArrowDis.xbm"
#include "forwardArrow.xbm"
#include "forwardArrowDis.xbm"
#include "find.xbm"
#include "findDis.xbm"
#include "print.xbm"
#include "printDis.xbm"
#include "about.xbm"
#include "about-text.h"
//------------------------------------------------------------------------
struct ZoomMenuInfo {
char *label;
double zoom;
};
static ZoomMenuInfo zoomMenuInfo[nZoomMenuItems] = {
{ "400%", 400 },
{ "200%", 200 },
{ "150%", 150 },
{ "125%", 125 },
{ "100%", 100 },
{ "50%", 50 },
{ "25%", 25 },
{ "12.5%", 12.5 },
{ "fit page", zoomPage },
{ "fit width", zoomWidth }
};
#define maxZoomIdx 0
#define defZoomIdx 3
#define minZoomIdx 7
#define zoomPageIdx 8
#define zoomWidthIdx 9
//------------------------------------------------------------------------
#define cmdMaxArgs 2
XPDFViewerCmd XPDFViewer::cmdTab[] = {
{ "about", 0, gFalse, gFalse, &XPDFViewer::cmdAbout },
{ "closeOutline", 0, gFalse, gFalse, &XPDFViewer::cmdCloseOutline },
{ "closeWindow", 0, gFalse, gFalse, &XPDFViewer::cmdCloseWindow },
{ "continuousMode", 0, gFalse, gFalse, &XPDFViewer::cmdContinuousMode },
{ "endPan", 0, gTrue, gTrue, &XPDFViewer::cmdEndPan },
{ "endSelection", 0, gTrue, gTrue, &XPDFViewer::cmdEndSelection },
{ "find", 0, gTrue, gFalse, &XPDFViewer::cmdFind },
{ "findNext", 0, gTrue, gFalse, &XPDFViewer::cmdFindNext },
{ "focusToDocWin", 0, gFalse, gFalse, &XPDFViewer::cmdFocusToDocWin },
{ "focusToPageNum", 0, gFalse, gFalse, &XPDFViewer::cmdFocusToPageNum },
{ "followLink", 0, gTrue, gTrue, &XPDFViewer::cmdFollowLink },
{ "followLinkInNewWin", 0, gTrue, gTrue, &XPDFViewer::cmdFollowLinkInNewWin },
{ "followLinkInNewWinNoSel", 0, gTrue, gTrue, &XPDFViewer::cmdFollowLinkInNewWinNoSel },
{ "followLinkNoSel", 0, gTrue, gTrue, &XPDFViewer::cmdFollowLinkNoSel },
{ "fullScreenMode", 0, gFalse, gFalse, &XPDFViewer::cmdFullScreenMode },
{ "goBackward", 0, gFalse, gFalse, &XPDFViewer::cmdGoBackward },
{ "goForward", 0, gFalse, gFalse, &XPDFViewer::cmdGoForward },
{ "gotoDest", 1, gTrue, gFalse, &XPDFViewer::cmdGotoDest },
{ "gotoLastPage", 0, gTrue, gFalse, &XPDFViewer::cmdGotoLastPage },
{ "gotoLastPageNoScroll", 0, gTrue, gFalse, &XPDFViewer::cmdGotoLastPageNoScroll },
{ "gotoPage", 1, gTrue, gFalse, &XPDFViewer::cmdGotoPage },
{ "gotoPageNoScroll", 1, gTrue, gFalse, &XPDFViewer::cmdGotoPageNoScroll },
{ "nextPage", 0, gTrue, gFalse, &XPDFViewer::cmdNextPage },
{ "nextPageNoScroll", 0, gTrue, gFalse, &XPDFViewer::cmdNextPageNoScroll },
{ "open", 0, gFalse, gFalse, &XPDFViewer::cmdOpen },
{ "openFile", 1, gFalse, gFalse, &XPDFViewer::cmdOpenFile },
{ "openFileAtDest", 2, gFalse, gFalse, &XPDFViewer::cmdOpenFileAtDest },
{ "openFileAtDestInNewWin", 2, gFalse, gFalse, &XPDFViewer::cmdOpenFileAtDestInNewWin },
{ "openFileAtPage", 2, gFalse, gFalse, &XPDFViewer::cmdOpenFileAtPage },
{ "openFileAtPageInNewWin", 2, gFalse, gFalse, &XPDFViewer::cmdOpenFileAtPageInNewWin },
{ "openFileInNewWin", 1, gFalse, gFalse, &XPDFViewer::cmdOpenFileInNewWin },
{ "openInNewWin", 0, gFalse, gFalse, &XPDFViewer::cmdOpenInNewWin },
{ "openOutline", 0, gFalse, gFalse, &XPDFViewer::cmdOpenOutline },
{ "pageDown", 0, gTrue, gFalse, &XPDFViewer::cmdPageDown },
{ "pageUp", 0, gTrue, gFalse, &XPDFViewer::cmdPageUp },
{ "postPopupMenu", 0, gFalse, gTrue, &XPDFViewer::cmdPostPopupMenu },
{ "prevPage", 0, gTrue, gFalse, &XPDFViewer::cmdPrevPage },
{ "prevPageNoScroll", 0, gTrue, gFalse, &XPDFViewer::cmdPrevPageNoScroll },
{ "print", 0, gTrue, gFalse, &XPDFViewer::cmdPrint },
{ "quit", 0, gFalse, gFalse, &XPDFViewer::cmdQuit },
{ "raise", 0, gFalse, gFalse, &XPDFViewer::cmdRaise },
{ "redraw", 0, gTrue, gFalse, &XPDFViewer::cmdRedraw },
{ "reload", 0, gTrue, gFalse, &XPDFViewer::cmdReload },
{ "run", 1, gFalse, gFalse, &XPDFViewer::cmdRun },
{ "scrollDown", 1, gTrue, gFalse, &XPDFViewer::cmdScrollDown },
{ "scrollDownNextPage", 1, gTrue, gFalse, &XPDFViewer::cmdScrollDownNextPage },
{ "scrollLeft", 1, gTrue, gFalse, &XPDFViewer::cmdScrollLeft },
{ "scrollOutlineDown", 1, gTrue, gFalse, &XPDFViewer::cmdScrollOutlineDown },
{ "scrollOutlineUp", 1, gTrue, gFalse, &XPDFViewer::cmdScrollOutlineUp },
{ "scrollRight", 1, gTrue, gFalse, &XPDFViewer::cmdScrollRight },
{ "scrollToBottomEdge", 0, gTrue, gFalse, &XPDFViewer::cmdScrollToBottomEdge },
{ "scrollToBottomRight", 0, gTrue, gFalse, &XPDFViewer::cmdScrollToBottomRight },
{ "scrollToLeftEdge", 0, gTrue, gFalse, &XPDFViewer::cmdScrollToLeftEdge },
{ "scrollToRightEdge", 0, gTrue, gFalse, &XPDFViewer::cmdScrollToRightEdge },
{ "scrollToTopEdge", 0, gTrue, gFalse, &XPDFViewer::cmdScrollToTopEdge },
{ "scrollToTopLeft", 0, gTrue, gFalse, &XPDFViewer::cmdScrollToTopLeft },
{ "scrollUp", 1, gTrue, gFalse, &XPDFViewer::cmdScrollUp },
{ "scrollUpPrevPage", 1, gTrue, gFalse, &XPDFViewer::cmdScrollUpPrevPage },
{ "singlePageMode", 0, gFalse, gFalse, &XPDFViewer::cmdSinglePageMode },
{ "startPan", 0, gTrue, gTrue, &XPDFViewer::cmdStartPan },
{ "startSelection", 0, gTrue, gTrue, &XPDFViewer::cmdStartSelection },
{ "toggleContinuousMode", 0, gFalse, gFalse, &XPDFViewer::cmdToggleContinuousMode },
{ "toggleFullScreenMode", 0, gFalse, gFalse, &XPDFViewer::cmdToggleFullScreenMode },
{ "toggleOutline", 0, gFalse, gFalse, &XPDFViewer::cmdToggleOutline },
{ "windowMode", 0, gFalse, gFalse, &XPDFViewer::cmdWindowMode },
{ "zoomFitPage", 0, gFalse, gFalse, &XPDFViewer::cmdZoomFitPage },
{ "zoomFitWidth", 0, gFalse, gFalse, &XPDFViewer::cmdZoomFitWidth },
{ "zoomIn", 0, gFalse, gFalse, &XPDFViewer::cmdZoomIn },
{ "zoomOut", 0, gFalse, gFalse, &XPDFViewer::cmdZoomOut },
{ "zoomPercent", 1, gFalse, gFalse, &XPDFViewer::cmdZoomPercent },
{ "zoomToSelection", 0, gTrue, gFalse, &XPDFViewer::cmdZoomToSelection }
};
#define nCmds (sizeof(cmdTab) / sizeof(XPDFViewerCmd))
//------------------------------------------------------------------------
XPDFViewer::XPDFViewer(XPDFApp *appA, GString *fileName,
int pageA, GString *destName, GBool fullScreen,
GString *ownerPassword, GString *userPassword) {
LinkDest *dest;
int pg;
double z;
app = appA;
win = NULL;
core = NULL;
ok = gFalse;
#ifndef DISABLE_OUTLINE
outlineLabels = NULL;
outlineLabelsLength = outlineLabelsSize = 0;
outlinePaneWidth = 175;
#endif
// do Motif-specific initialization and create the window;
// this also creates the core object
initWindow(fullScreen);
initAboutDialog();
initFindDialog();
initPrintDialog();
openDialog = NULL;
saveAsDialog = NULL;
dest = NULL; // make gcc happy
pg = pageA; // make gcc happy
if (fileName) {
if (loadFile(fileName, ownerPassword, userPassword)) {
getPageAndDest(pageA, destName, &pg, &dest);
#ifndef DISABLE_OUTLINE
if (outlineScroll != None &&
core->getDoc()->getOutline()->getItems() &&
core->getDoc()->getOutline()->getItems()->getLength() > 0) {
XtVaSetValues(outlineScroll, XmNwidth, outlinePaneWidth, NULL);
}
#endif
} else {
return;
}
}
core->resizeToPage(pg);
// map the window -- we do this after calling resizeToPage to avoid
// an annoying on-screen resize
mapWindow();
// display the first page
z = core->getZoom();
if (dest) {
displayDest(dest, z, core->getRotate(), gTrue);
delete dest;
} else {
displayPage(pg, z, core->getRotate(), gTrue, gTrue);
}
ok = gTrue;
}
XPDFViewer::XPDFViewer(XPDFApp *appA, PDFDoc *doc, int pageA,
GString *destName, GBool fullScreen) {
LinkDest *dest;
int pg;
double z;
app = appA;
win = NULL;
core = NULL;
ok = gFalse;
#ifndef DISABLE_OUTLINE
outlineLabels = NULL;
outlineLabelsLength = outlineLabelsSize = 0;
outlinePaneWidth = 175;
#endif
// do Motif-specific initialization and create the window;
// this also creates the core object
initWindow(fullScreen);
initAboutDialog();
initFindDialog();
initPrintDialog();
openDialog = NULL;
saveAsDialog = NULL;
dest = NULL; // make gcc happy
pg = pageA; // make gcc happy
if (doc) {
core->loadDoc(doc);
getPageAndDest(pageA, destName, &pg, &dest);
#ifndef DISABLE_OUTLINE
if (outlineScroll != None &&
core->getDoc()->getOutline()->getItems() &&
core->getDoc()->getOutline()->getItems()->getLength() > 0) {
XtVaSetValues(outlineScroll, XmNwidth, outlinePaneWidth, NULL);
}
#endif
}
core->resizeToPage(pg);
// map the window -- we do this after calling resizeToPage to avoid
// an annoying on-screen resize
mapWindow();
// display the first page
z = core->getZoom();
if (dest) {
displayDest(dest, z, core->getRotate(), gTrue);
delete dest;
} else {
displayPage(pg, z, core->getRotate(), gTrue, gTrue);
}
ok = gTrue;
}
XPDFViewer::~XPDFViewer() {
delete core;
XmFontListFree(aboutBigFont);
XmFontListFree(aboutVersionFont);
XmFontListFree(aboutFixedFont);
closeWindow();
#ifndef DISABLE_OUTLINE
if (outlineLabels) {
gfree(outlineLabels);
}
#endif
}
void XPDFViewer::open(GString *fileName, int pageA, GString *destName) {
LinkDest *dest;
int pg;
double z;
if (!core->getDoc() || fileName->cmp(core->getDoc()->getFileName())) {
if (!loadFile(fileName, NULL, NULL)) {
return;
}
}
getPageAndDest(pageA, destName, &pg, &dest);
z = core->getZoom();
if (dest) {
displayDest(dest, z, core->getRotate(), gTrue);
delete dest;
} else {
displayPage(pg, z, core->getRotate(), gTrue, gTrue);
}
}
void XPDFViewer::clear() {
char *title;
XmString s;
core->clear();
// set up title, number-of-pages display
title = app->getTitle() ? app->getTitle()->getCString()
: (char *)xpdfAppName;
XtVaSetValues(win, XmNtitle, title, XmNiconName, title, NULL);
s = XmStringCreateLocalized("");
XtVaSetValues(pageNumText, XmNlabelString, s, NULL);
XmStringFree(s);
s = XmStringCreateLocalized(" of 0");
XtVaSetValues(pageCountLabel, XmNlabelString, s, NULL);
XmStringFree(s);
// disable buttons
XtVaSetValues(prevTenPageBtn, XmNsensitive, False, NULL);
XtVaSetValues(prevPageBtn, XmNsensitive, False, NULL);
XtVaSetValues(nextTenPageBtn, XmNsensitive, False, NULL);
XtVaSetValues(nextPageBtn, XmNsensitive, False, NULL);
// remove the old outline
#ifndef DISABLE_OUTLINE
setupOutline();
#endif
}
//------------------------------------------------------------------------
// load / display
//------------------------------------------------------------------------
GBool XPDFViewer::loadFile(GString *fileName, GString *ownerPassword,
GString *userPassword) {
return core->loadFile(fileName, ownerPassword, userPassword) == errNone;
}
void XPDFViewer::reloadFile() {
int pg;
if (!core->getDoc()) {
return;
}
pg = core->getPageNum();
loadFile(core->getDoc()->getFileName());
if (pg > core->getDoc()->getNumPages()) {
pg = core->getDoc()->getNumPages();
}
displayPage(pg, core->getZoom(), core->getRotate(), gFalse, gFalse);
}
void XPDFViewer::displayPage(int pageA, double zoomA, int rotateA,
GBool scrollToTop, GBool addToHist) {
core->displayPage(pageA, zoomA, rotateA, scrollToTop, addToHist);
}
void XPDFViewer::displayDest(LinkDest *dest, double zoomA, int rotateA,
GBool addToHist) {
core->displayDest(dest, zoomA, rotateA, addToHist);
}
void XPDFViewer::getPageAndDest(int pageA, GString *destName,
int *pageOut, LinkDest **destOut) {
Ref pageRef;
// find the page number for a named destination
*pageOut = pageA;
*destOut = NULL;
if (destName && (*destOut = core->getDoc()->findDest(destName))) {
if ((*destOut)->isPageRef()) {
pageRef = (*destOut)->getPageRef();
*pageOut = core->getDoc()->findPage(pageRef.num, pageRef.gen);
} else {
*pageOut = (*destOut)->getPageNum();
}
}
if (*pageOut <= 0) {
*pageOut = 1;
}
if (*pageOut > core->getDoc()->getNumPages()) {
*pageOut = core->getDoc()->getNumPages();
}
}
//------------------------------------------------------------------------
// hyperlinks / actions
//------------------------------------------------------------------------
void XPDFViewer::doLink(int wx, int wy, GBool onlyIfNoSelection,
GBool newWin) {
XPDFViewer *newViewer;
LinkAction *action;
int pg, selPg;
double xu, yu, selULX, selULY, selLRX, selLRY;
if (core->getHyperlinksEnabled() &&
core->cvtWindowToUser(wx, wy, &pg, &xu, &yu) &&
!(onlyIfNoSelection &&
core->getSelection(&selPg, &selULX, &selULY, &selLRX, &selLRY))) {
if ((action = core->findLink(pg, xu, yu))) {
if (newWin &&
core->getDoc()->getFileName() &&
(action->getKind() == actionGoTo ||
action->getKind() == actionGoToR ||
(action->getKind() == actionNamed &&
((LinkNamed *)action)->getName()->cmp("Quit")))) {
newViewer = app->open(core->getDoc()->getFileName());
newViewer->core->doAction(action);
} else {
core->doAction(action);
}
}
}
}
void XPDFViewer::actionCbk(void *data, char *action) {
XPDFViewer *viewer = (XPDFViewer *)data;
if (!strcmp(action, "Quit")) {
viewer->app->quit();
}
}
//------------------------------------------------------------------------
// keyboard/mouse input
//------------------------------------------------------------------------
void XPDFViewer::keyPressCbk(void *data, KeySym key, Guint modifiers,
XEvent *event) {
XPDFViewer *viewer = (XPDFViewer *)data;
int keyCode;
GList *cmds;
int i;
if (key >= 0x20 && key <= 0xfe) {
keyCode = (int)key;
} else if (key == XK_Tab ||
key == XK_KP_Tab) {
keyCode = xpdfKeyCodeTab;
} else if (key == XK_Return) {
keyCode = xpdfKeyCodeReturn;
} else if (key == XK_KP_Enter) {
keyCode = xpdfKeyCodeEnter;
} else if (key == XK_BackSpace) {
keyCode = xpdfKeyCodeBackspace;
} else if (key == XK_Insert ||
key == XK_KP_Insert) {
keyCode = xpdfKeyCodeInsert;
} else if (key == XK_Delete ||
key == XK_KP_Delete) {
keyCode = xpdfKeyCodeDelete;
} else if (key == XK_Home ||
key == XK_KP_Home) {
keyCode = xpdfKeyCodeHome;
} else if (key == XK_End ||
key == XK_KP_End) {
keyCode = xpdfKeyCodeEnd;
} else if (key == XK_Page_Up ||
key == XK_KP_Page_Up) {
keyCode = xpdfKeyCodePgUp;
} else if (key == XK_Page_Down ||
key == XK_KP_Page_Down) {
keyCode = xpdfKeyCodePgDn;
} else if (key == XK_Left ||
key == XK_KP_Left) {
keyCode = xpdfKeyCodeLeft;
} else if (key == XK_Right ||
key == XK_KP_Right) {
keyCode = xpdfKeyCodeRight;
} else if (key == XK_Up ||
key == XK_KP_Up) {
keyCode = xpdfKeyCodeUp;
} else if (key == XK_Down ||
key == XK_KP_Down) {
keyCode = xpdfKeyCodeDown;
} else if (key >= XK_F1 && key <= XK_F35) {
keyCode = xpdfKeyCodeF1 + (key - XK_F1);
} else {
return;
}
if ((cmds = globalParams->getKeyBinding(keyCode,
viewer->getModifiers(modifiers),
viewer->getContext(modifiers)))) {
for (i = 0; i < cmds->getLength(); ++i) {
viewer->execCmd((GString *)cmds->get(i), event);
}
deleteGList(cmds, GString);
}
}
void XPDFViewer::mouseCbk(void *data, XEvent *event) {
XPDFViewer *viewer = (XPDFViewer *)data;
int keyCode;
GList *cmds;
int i;
if (event->type == ButtonPress) {
if (event->xbutton.button >= 1 && event->xbutton.button <= 7) {
keyCode = xpdfKeyCodeMousePress1 + event->xbutton.button - 1;
} else {
return;
}
} else if (event->type == ButtonRelease) {
if (event->xbutton.button >= 1 && event->xbutton.button <= 7) {
keyCode = xpdfKeyCodeMouseRelease1 + event->xbutton.button - 1;
} else {
return;
}
} else {
return;
}
if ((cmds = globalParams->getKeyBinding(keyCode,
viewer->getModifiers(
event->xkey.state),
viewer->getContext(
event->xkey.state)))) {
for (i = 0; i < cmds->getLength(); ++i) {
viewer->execCmd((GString *)cmds->get(i), event);
}
deleteGList(cmds, GString);
}
}
int XPDFViewer::getModifiers(Guint modifiers) {
int mods;
mods = 0;
if (modifiers & ShiftMask) {
mods |= xpdfKeyModShift;
}
if (modifiers & ControlMask) {
mods |= xpdfKeyModCtrl;
}
if (modifiers & Mod1Mask) {
mods |= xpdfKeyModAlt;
}
return mods;
}
int XPDFViewer::getContext(Guint modifiers) {
int context;
context = (core->getFullScreen() ? xpdfKeyContextFullScreen
: xpdfKeyContextWindow) |
(core->getContinuousMode() ? xpdfKeyContextContinuous
: xpdfKeyContextSinglePage) |
(core->getLinkAction() ? xpdfKeyContextOverLink
: xpdfKeyContextOffLink) |
((modifiers & Mod5Mask) ? xpdfKeyContextScrLockOn
: xpdfKeyContextScrLockOff);
return context;
}
void XPDFViewer::execCmd(GString *cmd, XEvent *event) {
GString *name;
GString *args[cmdMaxArgs];
char *p0, *p1;
int nArgs, i;
int a, b, m, cmp;
//----- parse the command
name = NULL;
nArgs = 0;
for (i = 0; i < cmdMaxArgs; ++i) {
args[i] = NULL;
}
p0 = cmd->getCString();
for (p1 = p0; *p1 && isalnum(*p1); ++p1) ;
if (p1 == p0) {
goto err1;
}
name = new GString(p0, p1 - p0);
if (*p1 == '(') {
while (nArgs < cmdMaxArgs) {
p0 = p1 + 1;
for (p1 = p0; *p1 && *p1 != ',' && *p1 != ')'; ++p1) ;
args[nArgs++] = new GString(p0, p1 - p0);
if (*p1 != ',') {
break;
}
}
if (*p1 != ')') {
goto err1;
}
++p1;
}
if (*p1) {
goto err1;
}
//----- find the command
a = -1;
b = nCmds;
// invariant: cmdTab[a].name < name < cmdTab[b].name
while (b - a > 1) {
m = (a + b) / 2;
cmp = strcmp(cmdTab[m].name, name->getCString());
if (cmp < 0) {
a = m;
} else if (cmp > 0) {
b = m;
} else {
a = b = m;
}
}
if (cmp != 0) {
goto err1;
}
//----- execute the command
if (nArgs != cmdTab[a].nArgs ||
(cmdTab[a].requiresEvent && !event)) {
goto err1;
}
if (cmdTab[a].requiresDoc && !core->getDoc()) {
// don't issue an error message for this -- it happens, e.g., when
// clicking in a window with no open PDF file
goto err2;
}
(this->*cmdTab[a].func)(args, nArgs, event);
//----- clean up
delete name;
for (i = 0; i < nArgs; ++i) {
if (args[i]) {
delete args[i];
}
}
return;
err1:
error(-1, "Invalid command syntax: '%s'", cmd->getCString());
err2:
if (name) {
delete name;
}
for (i = 0; i < nArgs; ++i) {
if (args[i]) {
delete args[i];
}
}
}
//------------------------------------------------------------------------
// command functions
//------------------------------------------------------------------------
static int mouseX(XEvent *event) {
switch (event->type) {
case ButtonPress:
case ButtonRelease:
return event->xbutton.x;
case KeyPress:
return event->xkey.x;
}
return 0;
}
static int mouseY(XEvent *event) {
switch (event->type) {
case ButtonPress:
case ButtonRelease:
return event->xbutton.y;
case KeyPress:
return event->xkey.y;
}
return 0;
}
void XPDFViewer::cmdAbout(GString *args[], int nArgs,
XEvent *event) {
XtManageChild(aboutDialog);
}
void XPDFViewer::cmdCloseOutline(GString *args[], int nArgs,
XEvent *event) {
#ifndef DISABLE_OUTLINE
Dimension w;
if (outlineScroll == None) {
return;
}
XtVaGetValues(outlineScroll, XmNwidth, &w, NULL);
if (w > 1) {
outlinePaneWidth = w;
// this ugly kludge is apparently the only way to resize the panes
// within an XmPanedWindow
XtVaSetValues(outlineScroll, XmNpaneMinimum, 1,
XmNpaneMaximum, 1, NULL);
XtVaSetValues(outlineScroll, XmNpaneMinimum, 1,
XmNpaneMaximum, 10000, NULL);
}
#endif
}
void XPDFViewer::cmdCloseWindow(GString *args[], int nArgs,
XEvent *event) {
app->close(this, gFalse);
}
void XPDFViewer::cmdContinuousMode(GString *args[], int nArgs,
XEvent *event) {
Widget btn;
if (core->getContinuousMode()) {
return;
}
core->setContinuousMode(gTrue);
btn = XtNameToWidget(popupMenu, "continuousMode");
XtVaSetValues(btn, XmNset, XmSET, NULL);
}
void XPDFViewer::cmdEndPan(GString *args[], int nArgs,
XEvent *event) {
core->endPan(mouseX(event), mouseY(event));
}
void XPDFViewer::cmdEndSelection(GString *args[], int nArgs,
XEvent *event) {
core->endSelection(mouseX(event), mouseY(event));
}
void XPDFViewer::cmdFind(GString *args[], int nArgs,
XEvent *event) {
mapFindDialog();
}
void XPDFViewer::cmdFindNext(GString *args[], int nArgs,
XEvent *event) {
doFind(gTrue);
}
void XPDFViewer::cmdFocusToDocWin(GString *args[], int nArgs,
XEvent *event) {
core->takeFocus();
}
void XPDFViewer::cmdFocusToPageNum(GString *args[], int nArgs,
XEvent *event) {
XmTextFieldSetSelection(pageNumText, 0,
strlen(XmTextFieldGetString(pageNumText)),
XtLastTimestampProcessed(display));
XmProcessTraversal(pageNumText, XmTRAVERSE_CURRENT);
}
void XPDFViewer::cmdFollowLink(GString *args[], int nArgs,
XEvent *event) {
doLink(mouseX(event), mouseY(event), gFalse, gFalse);
}
void XPDFViewer::cmdFollowLinkInNewWin(GString *args[], int nArgs,
XEvent *event) {
doLink(mouseX(event), mouseY(event), gFalse, gTrue);
}
void XPDFViewer::cmdFollowLinkInNewWinNoSel(GString *args[], int nArgs,
XEvent *event) {
doLink(mouseX(event), mouseY(event), gTrue, gTrue);
}
void XPDFViewer::cmdFollowLinkNoSel(GString *args[], int nArgs,
XEvent *event) {
doLink(mouseX(event), mouseY(event), gTrue, gFalse);
}
void XPDFViewer::cmdFullScreenMode(GString *args[], int nArgs,
XEvent *event) {
PDFDoc *doc;
XPDFViewer *viewer;
int pg;
Widget btn;
if (core->getFullScreen()) {
return;
}
pg = core->getPageNum();
XtPopdown(win);
doc = core->takeDoc(gFalse);
viewer = app->reopen(this, doc, pg, gTrue);
btn = XtNameToWidget(viewer->popupMenu, "fullScreen");
XtVaSetValues(btn, XmNset, XmSET, NULL);
}
void XPDFViewer::cmdGoBackward(GString *args[], int nArgs,
XEvent *event) {
core->goBackward();
}
void XPDFViewer::cmdGoForward(GString *args[], int nArgs,
XEvent *event) {
core->goForward();
}
void XPDFViewer::cmdGotoDest(GString *args[], int nArgs,
XEvent *event) {
int pg;
LinkDest *dest;
getPageAndDest(1, args[0], &pg, &dest);
if (dest) {
displayDest(dest, core->getZoom(), core->getRotate(), gTrue);
delete dest;
}
}
void XPDFViewer::cmdGotoLastPage(GString *args[], int nArgs,
XEvent *event) {
displayPage(core->getDoc()->getNumPages(),
core->getZoom(), core->getRotate(),
gTrue, gTrue);
}
void XPDFViewer::cmdGotoLastPageNoScroll(GString *args[], int nArgs,
XEvent *event) {
displayPage(core->getDoc()->getNumPages(),
core->getZoom(), core->getRotate(),
gFalse, gTrue);
}
void XPDFViewer::cmdGotoPage(GString *args[], int nArgs,
XEvent *event) {
int pg;
pg = atoi(args[0]->getCString());
if (pg < 1 || pg > core->getDoc()->getNumPages()) {
return;
}
displayPage(pg, core->getZoom(), core->getRotate(), gTrue, gTrue);
}
void XPDFViewer::cmdGotoPageNoScroll(GString *args[], int nArgs,
XEvent *event) {
int pg;
pg = atoi(args[0]->getCString());
if (pg < 1 || pg > core->getDoc()->getNumPages()) {
return;
}
displayPage(pg, core->getZoom(), core->getRotate(), gFalse, gTrue);
}
void XPDFViewer::cmdNextPage(GString *args[], int nArgs,
XEvent *event) {
core->gotoNextPage(1, gTrue);
}
void XPDFViewer::cmdNextPageNoScroll(GString *args[], int nArgs,
XEvent *event) {
core->gotoNextPage(1, gFalse);
}
void XPDFViewer::cmdOpen(GString *args[], int nArgs,
XEvent *event) {
mapOpenDialog(gFalse);
}
void XPDFViewer::cmdOpenFile(GString *args[], int nArgs,
XEvent *event) {
open(args[0], 1, NULL);
}
void XPDFViewer::cmdOpenFileAtDest(GString *args[], int nArgs,
XEvent *event) {
open(args[0], 1, args[1]);
}
void XPDFViewer::cmdOpenFileAtDestInNewWin(GString *args[], int nArgs,
XEvent *event) {
app->openAtDest(args[0], args[1]);
}
void XPDFViewer::cmdOpenFileAtPage(GString *args[], int nArgs,
XEvent *event) {
open(args[0], atoi(args[1]->getCString()), NULL);
}
void XPDFViewer::cmdOpenFileAtPageInNewWin(GString *args[], int nArgs,
XEvent *event) {
app->open(args[0], atoi(args[1]->getCString()));
}
void XPDFViewer::cmdOpenFileInNewWin(GString *args[], int nArgs,
XEvent *event) {
app->open(args[0]);
}
void XPDFViewer::cmdOpenInNewWin(GString *args[], int nArgs,
XEvent *event) {
mapOpenDialog(gTrue);
}
void XPDFViewer::cmdOpenOutline(GString *args[], int nArgs,
XEvent *event) {
#ifndef DISABLE_OUTLINE
Dimension w;
if (outlineScroll == None) {
return;
}
XtVaGetValues(outlineScroll, XmNwidth, &w, NULL);
if (w == 1) {
// this ugly kludge is apparently the only way to resize the panes
// within an XmPanedWindow
XtVaSetValues(outlineScroll, XmNpaneMinimum, outlinePaneWidth,
XmNpaneMaximum, outlinePaneWidth, NULL);
XtVaSetValues(outlineScroll, XmNpaneMinimum, 1,
XmNpaneMaximum, 10000, NULL);
}
#endif
}
void XPDFViewer::cmdPageDown(GString *args[], int nArgs,
XEvent *event) {
core->scrollPageDown();
}
void XPDFViewer::cmdPageUp(GString *args[], int nArgs,
XEvent *event) {
core->scrollPageUp();
}
void XPDFViewer::cmdPostPopupMenu(GString *args[], int nArgs,
XEvent *event) {
XmMenuPosition(popupMenu, event->type == ButtonPress ? &event->xbutton
: (XButtonEvent *)NULL);
XtManageChild(popupMenu);
// this is magic (taken from DDD) - weird things happen if this
// call isn't made (this is done in two different places, in hopes
// of squashing this stupid bug)
XtUngrabButton(core->getDrawAreaWidget(), AnyButton, AnyModifier);
}
void XPDFViewer::cmdPrevPage(GString *args[], int nArgs,
XEvent *event) {
core->gotoPrevPage(1, gTrue, gFalse);
}
void XPDFViewer::cmdPrevPageNoScroll(GString *args[], int nArgs,
XEvent *event) {
core->gotoPrevPage(1, gFalse, gFalse);
}
void XPDFViewer::cmdPrint(GString *args[], int nArgs,
XEvent *event) {
XtManageChild(printDialog);
}
void XPDFViewer::cmdQuit(GString *args[], int nArgs,
XEvent *event) {
app->quit();
}
void XPDFViewer::cmdRaise(GString *args[], int nArgs,
XEvent *event) {
XMapRaised(display, XtWindow(win));
XFlush(display);
}
void XPDFViewer::cmdRedraw(GString *args[], int nArgs,
XEvent *event) {
displayPage(core->getPageNum(), core->getZoom(), core->getRotate(),
gFalse, gFalse);
}
void XPDFViewer::cmdReload(GString *args[], int nArgs,
XEvent *event) {
reloadFile();
}
void XPDFViewer::cmdRun(GString *args[], int nArgs,
XEvent *event) {
GString *fmt, *cmd, *s;
LinkAction *action;
double selLRX, selLRY, selURX, selURY;
int selPage;
GBool gotSel;
char buf[64];
char *p;
char c0, c1;
int i;
cmd = new GString();
fmt = args[0];
i = 0;
gotSel = gFalse;
while (i < fmt->getLength()) {
c0 = fmt->getChar(i);
if (c0 == '%' && i+1 < fmt->getLength()) {
c1 = fmt->getChar(i+1);
switch (c1) {
case 'f':
if (core->getDoc() && (s = core->getDoc()->getFileName())) {
cmd->append(s);
}
break;
case 'b':
if (core->getDoc() && (s = core->getDoc()->getFileName())) {
if ((p = strrchr(s->getCString(), '.'))) {
cmd->append(s->getCString(), p - s->getCString());
} else {
cmd->append(s);
}
}
break;
case 'u':
if ((action = core->getLinkAction()) &&
action->getKind() == actionURI) {
s = core->mungeURL(((LinkURI *)action)->getURI());
cmd->append(s);
delete s;
}
break;
case 'x':
case 'y':
case 'X':
case 'Y':
if (!gotSel) {
if (!core->getSelection(&selPage, &selURX, &selURY,
&selLRX, &selLRY)) {
selPage = 0;
selURX = selURY = selLRX = selLRY = 0;
}
gotSel = gTrue;
}
sprintf(buf, "%g",
(c1 == 'x') ? selURX :
(c1 == 'y') ? selURY :
(c1 == 'X') ? selLRX : selLRY);
cmd->append(buf);
break;
default:
cmd->append(c1);
break;
}
i += 2;
} else {
cmd->append(c0);
++i;
}
}
#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;
}
void XPDFViewer::cmdScrollDown(GString *args[], int nArgs,
XEvent *event) {
core->scrollDown(atoi(args[0]->getCString()));
}
void XPDFViewer::cmdScrollDownNextPage(GString *args[], int nArgs,
XEvent *event) {
core->scrollDownNextPage(atoi(args[0]->getCString()));
}
void XPDFViewer::cmdScrollLeft(GString *args[], int nArgs,
XEvent *event) {
core->scrollLeft(atoi(args[0]->getCString()));
}
void XPDFViewer::cmdScrollOutlineDown(GString *args[], int nArgs,
XEvent *event) {
#ifndef DISABLE_OUTLINE
Widget sb;
int val, inc, pageInc, m, slider;
if (outlineScroll == None) {
return;
}
if ((sb = XtNameToWidget(outlineScroll, "VertScrollBar"))) {
XtVaGetValues(sb, XmNvalue, &val, XmNincrement, &inc,
XmNpageIncrement, &pageInc, XmNmaximum, &m,
XmNsliderSize, &slider, NULL);
if ((val += inc * atoi(args[0]->getCString())) > m - slider) {
val = m - slider;
}
XmScrollBarSetValues(sb, val, slider, inc, pageInc, True);
}
#endif
}
void XPDFViewer::cmdScrollOutlineUp(GString *args[], int nArgs,
XEvent *event) {
#ifndef DISABLE_OUTLINE
Widget sb;
int val, inc, pageInc, m, slider;
if (outlineScroll == None) {
return;
}
if ((sb = XtNameToWidget(outlineScroll, "VertScrollBar"))) {
XtVaGetValues(sb, XmNvalue, &val, XmNincrement, &inc,
XmNpageIncrement, &pageInc, XmNminimum, &m,
XmNsliderSize, &slider, NULL);
if ((val -= inc * atoi(args[0]->getCString())) < m) {
val = m;
}
XmScrollBarSetValues(sb, val, slider, inc, pageInc, True);
}
#endif
}
void XPDFViewer::cmdScrollRight(GString *args[], int nArgs,
XEvent *event) {
core->scrollRight(atoi(args[0]->getCString()));
}
void XPDFViewer::cmdScrollToBottomEdge(GString *args[], int nArgs,
XEvent *event) {
core->scrollToBottomEdge();
}
void XPDFViewer::cmdScrollToBottomRight(GString *args[], int nArgs,
XEvent *event) {
core->scrollToBottomRight();
}
void XPDFViewer::cmdScrollToLeftEdge(GString *args[], int nArgs,
XEvent *event) {
core->scrollToLeftEdge();
}
void XPDFViewer::cmdScrollToRightEdge(GString *args[], int nArgs,
XEvent *event) {
core->scrollToRightEdge();
}
void XPDFViewer::cmdScrollToTopEdge(GString *args[], int nArgs,
XEvent *event) {
core->scrollToTopEdge();
}
void XPDFViewer::cmdScrollToTopLeft(GString *args[], int nArgs,
XEvent *event) {
core->scrollToTopLeft();
}
void XPDFViewer::cmdScrollUp(GString *args[], int nArgs,
XEvent *event) {
core->scrollUp(atoi(args[0]->getCString()));
}
void XPDFViewer::cmdScrollUpPrevPage(GString *args[], int nArgs,
XEvent *event) {
core->scrollUpPrevPage(atoi(args[0]->getCString()));
}
void XPDFViewer::cmdSinglePageMode(GString *args[], int nArgs,
XEvent *event) {
Widget btn;
if (!core->getContinuousMode()) {
return;
}
core->setContinuousMode(gFalse);
btn = XtNameToWidget(popupMenu, "continuousMode");
XtVaSetValues(btn, XmNset, XmUNSET, NULL);
}
void XPDFViewer::cmdStartPan(GString *args[], int nArgs,
XEvent *event) {
core->startPan(mouseX(event), mouseY(event));
}
void XPDFViewer::cmdStartSelection(GString *args[], int nArgs,
XEvent *event) {
core->startSelection(mouseX(event), mouseY(event));
}
void XPDFViewer::cmdToggleContinuousMode(GString *args[], int nArgs,
XEvent *event) {
if (core->getContinuousMode()) {
cmdSinglePageMode(NULL, 0, event);
} else {
cmdContinuousMode(NULL, 0, event);
}
}
void XPDFViewer::cmdToggleFullScreenMode(GString *args[], int nArgs,
XEvent *event) {
if (core->getFullScreen()) {
cmdWindowMode(NULL, 0, event);
} else {
cmdFullScreenMode(NULL, 0, event);
}
}
void XPDFViewer::cmdToggleOutline(GString *args[], int nArgs,
XEvent *event) {
#ifndef DISABLE_OUTLINE
Dimension w;
if (outlineScroll == None) {
return;
}
XtVaGetValues(outlineScroll, XmNwidth, &w, NULL);
if (w > 1) {
cmdCloseOutline(NULL, 0, event);
} else {
cmdOpenOutline(NULL, 0, event);
}
#endif
}
void XPDFViewer::cmdWindowMode(GString *args[], int nArgs,
XEvent *event) {
PDFDoc *doc;
XPDFViewer *viewer;
int pg;
Widget btn;
if (!core->getFullScreen()) {
return;
}
pg = core->getPageNum();
XtPopdown(win);
doc = core->takeDoc(gFalse);
viewer = app->reopen(this, doc, pg, gFalse);
btn = XtNameToWidget(viewer->popupMenu, "fullScreen");
XtVaSetValues(btn, XmNset, XmUNSET, NULL);
}
void XPDFViewer::cmdZoomFitPage(GString *args[], int nArgs,
XEvent *event) {
if (core->getZoom() != zoomPage) {
setZoomIdx(zoomPageIdx);
displayPage(core->getPageNum(), zoomPage,
core->getRotate(), gTrue, gFalse);
}
}
void XPDFViewer::cmdZoomFitWidth(GString *args[], int nArgs,
XEvent *event) {
if (core->getZoom() != zoomWidth) {
setZoomIdx(zoomWidthIdx);
displayPage(core->getPageNum(), zoomWidth,
core->getRotate(), gTrue, gFalse);
}
}
void XPDFViewer::cmdZoomIn(GString *args[], int nArgs,
XEvent *event) {
int z;
z = getZoomIdx();
if (z <= minZoomIdx && z > maxZoomIdx) {
--z;
setZoomIdx(z);
displayPage(core->getPageNum(), zoomMenuInfo[z].zoom,
core->getRotate(), gTrue, gFalse);
}
}
void XPDFViewer::cmdZoomOut(GString *args[], int nArgs,
XEvent *event) {
int z;
z = getZoomIdx();
if (z < minZoomIdx && z >= maxZoomIdx) {
++z;
setZoomIdx(z);
displayPage(core->getPageNum(), zoomMenuInfo[z].zoom,
core->getRotate(), gTrue, gFalse);
}
}
void XPDFViewer::cmdZoomPercent(GString *args[], int nArgs,
XEvent *event) {
double z;
z = atof(args[0]->getCString());
setZoomVal(z);
displayPage(core->getPageNum(), z, core->getRotate(), gTrue, gFalse);
}
void XPDFViewer::cmdZoomToSelection(GString *args[], int nArgs,
XEvent *event) {
int pg;
double ulx, uly, lrx, lry;
if (core->getSelection(&pg, &ulx, &uly, &lrx, &lry)) {
core->zoomToRect(pg, ulx, uly, lrx, lry);
}
}
//------------------------------------------------------------------------
// GUI code: main window
//------------------------------------------------------------------------
void XPDFViewer::initWindow(GBool fullScreen) {
Colormap colormap;
XColor xcol;
Atom state, val;
Arg args[20];
int n;
char *title;
display = XtDisplay(app->getAppShell());
screenNum = XScreenNumberOfScreen(XtScreen(app->getAppShell()));
toolBar = None;
#ifndef DISABLE_OUTLINE
outlineScroll = None;
#endif
// private colormap
if (app->getInstallCmap()) {
XtVaGetValues(app->getAppShell(), XmNcolormap, &colormap, NULL);
// ensure that BlackPixel and WhitePixel are reserved in the
// new colormap
xcol.red = xcol.green = xcol.blue = 0;
XAllocColor(display, colormap, &xcol);
xcol.red = xcol.green = xcol.blue = 65535;
XAllocColor(display, colormap, &xcol);
colormap = XCopyColormapAndFree(display, colormap);
}
// top-level window
n = 0;
title = app->getTitle() ? app->getTitle()->getCString()
: (char *)xpdfAppName;
XtSetArg(args[n], XmNtitle, title); ++n;
XtSetArg(args[n], XmNiconName, title); ++n;
XtSetArg(args[n], XmNminWidth, 100); ++n;
XtSetArg(args[n], XmNminHeight, 100); ++n;
XtSetArg(args[n], XmNbaseWidth, 0); ++n;
XtSetArg(args[n], XmNbaseHeight, 0); ++n;
XtSetArg(args[n], XmNdeleteResponse, XmDO_NOTHING); ++n;
win = XtCreatePopupShell("win", topLevelShellWidgetClass,
app->getAppShell(), args, n);
if (app->getInstallCmap()) {
XtVaSetValues(win, XmNcolormap, colormap, NULL);
}
XmAddWMProtocolCallback(win, XInternAtom(display, "WM_DELETE_WINDOW", False),
&closeMsgCbk, this);
// create the full-screen window
if (fullScreen) {
initCore(win, gTrue);
// create the normal (non-full-screen) window
} else {
if (app->getGeometry()) {
n = 0;
XtSetArg(args[n], XmNgeometry, app->getGeometry()->getCString()); ++n;
XtSetValues(win, args, n);
}
n = 0;
form = XmCreateForm(win, "form", args, n);
XtManageChild(form);
#ifdef DISABLE_OUTLINE
initToolbar(form);
n = 0;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
XtSetValues(toolBar, args, n);
initCore(form, gFalse);
n = 0;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); ++n;
XtSetArg(args[n], XmNbottomWidget, toolBar); ++n;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
XtSetValues(core->getWidget(), args, n);
#else
initToolbar(form);
n = 0;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
XtSetValues(toolBar, args, n);
initPanedWin(form);
n = 0;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); ++n;
XtSetArg(args[n], XmNbottomWidget, toolBar); ++n;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
XtSetValues(panedWin, args, n);
initCore(panedWin, fullScreen);
n = 0;
XtSetArg(args[n], XmNpositionIndex, 1); ++n;
XtSetArg(args[n], XmNallowResize, True); ++n;
XtSetArg(args[n], XmNpaneMinimum, 1); ++n;
XtSetArg(args[n], XmNpaneMaximum, 10000); ++n;
XtSetValues(core->getWidget(), args, n);
#endif
}
// set the zoom menu to match the initial zoom setting
setZoomVal(core->getZoom());
// set traversal order
XtVaSetValues(core->getDrawAreaWidget(),
XmNnavigationType, XmEXCLUSIVE_TAB_GROUP, NULL);
if (toolBar != None) {
XtVaSetValues(backBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
NULL);
XtVaSetValues(prevTenPageBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
NULL);
XtVaSetValues(prevPageBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
NULL);
XtVaSetValues(nextPageBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
NULL);
XtVaSetValues(nextTenPageBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
NULL);
XtVaSetValues(forwardBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
NULL);
XtVaSetValues(pageNumText, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
NULL);
XtVaSetValues(zoomWidget, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
NULL);
XtVaSetValues(findBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
NULL);
XtVaSetValues(printBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
NULL);
XtVaSetValues(aboutBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
NULL);
XtVaSetValues(quitBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
NULL);
}
initPopupMenu();
if (fullScreen) {
// Set both the old-style Motif decorations hint and the new-style
// _NET_WM_STATE property. This is redundant, but might be useful
// for older window managers. We also set the geometry to +0+0 to
// avoid interactive placement. (Note: we need to realize the
// shell, so it has a Window on which to set the _NET_WM_STATE
// property, but we don't want to map it until later, so we set
// mappedWhenManaged to false.)
n = 0;
XtSetArg(args[n], XmNmappedWhenManaged, False); ++n;
XtSetArg(args[n], XmNmwmDecorations, 0); ++n;
XtSetArg(args[n], XmNgeometry, "+0+0"); ++n;
XtSetValues(win, args, n);
XtRealizeWidget(win);
state = XInternAtom(display, "_NET_WM_STATE", False);
val = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", False);
XChangeProperty(display, XtWindow(win), state, XA_ATOM, 32,
PropModeReplace, (Guchar *)&val, 1);
}
}
void XPDFViewer::initToolbar(Widget parent) {
Widget label, lastBtn;
#ifndef USE_COMBO_BOX
Widget btn;
#endif
Arg args[20];
int n;
XmString s, emptyString;
int i;
// toolbar
n = 0;
toolBar = XmCreateForm(parent, "toolBar", args, n);
XtManageChild(toolBar);
// create an empty string -- this is used for buttons that will get
// pixmaps later
emptyString = XmStringCreateLocalized("");
// page movement buttons
n = 0;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNmarginWidth, 6); ++n;
XtSetArg(args[n], XmNsensitive, False); ++n;
XtSetArg(args[n], XmNlabelString, emptyString); ++n;
backBtn = XmCreatePushButton(toolBar, "back", args, n);
addToolTip(backBtn, "Back");
XtManageChild(backBtn);
XtAddCallback(backBtn, XmNactivateCallback,
&backCbk, (XtPointer)this);
n = 0;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
XtSetArg(args[n], XmNleftWidget, backBtn); ++n;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNmarginWidth, 6); ++n;
XtSetArg(args[n], XmNsensitive, False); ++n;
XtSetArg(args[n], XmNlabelString, emptyString); ++n;
prevTenPageBtn = XmCreatePushButton(toolBar, "prevTenPage", args, n);
addToolTip(prevTenPageBtn, "-10 pages");
XtManageChild(prevTenPageBtn);
XtAddCallback(prevTenPageBtn, XmNactivateCallback,
&prevTenPageCbk, (XtPointer)this);
n = 0;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
XtSetArg(args[n], XmNleftWidget, prevTenPageBtn); ++n;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNmarginWidth, 6); ++n;
XtSetArg(args[n], XmNsensitive, False); ++n;
XtSetArg(args[n], XmNlabelString, emptyString); ++n;
prevPageBtn = XmCreatePushButton(toolBar, "prevPage", args, n);
addToolTip(prevPageBtn, "Previous page");
XtManageChild(prevPageBtn);
XtAddCallback(prevPageBtn, XmNactivateCallback,
&prevPageCbk, (XtPointer)this);
n = 0;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
XtSetArg(args[n], XmNleftWidget, prevPageBtn); ++n;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNmarginWidth, 6); ++n;
XtSetArg(args[n], XmNsensitive, False); ++n;
XtSetArg(args[n], XmNlabelString, emptyString); ++n;
nextPageBtn = XmCreatePushButton(toolBar, "nextPage", args, n);
addToolTip(nextPageBtn, "Next page");
XtManageChild(nextPageBtn);
XtAddCallback(nextPageBtn, XmNactivateCallback,
&nextPageCbk, (XtPointer)this);
n = 0;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
XtSetArg(args[n], XmNleftWidget, nextPageBtn); ++n;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNmarginWidth, 6); ++n;
XtSetArg(args[n], XmNsensitive, False); ++n;
XtSetArg(args[n], XmNlabelString, emptyString); ++n;
nextTenPageBtn = XmCreatePushButton(toolBar, "nextTenPage", args, n);
addToolTip(nextTenPageBtn, "+10 pages");
XtManageChild(nextTenPageBtn);
XtAddCallback(nextTenPageBtn, XmNactivateCallback,
&nextTenPageCbk, (XtPointer)this);
n = 0;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
XtSetArg(args[n], XmNleftWidget, nextTenPageBtn); ++n;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNmarginWidth, 6); ++n;
XtSetArg(args[n], XmNsensitive, False); ++n;
XtSetArg(args[n], XmNlabelString, emptyString); ++n;
forwardBtn = XmCreatePushButton(toolBar, "forward", args, n);
addToolTip(forwardBtn, "Forward");
XtManageChild(forwardBtn);
XtAddCallback(forwardBtn, XmNactivateCallback,
&forwardCbk, (XtPointer)this);
// page number display
n = 0;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
XtSetArg(args[n], XmNleftWidget, forwardBtn); ++n;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
s = XmStringCreateLocalized("Page ");
XtSetArg(args[n], XmNlabelString, s); ++n;
label = XmCreateLabel(toolBar, "pageLabel", args, n);
XmStringFree(s);
XtManageChild(label);
n = 0;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
XtSetArg(args[n], XmNleftWidget, label); ++n;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNmarginWidth, 3); ++n;
XtSetArg(args[n], XmNmarginHeight, 3); ++n;
XtSetArg(args[n], XmNcolumns, 5); ++n;
pageNumText = XmCreateTextField(toolBar, "pageNum", args, n);
XtManageChild(pageNumText);
XtAddCallback(pageNumText, XmNactivateCallback,
&pageNumCbk, (XtPointer)this);
n = 0;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
XtSetArg(args[n], XmNleftWidget, pageNumText); ++n;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
s = XmStringCreateLocalized(" of 00000");
XtSetArg(args[n], XmNlabelString, s); ++n;
XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); ++n;
XtSetArg(args[n], XmNrecomputeSize, False); ++n;
pageCountLabel = XmCreateLabel(toolBar, "pageCountLabel", args, n);
XmStringFree(s);
XtManageChild(pageCountLabel);
s = XmStringCreateLocalized(" of 0");
XtVaSetValues(pageCountLabel, XmNlabelString, s, NULL);
XmStringFree(s);
// zoom menu
#if USE_COMBO_BOX
XmString st[nZoomMenuItems];
n = 0;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
XtSetArg(args[n], XmNleftWidget, pageCountLabel); ++n;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNmarginWidth, 0); ++n;
XtSetArg(args[n], XmNmarginHeight, 0); ++n;
XtSetArg(args[n], XmNcomboBoxType, XmDROP_DOWN_COMBO_BOX); ++n;
XtSetArg(args[n], XmNpositionMode, XmONE_BASED); ++n;
XtSetArg(args[n], XmNcolumns, 7); ++n;
for (i = 0; i < nZoomMenuItems; ++i) {
st[i] = XmStringCreateLocalized(zoomMenuInfo[i].label);
}
XtSetArg(args[n], XmNitems, st); ++n;
XtSetArg(args[n], XmNitemCount, nZoomMenuItems); ++n;
zoomComboBox = XmCreateComboBox(toolBar, "zoomComboBox", args, n);
for (i = 0; i < nZoomMenuItems; ++i) {
XmStringFree(st[i]);
}
addToolTip(zoomComboBox, "Zoom");
XtAddCallback(zoomComboBox, XmNselectionCallback,
&zoomComboBoxCbk, (XtPointer)this);
XtManageChild(zoomComboBox);
zoomWidget = zoomComboBox;
#else
Widget menuPane;
char buf[16];
n = 0;
menuPane = XmCreatePulldownMenu(toolBar, "zoomMenuPane", args, n);
for (i = 0; i < nZoomMenuItems; ++i) {
n = 0;
s = XmStringCreateLocalized(zoomMenuInfo[i].label);
XtSetArg(args[n], XmNlabelString, s); ++n;
XtSetArg(args[n], XmNuserData, (XtPointer)i); ++n;
sprintf(buf, "zoom%d", i);
btn = XmCreatePushButton(menuPane, buf, args, n);
XmStringFree(s);
XtManageChild(btn);
XtAddCallback(btn, XmNactivateCallback,
&zoomMenuCbk, (XtPointer)this);
zoomMenuBtns[i] = btn;
}
n = 0;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
XtSetArg(args[n], XmNleftWidget, pageCountLabel); ++n;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNmarginWidth, 0); ++n;
XtSetArg(args[n], XmNmarginHeight, 0); ++n;
XtSetArg(args[n], XmNsubMenuId, menuPane); ++n;
zoomMenu = XmCreateOptionMenu(toolBar, "zoomMenu", args, n);
addToolTip(zoomMenu, "Zoom");
XtManageChild(zoomMenu);
zoomWidget = zoomMenu;
#endif
// find/print/about buttons
n = 0;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
XtSetArg(args[n], XmNleftWidget, zoomWidget); ++n;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNmarginWidth, 6); ++n;
XtSetArg(args[n], XmNlabelString, emptyString); ++n;
findBtn = XmCreatePushButton(toolBar, "find", args, n);
addToolTip(findBtn, "Find");
XtManageChild(findBtn);
XtAddCallback(findBtn, XmNactivateCallback,
&findCbk, (XtPointer)this);
n = 0;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
XtSetArg(args[n], XmNleftWidget, findBtn); ++n;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNmarginWidth, 6); ++n;
XtSetArg(args[n], XmNlabelString, emptyString); ++n;
printBtn = XmCreatePushButton(toolBar, "print", args, n);
addToolTip(printBtn, "Print");
XtManageChild(printBtn);
XtAddCallback(printBtn, XmNactivateCallback,
&printCbk, (XtPointer)this);
n = 0;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
XtSetArg(args[n], XmNleftWidget, printBtn); ++n;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNmarginWidth, 6); ++n;
XtSetArg(args[n], XmNlabelString, emptyString); ++n;
aboutBtn = XmCreatePushButton(toolBar, "about", args, n);
addToolTip(aboutBtn, "About / help");
XtManageChild(aboutBtn);
XtAddCallback(aboutBtn, XmNactivateCallback,
&aboutCbk, (XtPointer)this);
lastBtn = aboutBtn;
// quit button
n = 0;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNmarginWidth, 6); ++n;
s = XmStringCreateLocalized("Quit");
XtSetArg(args[n], XmNlabelString, s); ++n;
quitBtn = XmCreatePushButton(toolBar, "quit", args, n);
XmStringFree(s);
XtManageChild(quitBtn);
XtAddCallback(quitBtn, XmNactivateCallback,
&quitCbk, (XtPointer)this);
// link label
n = 0;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
XtSetArg(args[n], XmNleftWidget, lastBtn); ++n;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); ++n;
XtSetArg(args[n], XmNrightWidget, quitBtn); ++n;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
s = XmStringCreateLocalized("");
XtSetArg(args[n], XmNlabelString, s); ++n;
XtSetArg(args[n], XmNrecomputeSize, True); ++n;
XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); ++n;
linkLabel = XmCreateLabel(toolBar, "linkLabel", args, n);
XmStringFree(s);
XtManageChild(linkLabel);
XmStringFree(emptyString);
}
#ifndef DISABLE_OUTLINE
void XPDFViewer::initPanedWin(Widget parent) {
Widget clipWin;
Arg args[20];
int n;
// paned window
n = 0;
XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
#if defined(__sgi) && (XmVERSION <= 1)
panedWin = SgCreateHorzPanedWindow(parent, "panedWin", args, n);
#else
panedWin = XmCreatePanedWindow(parent, "panedWin", args, n);
#endif
XtManageChild(panedWin);
// scrolled window for outline container
n = 0;
XtSetArg(args[n], XmNpositionIndex, 0); ++n;
XtSetArg(args[n], XmNallowResize, True); ++n;
XtSetArg(args[n], XmNpaneMinimum, 1); ++n;
XtSetArg(args[n], XmNpaneMaximum, 10000); ++n;
#if !(defined(__sgi) && (XmVERSION <= 1))
XtSetArg(args[n], XmNwidth, 1); ++n;
#endif
XtSetArg(args[n], XmNscrollingPolicy, XmAUTOMATIC); ++n;
outlineScroll = XmCreateScrolledWindow(panedWin, "outlineScroll", args, n);
XtManageChild(outlineScroll);
XtVaGetValues(outlineScroll, XmNclipWindow, &clipWin, NULL);
XtVaSetValues(clipWin, XmNbackground, app->getPaperPixel(), NULL);
// outline tree
n = 0;
XtSetArg(args[n], XmNbackground, app->getPaperPixel()); ++n;
outlineTree = XPDFCreateTree(outlineScroll, "outlineTree", args, n);
XtManageChild(outlineTree);
XtAddCallback(outlineTree, XPDFNselectionCallback, &outlineSelectCbk,
(XtPointer)this);
}
#endif
void XPDFViewer::initCore(Widget parent, GBool fullScreen) {
core = new XPDFCore(win, parent,
app->getPaperRGB(), app->getPaperPixel(),
app->getMattePixel(fullScreen),
fullScreen, app->getReverseVideo(),
app->getInstallCmap(), app->getRGBCubeSize());
core->setUpdateCbk(&updateCbk, this);
core->setActionCbk(&actionCbk, this);
core->setKeyPressCbk(&keyPressCbk, this);
core->setMouseCbk(&mouseCbk, this);
}
void XPDFViewer::initPopupMenu() {
Widget btn;
Arg args[20];
int n;
XmString s, s2;
n = 0;
#if XmVersion < 1002
// older versions of Motif need this, newer ones choke on it,
// sometimes not displaying the menu at all, maybe depending on the
// state of the NumLock key (taken from DDD)
XtSetArg(args[n], XmNmenuPost, "<Btn3Down>"); ++n;
#endif
popupMenu = XmCreatePopupMenu(core->getDrawAreaWidget(), "popupMenu",
args, n);
n = 0;
s = XmStringCreateLocalized("Open...");
XtSetArg(args[n], XmNlabelString, s); ++n;
s2 = XmStringCreateLocalized("O");
XtSetArg(args[n], XmNacceleratorText, s2); ++n;
btn = XmCreatePushButton(popupMenu, "open", args, n);
XmStringFree(s);
XmStringFree(s2);
XtManageChild(btn);
XtAddCallback(btn, XmNactivateCallback,
&openCbk, (XtPointer)this);
n = 0;
s = XmStringCreateLocalized("Open in new window...");
XtSetArg(args[n], XmNlabelString, s); ++n;
btn = XmCreatePushButton(popupMenu, "openInNewWindow", args, n);
XmStringFree(s);
XtManageChild(btn);
XtAddCallback(btn, XmNactivateCallback,
&openInNewWindowCbk, (XtPointer)this);
n = 0;
s = XmStringCreateLocalized("Reload");
XtSetArg(args[n], XmNlabelString, s); ++n;
s2 = XmStringCreateLocalized("R");
XtSetArg(args[n], XmNacceleratorText, s2); ++n;
btn = XmCreatePushButton(popupMenu, "reload", args, n);
XmStringFree(s);
XmStringFree(s2);
XtManageChild(btn);
XtAddCallback(btn, XmNactivateCallback,
&reloadCbk, (XtPointer)this);
n = 0;
s = XmStringCreateLocalized("Save as...");
XtSetArg(args[n], XmNlabelString, s); ++n;
btn = XmCreatePushButton(popupMenu, "saveAs", args, n);
XmStringFree(s);
XtManageChild(btn);
XtAddCallback(btn, XmNactivateCallback,
&saveAsCbk, (XtPointer)this);
n = 0;
btn = XmCreateSeparator(popupMenu, "sep1", args, n);
XtManageChild(btn);
n = 0;
s = XmStringCreateLocalized("Continuous view");
XtSetArg(args[n], XmNlabelString, s); ++n;
XtSetArg(args[n], XmNindicatorType, XmN_OF_MANY); ++n;
XtSetArg(args[n], XmNvisibleWhenOff, True); ++n;
XtSetArg(args[n], XmNset, core->getContinuousMode() ? XmSET : XmUNSET); ++n;
btn = XmCreateToggleButton(popupMenu, "continuousMode", args, n);
XmStringFree(s);
XtManageChild(btn);
XtAddCallback(btn, XmNvalueChangedCallback,
&continuousModeToggleCbk, (XtPointer)this);
n = 0;
s = XmStringCreateLocalized("Full screen");
XtSetArg(args[n], XmNlabelString, s); ++n;
XtSetArg(args[n], XmNindicatorType, XmN_OF_MANY); ++n;
XtSetArg(args[n], XmNvisibleWhenOff, True); ++n;
XtSetArg(args[n], XmNset, core->getFullScreen() ? XmSET : XmUNSET); ++n;
btn = XmCreateToggleButton(popupMenu, "fullScreen", args, n);
XmStringFree(s);
XtManageChild(btn);
XtAddCallback(btn, XmNvalueChangedCallback,
&fullScreenToggleCbk, (XtPointer)this);
n = 0;
s = XmStringCreateLocalized("Rotate counterclockwise");
XtSetArg(args[n], XmNlabelString, s); ++n;
btn = XmCreatePushButton(popupMenu, "rotateCCW", args, n);
XmStringFree(s);
XtManageChild(btn);
XtAddCallback(btn, XmNactivateCallback,
&rotateCCWCbk, (XtPointer)this);
n = 0;
s = XmStringCreateLocalized("Rotate clockwise");
XtSetArg(args[n], XmNlabelString, s); ++n;
btn = XmCreatePushButton(popupMenu, "rotateCW", args, n);
XmStringFree(s);
XtManageChild(btn);
XtAddCallback(btn, XmNactivateCallback,
&rotateCWCbk, (XtPointer)this);
n = 0;
s = XmStringCreateLocalized("Zoom to selection");
XtSetArg(args[n], XmNlabelString, s); ++n;
btn = XmCreatePushButton(popupMenu, "zoomToSelection", args, n);
XmStringFree(s);
XtManageChild(btn);
XtAddCallback(btn, XmNactivateCallback,
&zoomToSelectionCbk, (XtPointer)this);
n = 0;
btn = XmCreateSeparator(popupMenu, "sep2", args, n);
XtManageChild(btn);
n = 0;
s = XmStringCreateLocalized("Close");
XtSetArg(args[n], XmNlabelString, s); ++n;
s2 = XmStringCreateLocalized("Ctrl+W");
XtSetArg(args[n], XmNacceleratorText, s2); ++n;
btn = XmCreatePushButton(popupMenu, "close", args, n);
XmStringFree(s);
XmStringFree(s2);
XtManageChild(btn);
XtAddCallback(btn, XmNactivateCallback,
&closeCbk, (XtPointer)this);
n = 0;
s = XmStringCreateLocalized("Quit");
XtSetArg(args[n], XmNlabelString, s); ++n;
s2 = XmStringCreateLocalized("Q");
XtSetArg(args[n], XmNacceleratorText, s2); ++n;
btn = XmCreatePushButton(popupMenu, "quit", args, n);
XmStringFree(s);
XmStringFree(s2);
XtManageChild(btn);
XtAddCallback(btn, XmNactivateCallback,
&quitCbk, (XtPointer)this);
// this is magic (taken from DDD) - weird things happen if this
// call isn't made
XtUngrabButton(core->getDrawAreaWidget(), AnyButton, AnyModifier);
}
void XPDFViewer::addToolTip(Widget widget, char *text) {
#ifdef XmNtoolTipString
XmString s;
Cardinal n, i;
WidgetList children;
if (XtIsComposite(widget)) {
XtVaGetValues(widget, XmNnumChildren, &n, XmNchildren, &children, NULL);
for (i = 0; i < n; ++i) {
addToolTip(children[i], text);
}
} else {
s = XmStringCreateLocalized(text);
XtVaSetValues(widget, XmNtoolTipString, s, NULL);
XmStringFree(s);
}
#endif
}
void XPDFViewer::mapWindow() {
#ifdef HAVE_X11_XPM_H
Pixmap iconPixmap;
#endif
int depth;
Pixel fg, bg, arm;
// show the window
XtPopup(win, XtGrabNone);
core->takeFocus();
// create the icon
#ifdef HAVE_X11_XPM_H
if (XpmCreatePixmapFromData(display, XtWindow(win), xpdfIcon,
&iconPixmap, NULL, NULL) == XpmSuccess) {
XtVaSetValues(win, XmNiconPixmap, iconPixmap, NULL);
}
#endif
// set button bitmaps (must be done after the window is mapped)
if (toolBar != None) {
XtVaGetValues(backBtn, XmNdepth, &depth,
XmNforeground, &fg, XmNbackground, &bg,
XmNarmColor, &arm, NULL);
XtVaSetValues(backBtn, XmNlabelType, XmPIXMAP,
XmNlabelPixmap,
XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
(char *)backArrow_bits,
backArrow_width,
backArrow_height,
fg, bg, depth),
XmNarmPixmap,
XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
(char *)backArrow_bits,
backArrow_width,
backArrow_height,
fg, arm, depth),
XmNlabelInsensitivePixmap,
XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
(char *)backArrowDis_bits,
backArrowDis_width,
backArrowDis_height,
fg, bg, depth),
NULL);
XtVaSetValues(prevTenPageBtn, XmNlabelType, XmPIXMAP,
XmNlabelPixmap,
XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
(char *)dblLeftArrow_bits,
dblLeftArrow_width,
dblLeftArrow_height,
fg, bg, depth),
XmNarmPixmap,
XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
(char *)dblLeftArrow_bits,
dblLeftArrow_width,
dblLeftArrow_height,
fg, arm, depth),
XmNlabelInsensitivePixmap,
XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
(char *)dblLeftArrowDis_bits,
dblLeftArrowDis_width,
dblLeftArrowDis_height,
fg, bg, depth),
NULL);
XtVaSetValues(prevPageBtn, XmNlabelType, XmPIXMAP,
XmNlabelPixmap,
XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
(char *)leftArrow_bits,
leftArrow_width,
leftArrow_height,
fg, bg, depth),
XmNarmPixmap,
XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
(char *)leftArrow_bits,
leftArrow_width,
leftArrow_height,
fg, arm, depth),
XmNlabelInsensitivePixmap,
XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
(char *)leftArrowDis_bits,
leftArrowDis_width,
leftArrowDis_height,
fg, bg, depth),
NULL);
XtVaSetValues(nextPageBtn, XmNlabelType, XmPIXMAP,
XmNlabelPixmap,
XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
(char *)rightArrow_bits,
rightArrow_width,
rightArrow_height,
fg, bg, depth),
XmNarmPixmap,
XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
(char *)rightArrow_bits,
rightArrow_width,
rightArrow_height,
fg, arm, depth),
XmNlabelInsensitivePixmap,
XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
(char *)rightArrowDis_bits,
rightArrowDis_width,
rightArrowDis_height,
fg, bg, depth),
NULL);
XtVaSetValues(nextTenPageBtn, XmNlabelType, XmPIXMAP,
XmNlabelPixmap,
XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
(char *)dblRightArrow_bits,
dblRightArrow_width,
dblRightArrow_height,
fg, bg, depth),
XmNarmPixmap,
XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
(char *)dblRightArrow_bits,
dblRightArrow_width,
dblRightArrow_height,
fg, arm, depth),
XmNlabelInsensitivePixmap,
XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
(char *)dblRightArrowDis_bits,
dblRightArrowDis_width,
dblRightArrowDis_height,
fg, bg, depth),
NULL);
XtVaSetValues(forwardBtn, XmNlabelType, XmPIXMAP,
XmNlabelPixmap,
XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
(char *)forwardArrow_bits,
forwardArrow_width,
forwardArrow_height,
fg, bg, depth),
XmNarmPixmap,
XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
(char *)forwardArrow_bits,
forwardArrow_width,
forwardArrow_height,
fg, arm, depth),
XmNlabelInsensitivePixmap,
XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
(char *)forwardArrowDis_bits,
forwardArrowDis_width,
forwardArrowDis_height,
fg, bg, depth),
NULL);
XtVaSetValues(findBtn, XmNlabelType, XmPIXMAP,
XmNlabelPixmap,
XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
(char *)find_bits,
find_width,
find_height,
fg, bg, depth),
XmNarmPixmap,
XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
(char *)find_bits,
find_width,
find_height,
fg, arm, depth),
XmNlabelInsensitivePixmap,
XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
(char *)findDis_bits,
findDis_width,
findDis_height,
fg, bg, depth),
NULL);
XtVaSetValues(printBtn, XmNlabelType, XmPIXMAP,
XmNlabelPixmap,
XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
(char *)print_bits,
print_width,
print_height,
fg, bg, depth),
XmNarmPixmap,
XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
(char *)print_bits,
print_width,
print_height,
fg, arm, depth),
XmNlabelInsensitivePixmap,
XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
(char *)printDis_bits,
printDis_width,
printDis_height,
fg, bg, depth),
NULL);
XtVaSetValues(aboutBtn, XmNlabelType, XmPIXMAP,
XmNlabelPixmap,
XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
(char *)about_bits,
about_width,
about_height,
fg, bg, depth),
XmNarmPixmap,
XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
(char *)about_bits,
about_width,
about_height,
fg, arm, depth),
NULL);
}
}
void XPDFViewer::closeWindow() {
XtPopdown(win);
XtDestroyWidget(win);
}
int XPDFViewer::getZoomIdx() {
int i;
for (i = 0; i < nZoomMenuItems; ++i) {
if (core->getZoom() == zoomMenuInfo[i].zoom) {
return i;
}
}
return -1;
}
void XPDFViewer::setZoomIdx(int idx) {
if (toolBar == None) {
return;
}
#if USE_COMBO_BOX
XtVaSetValues(zoomComboBox, XmNselectedPosition, idx + 1, NULL);
#else
XtVaSetValues(zoomMenu, XmNmenuHistory, zoomMenuBtns[idx], NULL);
#endif
}
void XPDFViewer::setZoomVal(double z) {
if (toolBar == None) {
return;
}
#if USE_COMBO_BOX
char buf[32];
XmString s;
int i;
for (i = 0; i < nZoomMenuItems; ++i) {
if (z == zoomMenuInfo[i].zoom) {
XtVaSetValues(zoomComboBox, XmNselectedPosition, i + 1, NULL);
return;
}
}
sprintf(buf, "%d%%", (int)z);
s = XmStringCreateLocalized(buf);
XtVaSetValues(zoomComboBox, XmNselectedItem, s, NULL);
XmStringFree(s);
#else
int i;
for (i = 0; i < nZoomMenuItems; ++i) {
if (z == zoomMenuInfo[i].zoom) {
XtVaSetValues(zoomMenu, XmNmenuHistory, zoomMenuBtns[i], NULL);
return;
}
}
for (i = maxZoomIdx; i < minZoomIdx; ++i) {
if (z > zoomMenuInfo[i].zoom) {
break;
}
}
XtVaSetValues(zoomMenu, XmNmenuHistory, zoomMenuBtns[i], NULL);
#endif
}
void XPDFViewer::prevPageCbk(Widget widget, XtPointer ptr,
XtPointer callData) {
XPDFViewer *viewer = (XPDFViewer *)ptr;
viewer->core->gotoPrevPage(1, gTrue, gFalse);
viewer->core->takeFocus();
}
void XPDFViewer::prevTenPageCbk(Widget widget, XtPointer ptr,
XtPointer callData) {
XPDFViewer *viewer = (XPDFViewer *)ptr;
viewer->core->gotoPrevPage(10, gTrue, gFalse);
viewer->core->takeFocus();
}
void XPDFViewer::nextPageCbk(Widget widget, XtPointer ptr,
XtPointer callData) {
XPDFViewer *viewer = (XPDFViewer *)ptr;
viewer->core->gotoNextPage(1, gTrue);
viewer->core->takeFocus();
}
void XPDFViewer::nextTenPageCbk(Widget widget, XtPointer ptr,
XtPointer callData) {
XPDFViewer *viewer = (XPDFViewer *)ptr;
viewer->core->gotoNextPage(10, gTrue);
viewer->core->takeFocus();
}
void XPDFViewer::backCbk(Widget widget, XtPointer ptr,
XtPointer callData) {
XPDFViewer *viewer = (XPDFViewer *)ptr;
viewer->core->goBackward();
viewer->core->takeFocus();
}
void XPDFViewer::forwardCbk(Widget widget, XtPointer ptr,
XtPointer callData) {
XPDFViewer *viewer = (XPDFViewer *)ptr;
viewer->core->goForward();
viewer->core->takeFocus();
}
#if USE_COMBO_BOX
void XPDFViewer::zoomComboBoxCbk(Widget widget, XtPointer ptr,
XtPointer callData) {
XPDFViewer *viewer = (XPDFViewer *)ptr;
XmComboBoxCallbackStruct *data = (XmComboBoxCallbackStruct *)callData;
double z;
char *s;
XmStringContext context;
XmStringCharSet charSet;
XmStringDirection dir;
Boolean sep;
z = viewer->core->getZoom();
if (data->item_position == 0) {
XmStringInitContext(&context, data->item_or_text);
if (XmStringGetNextSegment(context, &s, &charSet, &dir, &sep)) {
z = atof(s);
if (z <= 1) {
z = defZoom;
}
XtFree(charSet);
XtFree(s);
}
XmStringFreeContext(context);
} else {
z = zoomMenuInfo[data->item_position - 1].zoom;
}
// only redraw if this was triggered by an event; otherwise
// the caller is responsible for doing the redraw
if (z != viewer->core->getZoom() && data->event) {
viewer->displayPage(viewer->core->getPageNum(), z,
viewer->core->getRotate(), gTrue, gFalse);
}
viewer->core->takeFocus();
}
#else // USE_COMBO_BOX
void XPDFViewer::zoomMenuCbk(Widget widget, XtPointer ptr,
XtPointer callData) {
XPDFViewer *viewer = (XPDFViewer *)ptr;
XmPushButtonCallbackStruct *data = (XmPushButtonCallbackStruct *)callData;
XtPointer userData;
double z;
XtVaGetValues(widget, XmNuserData, &userData, NULL);
z = zoomMenuInfo[(long)userData].zoom;
// only redraw if this was triggered by an event; otherwise
// the caller is responsible for doing the redraw
if (z != viewer->core->getZoom() && data->event) {
viewer->displayPage(viewer->core->getPageNum(), z,
viewer->core->getRotate(), gTrue, gFalse);
}
viewer->core->takeFocus();
}
#endif // USE_COMBO_BOX
void XPDFViewer::findCbk(Widget widget, XtPointer ptr,
XtPointer callData) {
XPDFViewer *viewer = (XPDFViewer *)ptr;
if (!viewer->core->getDoc()) {
return;
}
viewer->mapFindDialog();
}
void XPDFViewer::printCbk(Widget widget, XtPointer ptr,
XtPointer callData) {
XPDFViewer *viewer = (XPDFViewer *)ptr;
if (!viewer->core->getDoc()) {
return;
}
XtManageChild(viewer->printDialog);
}
void XPDFViewer::aboutCbk(Widget widget, XtPointer ptr,
XtPointer callData) {
XPDFViewer *viewer = (XPDFViewer *)ptr;
XtManageChild(viewer->aboutDialog);
}
void XPDFViewer::quitCbk(Widget widget, XtPointer ptr,
XtPointer callData) {
XPDFViewer *viewer = (XPDFViewer *)ptr;
viewer->app->quit();
}
void XPDFViewer::openCbk(Widget widget, XtPointer ptr,
XtPointer callData) {
XPDFViewer *viewer = (XPDFViewer *)ptr;
viewer->mapOpenDialog(gFalse);
}
void XPDFViewer::openInNewWindowCbk(Widget widget, XtPointer ptr,
XtPointer callData) {
XPDFViewer *viewer = (XPDFViewer *)ptr;
viewer->mapOpenDialog(gTrue);
}
void XPDFViewer::reloadCbk(Widget widget, XtPointer ptr,
XtPointer callData) {
XPDFViewer *viewer = (XPDFViewer *)ptr;
viewer->reloadFile();
}
void XPDFViewer::saveAsCbk(Widget widget, XtPointer ptr,
XtPointer callData) {
XPDFViewer *viewer = (XPDFViewer *)ptr;
if (!viewer->core->getDoc()) {
return;
}
viewer->mapSaveAsDialog();
}
void XPDFViewer::continuousModeToggleCbk(Widget widget, XtPointer ptr,
XtPointer callData) {
XPDFViewer *viewer = (XPDFViewer *)ptr;
XmToggleButtonCallbackStruct *data =
(XmToggleButtonCallbackStruct *)callData;
viewer->core->setContinuousMode(data->set == XmSET);
}
void XPDFViewer::fullScreenToggleCbk(Widget widget, XtPointer ptr,
XtPointer callData) {
XPDFViewer *viewer = (XPDFViewer *)ptr;
XmToggleButtonCallbackStruct *data =
(XmToggleButtonCallbackStruct *)callData;
if (data->set == XmSET) {
viewer->cmdFullScreenMode(NULL, 0, NULL);
} else {
viewer->cmdWindowMode(NULL, 0, NULL);
}
}
void XPDFViewer::rotateCCWCbk(Widget widget, XtPointer ptr,
XtPointer callData) {
XPDFViewer *viewer = (XPDFViewer *)ptr;
int r;
r = viewer->core->getRotate();
r = (r == 0) ? 270 : r - 90;
viewer->displayPage(viewer->core->getPageNum(), viewer->core->getZoom(),
r, gTrue, gFalse);
}
void XPDFViewer::rotateCWCbk(Widget widget, XtPointer ptr,
XtPointer callData) {
XPDFViewer *viewer = (XPDFViewer *)ptr;
int r;
r = viewer->core->getRotate();
r = (r == 270) ? 0 : r + 90;
viewer->displayPage(viewer->core->getPageNum(), viewer->core->getZoom(),
r, gTrue, gFalse);
}
void XPDFViewer::zoomToSelectionCbk(Widget widget, XtPointer ptr,
XtPointer callData) {
XPDFViewer *viewer = (XPDFViewer *)ptr;
int pg;
double ulx, uly, lrx, lry;
if (viewer->core->getSelection(&pg, &ulx, &uly, &lrx, &lry)) {
viewer->core->zoomToRect(pg, ulx, uly, lrx, lry);
}
}
void XPDFViewer::closeCbk(Widget widget, XtPointer ptr,
XtPointer callData) {
XPDFViewer *viewer = (XPDFViewer *)ptr;
viewer->app->close(viewer, gFalse);
}
void XPDFViewer::closeMsgCbk(Widget widget, XtPointer ptr,
XtPointer callData) {
XPDFViewer *viewer = (XPDFViewer *)ptr;
viewer->app->close(viewer, gTrue);
}
void XPDFViewer::pageNumCbk(Widget widget, XtPointer ptr,
XtPointer callData) {
XPDFViewer *viewer = (XPDFViewer *)ptr;
char *s, *p;
int pg;
char buf[20];
if (!viewer->core->getDoc()) {
goto err;
}
s = XmTextFieldGetString(viewer->pageNumText);
for (p = s; *p; ++p) {
if (!isdigit(*p)) {
goto err;
}
}
pg = atoi(s);
if (pg < 1 || pg > viewer->core->getDoc()->getNumPages()) {
goto err;
}
viewer->displayPage(pg, viewer->core->getZoom(),
viewer->core->getRotate(), gFalse, gTrue);
viewer->core->takeFocus();
return;
err:
XBell(viewer->display, 0);
sprintf(buf, "%d", viewer->core->getPageNum());
XmTextFieldSetString(viewer->pageNumText, buf);
}
void XPDFViewer::updateCbk(void *data, GString *fileName,
int pageNum, int numPages, char *linkString) {
XPDFViewer *viewer = (XPDFViewer *)data;
GString *title;
char buf[20];
XmString s;
if (fileName) {
if (!(title = viewer->app->getTitle())) {
title = (new GString(xpdfAppName))->append(": ")->append(fileName);
}
XtVaSetValues(viewer->win, XmNtitle, title->getCString(),
XmNiconName, title->getCString(), NULL);
if (!viewer->app->getTitle()) {
delete title;
}
#ifndef DISABLE_OUTLINE
viewer->setupOutline();
#endif
viewer->setupPrintDialog();
}
if (viewer->toolBar != None) {
if (pageNum >= 0) {
s = XmStringCreateLocalized("");
XtVaSetValues(viewer->linkLabel, XmNlabelString, s, NULL);
XmStringFree(s);
sprintf(buf, "%d", pageNum);
XmTextFieldSetString(viewer->pageNumText, buf);
XtVaSetValues(viewer->prevTenPageBtn, XmNsensitive,
pageNum > 1, NULL);
XtVaSetValues(viewer->prevPageBtn, XmNsensitive,
pageNum > 1, NULL);
XtVaSetValues(viewer->nextTenPageBtn, XmNsensitive,
pageNum < viewer->core->getDoc()->getNumPages(), NULL);
XtVaSetValues(viewer->nextPageBtn, XmNsensitive,
pageNum < viewer->core->getDoc()->getNumPages(), NULL);
XtVaSetValues(viewer->backBtn, XmNsensitive,
viewer->core->canGoBack(), NULL);
XtVaSetValues(viewer->forwardBtn, XmNsensitive,
viewer->core->canGoForward(), NULL);
}
if (numPages >= 0) {
sprintf(buf, " of %d", numPages);
s = XmStringCreateLocalized(buf);
XtVaSetValues(viewer->pageCountLabel, XmNlabelString, s, NULL);
XmStringFree(s);
}
if (linkString) {
s = XmStringCreateLocalized(linkString);
XtVaSetValues(viewer->linkLabel, XmNlabelString, s, NULL);
XmStringFree(s);
}
}
}
//------------------------------------------------------------------------
// GUI code: outline
//------------------------------------------------------------------------
#ifndef DISABLE_OUTLINE
void XPDFViewer::setupOutline() {
GList *items;
UnicodeMap *uMap;
GString *enc;
int i;
if (outlineScroll == None) {
return;
}
// unmanage and destroy the old labels
if (outlineLabels) {
XtUnmanageChildren(outlineLabels, outlineLabelsLength);
for (i = 0; i < outlineLabelsLength; ++i) {
XtDestroyWidget(outlineLabels[i]);
}
gfree(outlineLabels);
outlineLabels = NULL;
outlineLabelsLength = outlineLabelsSize = 0;
}
if (core->getDoc()) {
// create the new labels
items = core->getDoc()->getOutline()->getItems();
if (items && items->getLength() > 0) {
enc = new GString("Latin1");
uMap = globalParams->getUnicodeMap(enc);
delete enc;
setupOutlineItems(items, NULL, uMap);
uMap->decRefCnt();
}
// manage the new labels
XtManageChildren(outlineLabels, outlineLabelsLength);
}
}
void XPDFViewer::setupOutlineItems(GList *items, Widget parent,
UnicodeMap *uMap) {
OutlineItem *item;
GList *kids;
Widget label;
Arg args[20];
GString *title;
char buf[8];
XmString s;
int i, j, n;
for (i = 0; i < items->getLength(); ++i) {
item = (OutlineItem *)items->get(i);
title = new GString();
for (j = 0; j < item->getTitleLength(); ++j) {
n = uMap->mapUnicode(item->getTitle()[j], buf, sizeof(buf));
title->append(buf, n);
}
n = 0;
XtSetArg(args[n], XPDFNentryPosition, i); ++n;
if (parent) {
XtSetArg(args[n], XPDFNentryParent, parent); ++n;
}
XtSetArg(args[n], XPDFNentryExpanded, item->isOpen()); ++n;
s = XmStringCreateLocalized(title->getCString());
delete title;
XtSetArg(args[n], XmNlabelString, s); ++n;
XtSetArg(args[n], XmNuserData, item); ++n;
XtSetArg(args[n], XmNmarginWidth, 0); ++n;
XtSetArg(args[n], XmNmarginHeight, 2); ++n;
XtSetArg(args[n], XmNshadowThickness, 0); ++n;
XtSetArg(args[n], XmNforeground,
app->getReverseVideo() ? WhitePixel(display, screenNum)
: BlackPixel(display, screenNum)); ++n;
XtSetArg(args[n], XmNbackground, app->getPaperPixel()); ++n;
label = XmCreateLabelGadget(outlineTree, "label", args, n);
XmStringFree(s);
if (outlineLabelsLength == outlineLabelsSize) {
outlineLabelsSize += 64;
outlineLabels = (Widget *)greallocn(outlineLabels,
outlineLabelsSize, sizeof(Widget *));
}
outlineLabels[outlineLabelsLength++] = label;
item->open();
if ((kids = item->getKids())) {
setupOutlineItems(kids, label, uMap);
}
}
}
void XPDFViewer::outlineSelectCbk(Widget widget, XtPointer ptr,
XtPointer callData) {
XPDFViewer *viewer = (XPDFViewer *)ptr;
XPDFTreeSelectCallbackStruct *data =
(XPDFTreeSelectCallbackStruct *)callData;
OutlineItem *item;
XtVaGetValues(data->selectedItem, XmNuserData, &item, NULL);
if (item) {
if (item->getAction()) {
viewer->core->doAction(item->getAction());
}
}
viewer->core->takeFocus();
}
#endif // !DISABLE_OUTLINE
//------------------------------------------------------------------------
// GUI code: "about" dialog
//------------------------------------------------------------------------
void XPDFViewer::initAboutDialog() {
Widget scrolledWin, col, label, sep, closeBtn;
Arg args[20];
int n, i;
XmString s;
char buf[20];
//----- dialog
n = 0;
s = XmStringCreateLocalized(xpdfAppName ": About");
XtSetArg(args[n], XmNdialogTitle, s); ++n;
XtSetArg(args[n], XmNwidth, 450); ++n;
XtSetArg(args[n], XmNheight, 300); ++n;
aboutDialog = XmCreateFormDialog(win, "aboutDialog", args, n);
XmStringFree(s);
//----- "close" button
n = 0;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNrightOffset, 4); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNbottomOffset, 4); ++n;
closeBtn = XmCreatePushButton(aboutDialog, "Close", args, n);
XtManageChild(closeBtn);
n = 0;
XtSetArg(args[n], XmNdefaultButton, closeBtn); ++n;
XtSetArg(args[n], XmNcancelButton, closeBtn); ++n;
XtSetValues(aboutDialog, args, n);
//----- scrolled window and RowColumn
n = 0;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); ++n;
XtSetArg(args[n], XmNbottomWidget, closeBtn); ++n;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNscrollingPolicy, XmAUTOMATIC); ++n;
scrolledWin = XmCreateScrolledWindow(aboutDialog, "scrolledWin", args, n);
XtManageChild(scrolledWin);
n = 0;
XtSetArg(args[n], XmNorientation, XmVERTICAL); ++n;
XtSetArg(args[n], XmNpacking, XmPACK_TIGHT); ++n;
col = XmCreateRowColumn(scrolledWin, "col", args, n);
XtManageChild(col);
//----- fonts
aboutBigFont =
createFontList("-*-times-bold-i-normal--20-*-*-*-*-*-iso8859-1");
aboutVersionFont =
createFontList("-*-times-medium-r-normal--16-*-*-*-*-*-iso8859-1");
aboutFixedFont =
createFontList("-*-courier-medium-r-normal--12-*-*-*-*-*-iso8859-1");
//----- heading
n = 0;
s = XmStringCreateLocalized("Xpdf");
XtSetArg(args[n], XmNlabelString, s); ++n;
XtSetArg(args[n], XmNfontList, aboutBigFont); ++n;
label = XmCreateLabel(col, "h0", args, n);
XmStringFree(s);
XtManageChild(label);
n = 0;
s = XmStringCreateLocalized("Version " xpdfVersion);
XtSetArg(args[n], XmNlabelString, s); ++n;
XtSetArg(args[n], XmNfontList, aboutVersionFont); ++n;
label = XmCreateLabel(col, "h1", args, n);
XmStringFree(s);
XtManageChild(label);
n = 0;
s = XmStringCreateLocalized(xpdfCopyright);
XtSetArg(args[n], XmNlabelString, s); ++n;
XtSetArg(args[n], XmNfontList, aboutVersionFont); ++n;
label = XmCreateLabel(col, "h2", args, n);
XmStringFree(s);
XtManageChild(label);
n = 0;
s = XmStringCreateLocalized(" ");
XtSetArg(args[n], XmNlabelString, s); ++n;
XtSetArg(args[n], XmNfontList, aboutVersionFont); ++n;
label = XmCreateLabel(col, "h3", args, n);
XmStringFree(s);
XtManageChild(label);
n = 0;
XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
sep = XmCreateSeparator(col, "sep", args, n);
XtManageChild(sep);
n = 0;
s = XmStringCreateLocalized(" ");
XtSetArg(args[n], XmNlabelString, s); ++n;
XtSetArg(args[n], XmNfontList, aboutVersionFont); ++n;
label = XmCreateLabel(col, "h4", args, n);
XmStringFree(s);
XtManageChild(label);
n = 0;
//----- text
for (i = 0; aboutWinText[i]; ++i) {
n = 0;
s = XmStringCreateLocalized(aboutWinText[i]);
XtSetArg(args[n], XmNlabelString, s); ++n;
XtSetArg(args[n], XmNfontList, aboutFixedFont); ++n;
sprintf(buf, "t%d", i);
label = XmCreateLabel(col, buf, args, n);
XtManageChild(label);
XmStringFree(s);
}
}
//------------------------------------------------------------------------
// GUI code: "open" dialog
//------------------------------------------------------------------------
void XPDFViewer::initOpenDialog() {
Arg args[20];
int n;
XmString s1, s2, s3;
GString *dir;
n = 0;
s1 = XmStringCreateLocalized("Open");
XtSetArg(args[n], XmNokLabelString, s1); ++n;
s2 = XmStringCreateLocalized("*.[Pp][Dd][Ff]");
XtSetArg(args[n], XmNpattern, s2); ++n;
s3 = XmStringCreateLocalized(xpdfAppName ": Open");
XtSetArg(args[n], XmNdialogTitle, s3); ++n;
XtSetArg(args[n], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); ++n;
XtSetArg(args[n], XmNautoUnmanage, True); ++n;
openDialog = XmCreateFileSelectionDialog(win, "openDialog", args, n);
XmStringFree(s1);
XmStringFree(s2);
XmStringFree(s3);
XtUnmanageChild(XmFileSelectionBoxGetChild(openDialog,
XmDIALOG_HELP_BUTTON));
XtAddCallback(openDialog, XmNokCallback,
&openOkCbk, (XtPointer)this);
if (core->getDoc() && core->getDoc()->getFileName()) {
dir = makePathAbsolute(grabPath(
core->getDoc()->getFileName()->getCString()));
s1 = XmStringCreateLocalized(dir->getCString());
XtVaSetValues(openDialog, XmNdirectory, s1, NULL);
XmStringFree(s1);
delete dir;
}
}
void XPDFViewer::mapOpenDialog(GBool openInNewWindowA) {
if (!openDialog) {
initOpenDialog();
}
openInNewWindow = openInNewWindowA;
XmFileSelectionDoSearch(openDialog, NULL);
XtManageChild(openDialog);
}
void XPDFViewer::openOkCbk(Widget widget, XtPointer ptr,
XtPointer callData) {
XPDFViewer *viewer = (XPDFViewer *)ptr;
XmFileSelectionBoxCallbackStruct *data =
(XmFileSelectionBoxCallbackStruct *)callData;
char *fileName;
XmStringContext context;
XmStringCharSet charSet;
XmStringDirection dir;
Boolean sep;
GString *fileNameStr;
XmStringInitContext(&context, data->value);
if (XmStringGetNextSegment(context, &fileName, &charSet, &dir, &sep)) {
fileNameStr = new GString(fileName);
if (viewer->openInNewWindow) {
viewer->app->open(fileNameStr);
} else {
if (viewer->loadFile(fileNameStr)) {
viewer->displayPage(1, viewer->core->getZoom(),
viewer->core->getRotate(), gTrue, gTrue);
}
}
delete fileNameStr;
XtFree(charSet);
XtFree(fileName);
}
XmStringFreeContext(context);
}
//------------------------------------------------------------------------
// GUI code: "find" dialog
//------------------------------------------------------------------------
void XPDFViewer::initFindDialog() {
Widget form1, label, okBtn, closeBtn;
Arg args[20];
int n;
XmString s;
//----- dialog
n = 0;
s = XmStringCreateLocalized(xpdfAppName ": Find");
XtSetArg(args[n], XmNdialogTitle, s); ++n;
XtSetArg(args[n], XmNnavigationType, XmNONE); ++n;
XtSetArg(args[n], XmNautoUnmanage, False); ++n;
findDialog = XmCreateFormDialog(win, "findDialog", args, n);
XmStringFree(s);
//----- "find" and "close" buttons
n = 0;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNleftOffset, 4); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNbottomOffset, 4); ++n;
XtSetArg(args[n], XmNnavigationType, XmEXCLUSIVE_TAB_GROUP); ++n;
okBtn = XmCreatePushButton(findDialog, "Find", args, n);
XtManageChild(okBtn);
XtAddCallback(okBtn, XmNactivateCallback,
&findFindCbk, (XtPointer)this);
n = 0;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNrightOffset, 4); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNbottomOffset, 4); ++n;
XtSetArg(args[n], XmNnavigationType, XmEXCLUSIVE_TAB_GROUP); ++n;
closeBtn = XmCreatePushButton(findDialog, "Close", args, n);
XtManageChild(closeBtn);
XtAddCallback(closeBtn, XmNactivateCallback,
&findCloseCbk, (XtPointer)this);
//----- checkboxes
n = 0;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNleftOffset, 4); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); ++n;
XtSetArg(args[n], XmNbottomWidget, okBtn); ++n;
XtSetArg(args[n], XmNindicatorType, XmN_OF_MANY); ++n;
#if XmVERSION <= 1
XtSetArg(args[n], XmNindicatorOn, True); ++n;
#else
XtSetArg(args[n], XmNindicatorOn, XmINDICATOR_FILL); ++n;
#endif
XtSetArg(args[n], XmNset, XmUNSET); ++n;
s = XmStringCreateLocalized("Search backward");
XtSetArg(args[n], XmNlabelString, s); ++n;
findBackwardToggle = XmCreateToggleButton(findDialog, "backward", args, n);
XmStringFree(s);
XtManageChild(findBackwardToggle);
n = 0;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
XtSetArg(args[n], XmNleftWidget, findBackwardToggle); ++n;
XtSetArg(args[n], XmNleftOffset, 16); ++n;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNrightOffset, 4); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); ++n;
XtSetArg(args[n], XmNbottomWidget, okBtn); ++n;
XtSetArg(args[n], XmNindicatorType, XmN_OF_MANY); ++n;
#if XmVERSION <= 1
XtSetArg(args[n], XmNindicatorOn, True); ++n;
#else
XtSetArg(args[n], XmNindicatorOn, XmINDICATOR_FILL); ++n;
#endif
XtSetArg(args[n], XmNset, XmUNSET); ++n;
s = XmStringCreateLocalized("Match case");
XtSetArg(args[n], XmNlabelString, s); ++n;
findCaseSensitiveToggle =
XmCreateToggleButton(findDialog, "matchCase", args, n);
XmStringFree(s);
XtManageChild(findCaseSensitiveToggle);
//----- search string entry
n = 0;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNtopOffset, 4); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); ++n;
XtSetArg(args[n], XmNbottomWidget, findBackwardToggle); ++n;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNleftOffset, 2); ++n;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNrightOffset, 2); ++n;
form1 = XmCreateForm(findDialog, "form", args, n);
XtManageChild(form1);
n = 0;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
s = XmStringCreateLocalized("Find text: ");
XtSetArg(args[n], XmNlabelString, s); ++n;
label = XmCreateLabel(form1, "label", args, n);
XmStringFree(s);
XtManageChild(label);
n = 0;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
XtSetArg(args[n], XmNleftWidget, label); ++n;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
findText = XmCreateTextField(form1, "text", args, n);
XtManageChild(findText);
#ifdef LESSTIF_VERSION
XtAddCallback(findText, XmNactivateCallback,
&findFindCbk, (XtPointer)this);
#endif
//----- dialog parameters
n = 0;
XtSetArg(args[n], XmNdefaultButton, okBtn); ++n;
XtSetArg(args[n], XmNcancelButton, closeBtn); ++n;
#if XmVersion > 1001
XtSetArg(args[n], XmNinitialFocus, findText); ++n;
#endif
XtSetValues(findDialog, args, n);
}
void XPDFViewer::findFindCbk(Widget widget, XtPointer ptr,
XtPointer callData) {
XPDFViewer *viewer = (XPDFViewer *)ptr;
viewer->doFind(gFalse);
}
void XPDFViewer::mapFindDialog() {
XmTextFieldSetSelection(findText, 0, XmTextFieldGetLastPosition(findText),
XtLastTimestampProcessed(display));
XmTextFieldSetInsertionPosition(findText, 0);
XtManageChild(findDialog);
}
void XPDFViewer::doFind(GBool next) {
if (XtWindow(findDialog)) {
XDefineCursor(display, XtWindow(findDialog), core->getBusyCursor());
}
core->find(XmTextFieldGetString(findText),
XmToggleButtonGetState(findCaseSensitiveToggle),
next,
XmToggleButtonGetState(findBackwardToggle),
gFalse);
if (XtWindow(findDialog)) {
XUndefineCursor(display, XtWindow(findDialog));
}
}
void XPDFViewer::findCloseCbk(Widget widget, XtPointer ptr,
XtPointer callData) {
XPDFViewer *viewer = (XPDFViewer *)ptr;
XtUnmanageChild(viewer->findDialog);
}
//------------------------------------------------------------------------
// GUI code: "save as" dialog
//------------------------------------------------------------------------
void XPDFViewer::initSaveAsDialog() {
Arg args[20];
int n;
XmString s1, s2, s3;
GString *dir;
n = 0;
s1 = XmStringCreateLocalized("Save");
XtSetArg(args[n], XmNokLabelString, s1); ++n;
s2 = XmStringCreateLocalized("*.[Pp][Dd][Ff]");
XtSetArg(args[n], XmNpattern, s2); ++n;
s3 = XmStringCreateLocalized(xpdfAppName ": Save as");
XtSetArg(args[n], XmNdialogTitle, s3); ++n;
XtSetArg(args[n], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); ++n;
XtSetArg(args[n], XmNautoUnmanage, True); ++n;
saveAsDialog = XmCreateFileSelectionDialog(win, "saveAsDialog", args, n);
XmStringFree(s1);
XmStringFree(s2);
XmStringFree(s3);
XtUnmanageChild(XmFileSelectionBoxGetChild(saveAsDialog,
XmDIALOG_HELP_BUTTON));
XtAddCallback(saveAsDialog, XmNokCallback,
&saveAsOkCbk, (XtPointer)this);
if (core->getDoc() && core->getDoc()->getFileName()) {
dir = makePathAbsolute(grabPath(
core->getDoc()->getFileName()->getCString()));
s1 = XmStringCreateLocalized(dir->getCString());
XtVaSetValues(saveAsDialog, XmNdirectory, s1, NULL);
XmStringFree(s1);
delete dir;
}
}
void XPDFViewer::mapSaveAsDialog() {
if (!saveAsDialog) {
initSaveAsDialog();
}
XmFileSelectionDoSearch(saveAsDialog, NULL);
XtManageChild(saveAsDialog);
}
void XPDFViewer::saveAsOkCbk(Widget widget, XtPointer ptr,
XtPointer callData) {
XPDFViewer *viewer = (XPDFViewer *)ptr;
XmFileSelectionBoxCallbackStruct *data =
(XmFileSelectionBoxCallbackStruct *)callData;
char *fileName;
GString *fileNameStr;
XmStringContext context;
XmStringCharSet charSet;
XmStringDirection dir;
Boolean sep;
XmStringInitContext(&context, data->value);
if (XmStringGetNextSegment(context, &fileName, &charSet, &dir, &sep)) {
fileNameStr = new GString(fileName);
viewer->core->getDoc()->saveAs(fileNameStr);
delete fileNameStr;
XtFree(charSet);
XtFree(fileName);
}
XmStringFreeContext(context);
}
//------------------------------------------------------------------------
// GUI code: "print" dialog
//------------------------------------------------------------------------
void XPDFViewer::initPrintDialog() {
Widget sep1, sep2, row, label1, label2, okBtn, cancelBtn;
Arg args[20];
int n;
XmString s;
GString *psFileName;
//----- dialog
n = 0;
s = XmStringCreateLocalized(xpdfAppName ": Print");
XtSetArg(args[n], XmNdialogTitle, s); ++n;
XtSetArg(args[n], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); ++n;
printDialog = XmCreateFormDialog(win, "printDialog", args, n);
XmStringFree(s);
//----- "print with command"
n = 0;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNtopOffset, 4); ++n;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); ++n;
XtSetArg(args[n], XmNset, XmSET); ++n;
s = XmStringCreateLocalized("Print with command:");
XtSetArg(args[n], XmNlabelString, s); ++n;
printWithCmdBtn = XmCreateToggleButton(printDialog, "printWithCmd", args, n);
XmStringFree(s);
XtManageChild(printWithCmdBtn);
XtAddCallback(printWithCmdBtn, XmNvalueChangedCallback,
&printWithCmdBtnCbk, (XtPointer)this);
n = 0;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
XtSetArg(args[n], XmNtopWidget, printWithCmdBtn); ++n;
XtSetArg(args[n], XmNtopOffset, 2); ++n;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNleftOffset, 16); ++n;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNrightOffset, 4); ++n;
XtSetArg(args[n], XmNcolumns, 40); ++n;
printCmdText = XmCreateTextField(printDialog, "printCmd", args, n);
XtManageChild(printCmdText);
//----- "print to file"
n = 0;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
XtSetArg(args[n], XmNtopWidget, printCmdText); ++n;
XtSetArg(args[n], XmNtopOffset, 4); ++n;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); ++n;
XtSetArg(args[n], XmNset, XmUNSET); ++n;
s = XmStringCreateLocalized("Print to file:");
XtSetArg(args[n], XmNlabelString, s); ++n;
printToFileBtn = XmCreateToggleButton(printDialog, "printToFile", args, n);
XmStringFree(s);
XtManageChild(printToFileBtn);
XtAddCallback(printToFileBtn, XmNvalueChangedCallback,
&printToFileBtnCbk, (XtPointer)this);
n = 0;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
XtSetArg(args[n], XmNtopWidget, printToFileBtn); ++n;
XtSetArg(args[n], XmNtopOffset, 2); ++n;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNleftOffset, 16); ++n;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNrightOffset, 4); ++n;
XtSetArg(args[n], XmNcolumns, 40); ++n;
XtSetArg(args[n], XmNsensitive, False); ++n;
printFileText = XmCreateTextField(printDialog, "printFile", args, n);
XtManageChild(printFileText);
//----- separator
n = 0;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
XtSetArg(args[n], XmNtopWidget, printFileText); ++n;
XtSetArg(args[n], XmNtopOffset, 8); ++n;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNleftOffset, 8); ++n;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNrightOffset, 8); ++n;
XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
sep1 = XmCreateSeparator(printDialog, "sep1", args, n);
XtManageChild(sep1);
//----- page range
n = 0;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
XtSetArg(args[n], XmNtopWidget, sep1); ++n;
XtSetArg(args[n], XmNtopOffset, 8); ++n;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNleftOffset, 4); ++n;
XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
XtSetArg(args[n], XmNpacking, XmPACK_TIGHT); ++n;
row = XmCreateRowColumn(printDialog, "row", args, n);
XtManageChild(row);
n = 0;
s = XmStringCreateLocalized("Pages:");
XtSetArg(args[n], XmNlabelString, s); ++n;
label1 = XmCreateLabel(row, "label1", args, n);
XmStringFree(s);
XtManageChild(label1);
n = 0;
XtSetArg(args[n], XmNcolumns, 5); ++n;
printFirstPage = XmCreateTextField(row, "printFirstPage", args, n);
XtManageChild(printFirstPage);
n = 0;
s = XmStringCreateLocalized("to");
XtSetArg(args[n], XmNlabelString, s); ++n;
label2 = XmCreateLabel(row, "label2", args, n);
XmStringFree(s);
XtManageChild(label2);
n = 0;
XtSetArg(args[n], XmNcolumns, 5); ++n;
printLastPage = XmCreateTextField(row, "printLastPage", args, n);
XtManageChild(printLastPage);
//----- separator
n = 0;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
XtSetArg(args[n], XmNtopWidget, row); ++n;
XtSetArg(args[n], XmNtopOffset, 8); ++n;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNleftOffset, 8); ++n;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNrightOffset, 8); ++n;
XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
sep2 = XmCreateSeparator(printDialog, "sep2", args, n);
XtManageChild(sep2);
//----- "print" and "cancel" buttons
n = 0;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
XtSetArg(args[n], XmNtopWidget, sep2); ++n;
XtSetArg(args[n], XmNtopOffset, 8); ++n;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNleftOffset, 4); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNbottomOffset, 4); ++n;
okBtn = XmCreatePushButton(printDialog, "Print", args, n);
XtManageChild(okBtn);
XtAddCallback(okBtn, XmNactivateCallback,
&printPrintCbk, (XtPointer)this);
n = 0;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
XtSetArg(args[n], XmNtopWidget, sep2); ++n;
XtSetArg(args[n], XmNtopOffset, 8); ++n;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNrightOffset, 4); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNbottomOffset, 4); ++n;
cancelBtn = XmCreatePushButton(printDialog, "Cancel", args, n);
XtManageChild(cancelBtn);
n = 0;
XtSetArg(args[n], XmNdefaultButton, okBtn); ++n;
XtSetArg(args[n], XmNcancelButton, cancelBtn); ++n;
XtSetValues(printDialog, args, n);
//----- initial values
if ((psFileName = globalParams->getPSFile())) {
if (psFileName->getChar(0) == '|') {
XmTextFieldSetString(printCmdText,
psFileName->getCString() + 1);
} else {
XmTextFieldSetString(printFileText, psFileName->getCString());
}
delete psFileName;
}
}
void XPDFViewer::setupPrintDialog() {
PDFDoc *doc;
char buf[20];
GString *pdfFileName, *psFileName, *psFileName2;
char *p;
doc = core->getDoc();
psFileName = globalParams->getPSFile();
if (!psFileName || psFileName->getChar(0) == '|') {
pdfFileName = doc->getFileName();
p = pdfFileName->getCString() + pdfFileName->getLength() - 4;
if (!strcmp(p, ".pdf") || !strcmp(p, ".PDF")) {
psFileName2 = new GString(pdfFileName->getCString(),
pdfFileName->getLength() - 4);
} else {
psFileName2 = pdfFileName->copy();
}
psFileName2->append(".ps");
XmTextFieldSetString(printFileText, psFileName2->getCString());
delete psFileName2;
}
if (psFileName && psFileName->getChar(0) == '|') {
XmToggleButtonSetState(printWithCmdBtn, True, False);
XmToggleButtonSetState(printToFileBtn, False, False);
XtVaSetValues(printCmdText, XmNsensitive, True, NULL);
XtVaSetValues(printFileText, XmNsensitive, False, NULL);
} else {
XmToggleButtonSetState(printWithCmdBtn, False, False);
XmToggleButtonSetState(printToFileBtn, True, False);
XtVaSetValues(printCmdText, XmNsensitive, False, NULL);
XtVaSetValues(printFileText, XmNsensitive, True, NULL);
}
if (psFileName) {
delete psFileName;
}
sprintf(buf, "%d", doc->getNumPages());
XmTextFieldSetString(printFirstPage, "1");
XmTextFieldSetString(printLastPage, buf);
}
void XPDFViewer::printWithCmdBtnCbk(Widget widget, XtPointer ptr,
XtPointer callData) {
XPDFViewer *viewer = (XPDFViewer *)ptr;
XmToggleButtonCallbackStruct *data =
(XmToggleButtonCallbackStruct *)callData;
if (data->set != XmSET) {
XmToggleButtonSetState(viewer->printWithCmdBtn, True, False);
}
XmToggleButtonSetState(viewer->printToFileBtn, False, False);
XtVaSetValues(viewer->printCmdText, XmNsensitive, True, NULL);
XtVaSetValues(viewer->printFileText, XmNsensitive, False, NULL);
}
void XPDFViewer::printToFileBtnCbk(Widget widget, XtPointer ptr,
XtPointer callData) {
XPDFViewer *viewer = (XPDFViewer *)ptr;
XmToggleButtonCallbackStruct *data =
(XmToggleButtonCallbackStruct *)callData;
if (data->set != XmSET) {
XmToggleButtonSetState(viewer->printToFileBtn, True, False);
}
XmToggleButtonSetState(viewer->printWithCmdBtn, False, False);
XtVaSetValues(viewer->printFileText, XmNsensitive, True, NULL);
XtVaSetValues(viewer->printCmdText, XmNsensitive, False, NULL);
}
void XPDFViewer::printPrintCbk(Widget widget, XtPointer ptr,
XtPointer callData) {
XPDFViewer *viewer = (XPDFViewer *)ptr;
unsigned char withCmd;
GString *psFileName;
int firstPage, lastPage;
PDFDoc *doc;
PSOutputDev *psOut;
doc = viewer->core->getDoc();
if (!doc->okToPrint()) {
error(-1, "Printing this document is not allowed.");
return;
}
viewer->core->setBusyCursor(gTrue);
XtVaGetValues(viewer->printWithCmdBtn, XmNset, &withCmd, NULL);
if (withCmd) {
psFileName = new GString(XmTextFieldGetString(viewer->printCmdText));
psFileName->insert(0, '|');
} else {
psFileName = new GString(XmTextFieldGetString(viewer->printFileText));
}
firstPage = atoi(XmTextFieldGetString(viewer->printFirstPage));
lastPage = atoi(XmTextFieldGetString(viewer->printLastPage));
if (firstPage < 1) {
firstPage = 1;
} else if (firstPage > doc->getNumPages()) {
firstPage = doc->getNumPages();
}
if (lastPage < firstPage) {
lastPage = firstPage;
} else if (lastPage > doc->getNumPages()) {
lastPage = doc->getNumPages();
}
psOut = new PSOutputDev(psFileName->getCString(), doc->getXRef(),
doc->getCatalog(), firstPage, lastPage,
psModePS);
if (psOut->isOk()) {
doc->displayPages(psOut, firstPage, lastPage, 72, 72,
0, gTrue, globalParams->getPSCrop(), gTrue);
}
delete psOut;
delete psFileName;
viewer->core->setBusyCursor(gFalse);
}
//------------------------------------------------------------------------
// Motif support
//------------------------------------------------------------------------
XmFontList XPDFViewer::createFontList(char *xlfd) {
XmFontList fontList;
#if XmVersion <= 1001
XFontStruct *font;
String params;
Cardinal nParams;
font = XLoadQueryFont(display, xlfd);
if (font) {
fontList = XmFontListCreate(font, XmSTRING_DEFAULT_CHARSET);
} else {
params = (String)xlfd;
nParams = 1;
XtAppWarningMsg(app->getAppContext(),
"noSuchFont", "CvtStringToXmFontList",
"XtToolkitError", "No such font: %s",
&params, &nParams);
fontList = NULL;
}
#else
XmFontListEntry entry;
entry = XmFontListEntryLoad(display, xlfd,
XmFONT_IS_FONT, XmFONTLIST_DEFAULT_TAG);
fontList = XmFontListAppendEntry(NULL, entry);
XmFontListEntryFree(&entry);
#endif
return fontList;
}