1 //========================================================================
2 //
3 // XPDFViewer.cc
4 //
5 // Copyright 2002-2003 Glyph & Cog, LLC
6 //
7 //========================================================================
8
9 #include <aconf.h>
10
11 #ifdef USE_GCC_PRAGMAS
12 #pragma implementation
13 #endif
14
15 #include <stdlib.h>
16 #include <string.h>
17 #include <ctype.h>
18 #include <X11/keysym.h>
19 #include <X11/cursorfont.h>
20 #ifdef HAVE_X11_XPM_H
21 #include <X11/xpm.h>
22 #endif
23 #if defined(__sgi) && (XmVERSION <= 1)
24 #define Object XtObject
25 #include <Sgm/HPanedW.h>
26 #undef Object
27 #endif
28 #include "gmem.h"
29 #include "gfile.h"
30 #include "GString.h"
31 #include "GList.h"
32 #include "Error.h"
33 #include "GlobalParams.h"
34 #include "PDFDoc.h"
35 #include "Link.h"
36 #include "ErrorCodes.h"
37 #include "Outline.h"
38 #include "UnicodeMap.h"
39 #ifndef DISABLE_OUTLINE
40 #define Object XtObject
41 #include "XPDFTree.h"
42 #undef Object
43 #endif
44 #include "XPDFApp.h"
45 #include "XPDFViewer.h"
46 #include "PSOutputDev.h"
47 #include "config.h"
48
49 // these macro defns conflict with xpdf's Object class
50 #ifdef LESSTIF_VERSION
51 #undef XtDisplay
52 #undef XtScreen
53 #undef XtWindow
54 #undef XtParent
55 #undef XtIsRealized
56 #endif
57
58 #if XmVERSION <= 1
59 #define XmSET True
60 #define XmUNSET False
61 #endif
62
63 // hack around old X includes which are missing these symbols
64 #ifndef XK_Page_Up
65 #define XK_Page_Up 0xFF55
66 #endif
67 #ifndef XK_Page_Down
68 #define XK_Page_Down 0xFF56
69 #endif
70 #ifndef XK_KP_Home
71 #define XK_KP_Home 0xFF95
72 #endif
73 #ifndef XK_KP_Left
74 #define XK_KP_Left 0xFF96
75 #endif
76 #ifndef XK_KP_Up
77 #define XK_KP_Up 0xFF97
78 #endif
79 #ifndef XK_KP_Right
80 #define XK_KP_Right 0xFF98
81 #endif
82 #ifndef XK_KP_Down
83 #define XK_KP_Down 0xFF99
84 #endif
85 #ifndef XK_KP_Prior
86 #define XK_KP_Prior 0xFF9A
87 #endif
88 #ifndef XK_KP_Page_Up
89 #define XK_KP_Page_Up 0xFF9A
90 #endif
91 #ifndef XK_KP_Next
92 #define XK_KP_Next 0xFF9B
93 #endif
94 #ifndef XK_KP_Page_Down
95 #define XK_KP_Page_Down 0xFF9B
96 #endif
97 #ifndef XK_KP_End
98 #define XK_KP_End 0xFF9C
99 #endif
100 #ifndef XK_KP_Begin
101 #define XK_KP_Begin 0xFF9D
102 #endif
103 #ifndef XK_KP_Insert
104 #define XK_KP_Insert 0xFF9E
105 #endif
106 #ifndef XK_KP_Delete
107 #define XK_KP_Delete 0xFF9F
108 #endif
109
110 //------------------------------------------------------------------------
111 // GUI includes
112 //------------------------------------------------------------------------
113
114 #include "xpdfIcon.xpm"
115 #include "leftArrow.xbm"
116 #include "leftArrowDis.xbm"
117 #include "dblLeftArrow.xbm"
118 #include "dblLeftArrowDis.xbm"
119 #include "rightArrow.xbm"
120 #include "rightArrowDis.xbm"
121 #include "dblRightArrow.xbm"
122 #include "dblRightArrowDis.xbm"
123 #include "backArrow.xbm"
124 #include "backArrowDis.xbm"
125 #include "forwardArrow.xbm"
126 #include "forwardArrowDis.xbm"
127 #include "find.xbm"
128 #include "findDis.xbm"
129 #include "print.xbm"
130 #include "printDis.xbm"
131 #include "about.xbm"
132 #include "about-text.h"
133
134 //------------------------------------------------------------------------
135
136 struct ZoomMenuInfo {
137 const char *label;
138 double zoom;
139 };
140
141 static ZoomMenuInfo zoomMenuInfo[nZoomMenuItems] = {
142 { "400%", 400 },
143 { "200%", 200 },
144 { "150%", 150 },
145 { "125%", 125 },
146 { "100%", 100 },
147 { "50%", 50 },
148 { "25%", 25 },
149 { "12.5%", 12.5 },
150 { "fit page", zoomPage },
151 { "fit width", zoomWidth }
152 };
153
154 #define maxZoomIdx 0
155 #define defZoomIdx 3
156 #define minZoomIdx 7
157 #define zoomPageIdx 8
158 #define zoomWidthIdx 9
159
160 //------------------------------------------------------------------------
161
162 #define cmdMaxArgs 8
163
164 XPDFViewerCmd XPDFViewer::cmdTab[] = {
165 { "about", 0, gFalse, gFalse, &XPDFViewer::cmdAbout },
166 { "closeOutline", 0, gFalse, gFalse, &XPDFViewer::cmdCloseOutline },
167 { "closeWindow", 0, gFalse, gFalse, &XPDFViewer::cmdCloseWindow },
168 { "closeWindowOrQuit", 0, gFalse, gFalse, &XPDFViewer::cmdCloseWindowOrQuit },
169 { "continuousMode", 0, gFalse, gFalse, &XPDFViewer::cmdContinuousMode },
170 { "endPan", 0, gTrue, gTrue, &XPDFViewer::cmdEndPan },
171 { "endSelection", 0, gTrue, gTrue, &XPDFViewer::cmdEndSelection },
172 { "find", 0, gTrue, gFalse, &XPDFViewer::cmdFind },
173 { "findNext", 0, gTrue, gFalse, &XPDFViewer::cmdFindNext },
174 { "focusToDocWin", 0, gFalse, gFalse, &XPDFViewer::cmdFocusToDocWin },
175 { "focusToPageNum", 0, gFalse, gFalse, &XPDFViewer::cmdFocusToPageNum },
176 { "followLink", 0, gTrue, gTrue, &XPDFViewer::cmdFollowLink },
177 { "followLinkInNewWin", 0, gTrue, gTrue, &XPDFViewer::cmdFollowLinkInNewWin },
178 { "followLinkInNewWinNoSel", 0, gTrue, gTrue, &XPDFViewer::cmdFollowLinkInNewWinNoSel },
179 { "followLinkNoSel", 0, gTrue, gTrue, &XPDFViewer::cmdFollowLinkNoSel },
180 { "fullScreenMode", 0, gFalse, gFalse, &XPDFViewer::cmdFullScreenMode },
181 { "goBackward", 0, gFalse, gFalse, &XPDFViewer::cmdGoBackward },
182 { "goForward", 0, gFalse, gFalse, &XPDFViewer::cmdGoForward },
183 { "gotoDest", 1, gTrue, gFalse, &XPDFViewer::cmdGotoDest },
184 { "gotoLastPage", 0, gTrue, gFalse, &XPDFViewer::cmdGotoLastPage },
185 { "gotoLastPageNoScroll", 0, gTrue, gFalse, &XPDFViewer::cmdGotoLastPageNoScroll },
186 { "gotoPage", 1, gTrue, gFalse, &XPDFViewer::cmdGotoPage },
187 { "gotoPageNoScroll", 1, gTrue, gFalse, &XPDFViewer::cmdGotoPageNoScroll },
188 { "nextPage", 0, gTrue, gFalse, &XPDFViewer::cmdNextPage },
189 { "nextPageNoScroll", 0, gTrue, gFalse, &XPDFViewer::cmdNextPageNoScroll },
190 { "open", 0, gFalse, gFalse, &XPDFViewer::cmdOpen },
191 { "openFile", 1, gFalse, gFalse, &XPDFViewer::cmdOpenFile },
192 { "openFileAtDest", 2, gFalse, gFalse, &XPDFViewer::cmdOpenFileAtDest },
193 { "openFileAtDestInNewWin", 2, gFalse, gFalse, &XPDFViewer::cmdOpenFileAtDestInNewWin },
194 { "openFileAtPage", 2, gFalse, gFalse, &XPDFViewer::cmdOpenFileAtPage },
195 { "openFileAtPageInNewWin", 2, gFalse, gFalse, &XPDFViewer::cmdOpenFileAtPageInNewWin },
196 { "openFileInNewWin", 1, gFalse, gFalse, &XPDFViewer::cmdOpenFileInNewWin },
197 { "openInNewWin", 0, gFalse, gFalse, &XPDFViewer::cmdOpenInNewWin },
198 { "openOutline", 0, gFalse, gFalse, &XPDFViewer::cmdOpenOutline },
199 { "pageDown", 0, gTrue, gFalse, &XPDFViewer::cmdPageDown },
200 { "pageUp", 0, gTrue, gFalse, &XPDFViewer::cmdPageUp },
201 { "postPopupMenu", 0, gFalse, gTrue, &XPDFViewer::cmdPostPopupMenu },
202 { "prevPage", 0, gTrue, gFalse, &XPDFViewer::cmdPrevPage },
203 { "prevPageNoScroll", 0, gTrue, gFalse, &XPDFViewer::cmdPrevPageNoScroll },
204 { "print", 0, gTrue, gFalse, &XPDFViewer::cmdPrint },
205 { "quit", 0, gFalse, gFalse, &XPDFViewer::cmdQuit },
206 { "raise", 0, gFalse, gFalse, &XPDFViewer::cmdRaise },
207 { "redraw", 0, gTrue, gFalse, &XPDFViewer::cmdRedraw },
208 { "reload", 0, gTrue, gFalse, &XPDFViewer::cmdReload },
209 { "rotateCCW", 0, gTrue, gFalse, &XPDFViewer::cmdRotateCCW },
210 { "rotateCW", 0, gTrue, gFalse, &XPDFViewer::cmdRotateCW },
211 { "run", 1, gFalse, gFalse, &XPDFViewer::cmdRun },
212 { "scrollDown", 1, gTrue, gFalse, &XPDFViewer::cmdScrollDown },
213 { "scrollDownNextPage", 1, gTrue, gFalse, &XPDFViewer::cmdScrollDownNextPage },
214 { "scrollLeft", 1, gTrue, gFalse, &XPDFViewer::cmdScrollLeft },
215 { "scrollOutlineDown", 1, gTrue, gFalse, &XPDFViewer::cmdScrollOutlineDown },
216 { "scrollOutlineUp", 1, gTrue, gFalse, &XPDFViewer::cmdScrollOutlineUp },
217 { "scrollRight", 1, gTrue, gFalse, &XPDFViewer::cmdScrollRight },
218 { "scrollToBottomEdge", 0, gTrue, gFalse, &XPDFViewer::cmdScrollToBottomEdge },
219 { "scrollToBottomRight", 0, gTrue, gFalse, &XPDFViewer::cmdScrollToBottomRight },
220 { "scrollToLeftEdge", 0, gTrue, gFalse, &XPDFViewer::cmdScrollToLeftEdge },
221 { "scrollToRightEdge", 0, gTrue, gFalse, &XPDFViewer::cmdScrollToRightEdge },
222 { "scrollToTopEdge", 0, gTrue, gFalse, &XPDFViewer::cmdScrollToTopEdge },
223 { "scrollToTopLeft", 0, gTrue, gFalse, &XPDFViewer::cmdScrollToTopLeft },
224 { "scrollUp", 1, gTrue, gFalse, &XPDFViewer::cmdScrollUp },
225 { "scrollUpPrevPage", 1, gTrue, gFalse, &XPDFViewer::cmdScrollUpPrevPage },
226 { "setSelection", 5, gTrue, gFalse, &XPDFViewer::cmdSetSelection },
227 { "singlePageMode", 0, gFalse, gFalse, &XPDFViewer::cmdSinglePageMode },
228 { "startPan", 0, gTrue, gTrue, &XPDFViewer::cmdStartPan },
229 { "startSelection", 0, gTrue, gTrue, &XPDFViewer::cmdStartSelection },
230 { "toggleContinuousMode", 0, gFalse, gFalse, &XPDFViewer::cmdToggleContinuousMode },
231 { "toggleFullScreenMode", 0, gFalse, gFalse, &XPDFViewer::cmdToggleFullScreenMode },
232 { "toggleOutline", 0, gFalse, gFalse, &XPDFViewer::cmdToggleOutline },
233 { "windowMode", 0, gFalse, gFalse, &XPDFViewer::cmdWindowMode },
234 { "zoomFitPage", 0, gFalse, gFalse, &XPDFViewer::cmdZoomFitPage },
235 { "zoomFitWidth", 0, gFalse, gFalse, &XPDFViewer::cmdZoomFitWidth },
236 { "zoomIn", 0, gFalse, gFalse, &XPDFViewer::cmdZoomIn },
237 { "zoomOut", 0, gFalse, gFalse, &XPDFViewer::cmdZoomOut },
238 { "zoomPercent", 1, gFalse, gFalse, &XPDFViewer::cmdZoomPercent },
239 { "zoomToSelection", 0, gTrue, gFalse, &XPDFViewer::cmdZoomToSelection }
240 };
241
242 #define nCmds (sizeof(cmdTab) / sizeof(XPDFViewerCmd))
243
244 //------------------------------------------------------------------------
245
XPDFViewer(XPDFApp * appA,GString * fileName,int pageA,GString * destName,GBool fullScreen,GString * ownerPassword,GString * userPassword)246 XPDFViewer::XPDFViewer(XPDFApp *appA, GString *fileName,
247 int pageA, GString *destName, GBool fullScreen,
248 GString *ownerPassword, GString *userPassword) {
249 LinkDest *dest;
250 int pg;
251 double z;
252
253 app = appA;
254 win = NULL;
255 core = NULL;
256 ok = gFalse;
257 #ifndef DISABLE_OUTLINE
258 outlineLabels = NULL;
259 outlineLabelsLength = outlineLabelsSize = 0;
260 outlinePaneWidth = 175;
261 #endif
262
263 // do Motif-specific initialization and create the window;
264 // this also creates the core object
265 initWindow(fullScreen);
266 initAboutDialog();
267 initFindDialog();
268 initPrintDialog();
269 openDialog = NULL;
270 saveAsDialog = NULL;
271
272 dest = NULL; // make gcc happy
273 pg = pageA; // make gcc happy
274
275 if (fileName) {
276 if (loadFile(fileName, ownerPassword, userPassword)) {
277 getPageAndDest(pageA, destName, &pg, &dest);
278 #ifndef DISABLE_OUTLINE
279 if (outlineScroll != None &&
280 core->getDoc()->getOutline()->getItems() &&
281 core->getDoc()->getOutline()->getItems()->getLength() > 0) {
282 XtVaSetValues(outlineScroll, XmNwidth, outlinePaneWidth, NULL);
283 }
284 #endif
285 } else {
286 return;
287 }
288 }
289 core->resizeToPage(pg);
290
291 // map the window -- we do this after calling resizeToPage to avoid
292 // an annoying on-screen resize
293 mapWindow();
294
295 // display the first page
296 z = core->getZoom();
297 if (dest) {
298 displayDest(dest, z, core->getRotate(), gTrue);
299 delete dest;
300 } else {
301 displayPage(pg, z, core->getRotate(), gTrue, gTrue);
302 }
303
304 ok = gTrue;
305 }
306
XPDFViewer(XPDFApp * appA,PDFDoc * doc,int pageA,GString * destName,GBool fullScreen)307 XPDFViewer::XPDFViewer(XPDFApp *appA, PDFDoc *doc, int pageA,
308 GString *destName, GBool fullScreen) {
309 LinkDest *dest;
310 int pg;
311 double z;
312
313 app = appA;
314 win = NULL;
315 core = NULL;
316 ok = gFalse;
317 #ifndef DISABLE_OUTLINE
318 outlineLabels = NULL;
319 outlineLabelsLength = outlineLabelsSize = 0;
320 outlinePaneWidth = 175;
321 #endif
322
323 // do Motif-specific initialization and create the window;
324 // this also creates the core object
325 initWindow(fullScreen);
326 initAboutDialog();
327 initFindDialog();
328 initPrintDialog();
329 openDialog = NULL;
330 saveAsDialog = NULL;
331
332 dest = NULL; // make gcc happy
333 pg = pageA; // make gcc happy
334
335 if (doc) {
336 core->loadDoc(doc);
337 getPageAndDest(pageA, destName, &pg, &dest);
338 #ifndef DISABLE_OUTLINE
339 if (outlineScroll != None &&
340 core->getDoc()->getOutline()->getItems() &&
341 core->getDoc()->getOutline()->getItems()->getLength() > 0) {
342 XtVaSetValues(outlineScroll, XmNwidth, outlinePaneWidth, NULL);
343 }
344 #endif
345 }
346 core->resizeToPage(pg);
347
348 // map the window -- we do this after calling resizeToPage to avoid
349 // an annoying on-screen resize
350 mapWindow();
351
352 // display the first page
353 z = core->getZoom();
354 if (dest) {
355 displayDest(dest, z, core->getRotate(), gTrue);
356 delete dest;
357 } else {
358 displayPage(pg, z, core->getRotate(), gTrue, gTrue);
359 }
360
361 ok = gTrue;
362 }
363
~XPDFViewer()364 XPDFViewer::~XPDFViewer() {
365 delete core;
366 if (aboutBigFont) {
367 XmFontListFree(aboutBigFont);
368 }
369 if (aboutVersionFont) {
370 XmFontListFree(aboutVersionFont);
371 }
372 if (aboutFixedFont) {
373 XmFontListFree(aboutFixedFont);
374 }
375 closeWindow();
376 #ifndef DISABLE_OUTLINE
377 if (outlineLabels) {
378 gfree(outlineLabels);
379 }
380 #endif
381 }
382
open(GString * fileName,int pageA,GString * destName)383 void XPDFViewer::open(GString *fileName, int pageA, GString *destName) {
384 LinkDest *dest;
385 int pg;
386 double z;
387
388 if (!core->getDoc() ||
389 !core->getDoc()->getFileName() ||
390 fileName->cmp(core->getDoc()->getFileName())) {
391 if (!loadFile(fileName, NULL, NULL)) {
392 return;
393 }
394 }
395 getPageAndDest(pageA, destName, &pg, &dest);
396 z = core->getZoom();
397 if (dest) {
398 displayDest(dest, z, core->getRotate(), gTrue);
399 delete dest;
400 } else {
401 displayPage(pg, z, core->getRotate(), gTrue, gTrue);
402 }
403 }
404
clear()405 void XPDFViewer::clear() {
406 char *title;
407 XmString s;
408
409 core->clear();
410
411 // set up title
412 title = app->getTitle() ? app->getTitle()->getCString()
413 : (char *)xpdfAppName;
414 XtVaSetValues(win, XmNtitle, title, XmNiconName, title, NULL);
415
416 if (toolBar != None) {
417
418 // set up number-of-pages display
419 s = XmStringCreateLocalized("");
420 XtVaSetValues(pageNumText, XmNlabelString, s, NULL);
421 XmStringFree(s);
422 s = XmStringCreateLocalized(" of 0");
423 XtVaSetValues(pageCountLabel, XmNlabelString, s, NULL);
424 XmStringFree(s);
425
426 // disable buttons
427 XtVaSetValues(prevTenPageBtn, XmNsensitive, False, NULL);
428 XtVaSetValues(prevPageBtn, XmNsensitive, False, NULL);
429 XtVaSetValues(nextTenPageBtn, XmNsensitive, False, NULL);
430 XtVaSetValues(nextPageBtn, XmNsensitive, False, NULL);
431 }
432
433 // remove the old outline
434 #ifndef DISABLE_OUTLINE
435 setupOutline();
436 #endif
437 }
438
439 //------------------------------------------------------------------------
440 // load / display
441 //------------------------------------------------------------------------
442
loadFile(GString * fileName,GString * ownerPassword,GString * userPassword)443 GBool XPDFViewer::loadFile(GString *fileName, GString *ownerPassword,
444 GString *userPassword) {
445 return core->loadFile(fileName, ownerPassword, userPassword) == errNone;
446 }
447
reloadFile()448 void XPDFViewer::reloadFile() {
449 int pg;
450
451 if (!core->getDoc() || !core->getDoc()->getFileName()) {
452 return;
453 }
454 pg = core->getPageNum();
455 loadFile(core->getDoc()->getFileName());
456 if (pg > core->getDoc()->getNumPages()) {
457 pg = core->getDoc()->getNumPages();
458 }
459 displayPage(pg, core->getZoom(), core->getRotate(), gFalse, gFalse);
460 }
461
displayPage(int pageA,double zoomA,int rotateA,GBool scrollToTop,GBool addToHist)462 void XPDFViewer::displayPage(int pageA, double zoomA, int rotateA,
463 GBool scrollToTop, GBool addToHist) {
464 core->displayPage(pageA, zoomA, rotateA, scrollToTop, addToHist);
465 }
466
displayDest(LinkDest * dest,double zoomA,int rotateA,GBool addToHist)467 void XPDFViewer::displayDest(LinkDest *dest, double zoomA, int rotateA,
468 GBool addToHist) {
469 core->displayDest(dest, zoomA, rotateA, addToHist);
470 }
471
getPageAndDest(int pageA,GString * destName,int * pageOut,LinkDest ** destOut)472 void XPDFViewer::getPageAndDest(int pageA, GString *destName,
473 int *pageOut, LinkDest **destOut) {
474 Ref pageRef;
475
476 // find the page number for a named destination
477 *pageOut = pageA;
478 *destOut = NULL;
479 if (destName && (*destOut = core->getDoc()->findDest(destName))) {
480 if ((*destOut)->isPageRef()) {
481 pageRef = (*destOut)->getPageRef();
482 *pageOut = core->getDoc()->findPage(pageRef.num, pageRef.gen);
483 } else {
484 *pageOut = (*destOut)->getPageNum();
485 }
486 }
487
488 if (*pageOut <= 0) {
489 *pageOut = 1;
490 }
491 if (*pageOut > core->getDoc()->getNumPages()) {
492 *pageOut = core->getDoc()->getNumPages();
493 }
494 }
495
496 //------------------------------------------------------------------------
497 // hyperlinks / actions
498 //------------------------------------------------------------------------
499
doLink(int wx,int wy,GBool onlyIfNoSelection,GBool newWin)500 void XPDFViewer::doLink(int wx, int wy, GBool onlyIfNoSelection,
501 GBool newWin) {
502 XPDFViewer *newViewer;
503 LinkAction *action;
504 int pg, selPg;
505 double xu, yu, selULX, selULY, selLRX, selLRY;
506
507 if (core->getHyperlinksEnabled() &&
508 core->cvtWindowToUser(wx, wy, &pg, &xu, &yu) &&
509 !(onlyIfNoSelection &&
510 core->getSelection(&selPg, &selULX, &selULY, &selLRX, &selLRY))) {
511 if ((action = core->findLink(pg, xu, yu))) {
512 if (newWin &&
513 core->getDoc()->getFileName() &&
514 (action->getKind() == actionGoTo ||
515 action->getKind() == actionGoToR ||
516 (action->getKind() == actionNamed &&
517 ((LinkNamed *)action)->getName()->cmp("Quit")))) {
518 newViewer = app->open(core->getDoc()->getFileName());
519 newViewer->core->doAction(action);
520 } else {
521 core->doAction(action);
522 }
523 }
524 }
525 }
526
actionCbk(void * data,char * action)527 void XPDFViewer::actionCbk(void *data, char *action) {
528 XPDFViewer *viewer = (XPDFViewer *)data;
529
530 if (!strcmp(action, "Quit")) {
531 viewer->app->quit();
532 }
533 }
534
535 //------------------------------------------------------------------------
536 // keyboard/mouse input
537 //------------------------------------------------------------------------
538
keyPressCbk(void * data,KeySym key,Guint modifiers,XEvent * event)539 void XPDFViewer::keyPressCbk(void *data, KeySym key, Guint modifiers,
540 XEvent *event) {
541 XPDFViewer *viewer = (XPDFViewer *)data;
542 int keyCode;
543 GList *cmds;
544 int i;
545
546 if (key >= 0x20 && key <= 0xfe) {
547 keyCode = (int)key;
548 } else if (key == XK_Tab ||
549 key == XK_KP_Tab) {
550 keyCode = xpdfKeyCodeTab;
551 } else if (key == XK_Return) {
552 keyCode = xpdfKeyCodeReturn;
553 } else if (key == XK_KP_Enter) {
554 keyCode = xpdfKeyCodeEnter;
555 } else if (key == XK_BackSpace) {
556 keyCode = xpdfKeyCodeBackspace;
557 } else if (key == XK_Insert ||
558 key == XK_KP_Insert) {
559 keyCode = xpdfKeyCodeInsert;
560 } else if (key == XK_Delete ||
561 key == XK_KP_Delete) {
562 keyCode = xpdfKeyCodeDelete;
563 } else if (key == XK_Home ||
564 key == XK_KP_Home) {
565 keyCode = xpdfKeyCodeHome;
566 } else if (key == XK_End ||
567 key == XK_KP_End) {
568 keyCode = xpdfKeyCodeEnd;
569 } else if (key == XK_Page_Up ||
570 key == XK_KP_Page_Up) {
571 keyCode = xpdfKeyCodePgUp;
572 } else if (key == XK_Page_Down ||
573 key == XK_KP_Page_Down) {
574 keyCode = xpdfKeyCodePgDn;
575 } else if (key == XK_Left ||
576 key == XK_KP_Left) {
577 keyCode = xpdfKeyCodeLeft;
578 } else if (key == XK_Right ||
579 key == XK_KP_Right) {
580 keyCode = xpdfKeyCodeRight;
581 } else if (key == XK_Up ||
582 key == XK_KP_Up) {
583 keyCode = xpdfKeyCodeUp;
584 } else if (key == XK_Down ||
585 key == XK_KP_Down) {
586 keyCode = xpdfKeyCodeDown;
587 } else if (key >= XK_F1 && key <= XK_F35) {
588 keyCode = xpdfKeyCodeF1 + (key - XK_F1);
589 } else {
590 return;
591 }
592
593 if ((cmds = globalParams->getKeyBinding(keyCode,
594 viewer->getModifiers(modifiers),
595 viewer->getContext(modifiers)))) {
596 for (i = 0; i < cmds->getLength(); ++i) {
597 viewer->execCmd((GString *)cmds->get(i), event);
598 }
599 deleteGList(cmds, GString);
600 }
601 }
602
mouseCbk(void * data,XEvent * event)603 void XPDFViewer::mouseCbk(void *data, XEvent *event) {
604 XPDFViewer *viewer = (XPDFViewer *)data;
605 int keyCode;
606 GList *cmds;
607 int i;
608
609 if (event->type == ButtonPress) {
610 if (event->xbutton.button >= 1 && event->xbutton.button <= 32) {
611 keyCode = xpdfKeyCodeMousePress1 + event->xbutton.button - 1;
612 } else {
613 return;
614 }
615 } else if (event->type == ButtonRelease) {
616 if (event->xbutton.button >= 1 && event->xbutton.button <= 32) {
617 keyCode = xpdfKeyCodeMouseRelease1 + event->xbutton.button - 1;
618 } else {
619 return;
620 }
621 } else {
622 return;
623 }
624
625 if ((cmds = globalParams->getKeyBinding(keyCode,
626 viewer->getModifiers(
627 event->xkey.state),
628 viewer->getContext(
629 event->xkey.state)))) {
630 for (i = 0; i < cmds->getLength(); ++i) {
631 viewer->execCmd((GString *)cmds->get(i), event);
632 }
633 deleteGList(cmds, GString);
634 }
635 }
636
getModifiers(Guint modifiers)637 int XPDFViewer::getModifiers(Guint modifiers) {
638 int mods;
639
640 mods = 0;
641 if (modifiers & ShiftMask) {
642 mods |= xpdfKeyModShift;
643 }
644 if (modifiers & ControlMask) {
645 mods |= xpdfKeyModCtrl;
646 }
647 if (modifiers & Mod1Mask) {
648 mods |= xpdfKeyModAlt;
649 }
650 return mods;
651 }
652
getContext(Guint modifiers)653 int XPDFViewer::getContext(Guint modifiers) {
654 int context;
655
656 context = (core->getFullScreen() ? xpdfKeyContextFullScreen
657 : xpdfKeyContextWindow) |
658 (core->getContinuousMode() ? xpdfKeyContextContinuous
659 : xpdfKeyContextSinglePage) |
660 (core->getLinkAction() ? xpdfKeyContextOverLink
661 : xpdfKeyContextOffLink) |
662 ((modifiers & Mod5Mask) ? xpdfKeyContextScrLockOn
663 : xpdfKeyContextScrLockOff);
664 return context;
665 }
666
execCmd(GString * cmd,XEvent * event)667 void XPDFViewer::execCmd(GString *cmd, XEvent *event) {
668 GString *name;
669 GString *args[cmdMaxArgs];
670 char *p0, *p1;
671 int nArgs, i;
672 int a, b, m, cmp;
673
674 //----- parse the command
675 name = NULL;
676 nArgs = 0;
677 for (i = 0; i < cmdMaxArgs; ++i) {
678 args[i] = NULL;
679 }
680 p0 = cmd->getCString();
681 for (p1 = p0; *p1 && isalnum(*p1); ++p1) ;
682 if (p1 == p0) {
683 goto err1;
684 }
685 name = new GString(p0, p1 - p0);
686 if (*p1 == '(') {
687 while (nArgs < cmdMaxArgs) {
688 p0 = p1 + 1;
689 for (p1 = p0; *p1 && *p1 != ',' && *p1 != ')'; ++p1) ;
690 args[nArgs++] = new GString(p0, p1 - p0);
691 if (*p1 != ',') {
692 break;
693 }
694 }
695 if (*p1 != ')') {
696 goto err1;
697 }
698 ++p1;
699 }
700 if (*p1) {
701 goto err1;
702 }
703
704 //----- find the command
705 a = -1;
706 b = nCmds;
707 // invariant: cmdTab[a].name < name < cmdTab[b].name
708 while (b - a > 1) {
709 m = (a + b) / 2;
710 cmp = strcmp(cmdTab[m].name, name->getCString());
711 if (cmp < 0) {
712 a = m;
713 } else if (cmp > 0) {
714 b = m;
715 } else {
716 a = b = m;
717 }
718 }
719 if (cmp != 0) {
720 goto err1;
721 }
722
723 //----- execute the command
724 if (nArgs != cmdTab[a].nArgs ||
725 (cmdTab[a].requiresEvent && !event)) {
726 goto err1;
727 }
728 if (cmdTab[a].requiresDoc && !core->getDoc()) {
729 // don't issue an error message for this -- it happens, e.g., when
730 // clicking in a window with no open PDF file
731 goto err2;
732 }
733 (this->*cmdTab[a].func)(args, nArgs, event);
734
735 //----- clean up
736 delete name;
737 for (i = 0; i < nArgs; ++i) {
738 if (args[i]) {
739 delete args[i];
740 }
741 }
742 return;
743
744 err1:
745 error(errConfig, -1, "Invalid command syntax: '{0:t}'", cmd);
746 err2:
747 if (name) {
748 delete name;
749 }
750 for (i = 0; i < nArgs; ++i) {
751 if (args[i]) {
752 delete args[i];
753 }
754 }
755 }
756
757 //------------------------------------------------------------------------
758 // command functions
759 //------------------------------------------------------------------------
760
mouseX(XEvent * event)761 static int mouseX(XEvent *event) {
762 switch (event->type) {
763 case ButtonPress:
764 case ButtonRelease:
765 return event->xbutton.x;
766 case KeyPress:
767 return event->xkey.x;
768 }
769 return 0;
770 }
771
mouseY(XEvent * event)772 static int mouseY(XEvent *event) {
773 switch (event->type) {
774 case ButtonPress:
775 case ButtonRelease:
776 return event->xbutton.y;
777 case KeyPress:
778 return event->xkey.y;
779 }
780 return 0;
781 }
782
cmdAbout(GString * args[],int nArgs,XEvent * event)783 void XPDFViewer::cmdAbout(GString *args[], int nArgs,
784 XEvent *event) {
785 XtManageChild(aboutDialog);
786 }
787
cmdCloseOutline(GString * args[],int nArgs,XEvent * event)788 void XPDFViewer::cmdCloseOutline(GString *args[], int nArgs,
789 XEvent *event) {
790 #ifndef DISABLE_OUTLINE
791 Dimension w;
792
793 if (outlineScroll == None) {
794 return;
795 }
796 XtVaGetValues(outlineScroll, XmNwidth, &w, NULL);
797 if (w > 1) {
798 outlinePaneWidth = w;
799 // this ugly kludge is apparently the only way to resize the panes
800 // within an XmPanedWindow
801 XtVaSetValues(outlineScroll, XmNpaneMinimum, 1,
802 XmNpaneMaximum, 1, NULL);
803 XtVaSetValues(outlineScroll, XmNpaneMinimum, 1,
804 XmNpaneMaximum, 10000, NULL);
805 }
806 #endif
807 }
808
cmdCloseWindow(GString * args[],int nArgs,XEvent * event)809 void XPDFViewer::cmdCloseWindow(GString *args[], int nArgs,
810 XEvent *event) {
811 app->close(this, gFalse);
812 }
813
cmdCloseWindowOrQuit(GString * args[],int nArgs,XEvent * event)814 void XPDFViewer::cmdCloseWindowOrQuit(GString *args[], int nArgs,
815 XEvent *event) {
816 app->close(this, gTrue);
817 }
818
cmdContinuousMode(GString * args[],int nArgs,XEvent * event)819 void XPDFViewer::cmdContinuousMode(GString *args[], int nArgs,
820 XEvent *event) {
821 Widget btn;
822
823 if (core->getContinuousMode()) {
824 return;
825 }
826 core->setContinuousMode(gTrue);
827
828 btn = XtNameToWidget(popupMenu, "continuousMode");
829 XtVaSetValues(btn, XmNset, XmSET, NULL);
830 }
831
cmdEndPan(GString * args[],int nArgs,XEvent * event)832 void XPDFViewer::cmdEndPan(GString *args[], int nArgs,
833 XEvent *event) {
834 core->endPan(mouseX(event), mouseY(event));
835 }
836
cmdEndSelection(GString * args[],int nArgs,XEvent * event)837 void XPDFViewer::cmdEndSelection(GString *args[], int nArgs,
838 XEvent *event) {
839 core->endSelection(mouseX(event), mouseY(event));
840 }
841
cmdFind(GString * args[],int nArgs,XEvent * event)842 void XPDFViewer::cmdFind(GString *args[], int nArgs,
843 XEvent *event) {
844 mapFindDialog();
845 }
846
cmdFindNext(GString * args[],int nArgs,XEvent * event)847 void XPDFViewer::cmdFindNext(GString *args[], int nArgs,
848 XEvent *event) {
849 doFind(gTrue);
850 }
851
cmdFocusToDocWin(GString * args[],int nArgs,XEvent * event)852 void XPDFViewer::cmdFocusToDocWin(GString *args[], int nArgs,
853 XEvent *event) {
854 core->takeFocus();
855 }
856
cmdFocusToPageNum(GString * args[],int nArgs,XEvent * event)857 void XPDFViewer::cmdFocusToPageNum(GString *args[], int nArgs,
858 XEvent *event) {
859 if (toolBar != None) {
860 XmTextFieldSetSelection(pageNumText, 0,
861 strlen(XmTextFieldGetString(pageNumText)),
862 XtLastTimestampProcessed(display));
863 XmProcessTraversal(pageNumText, XmTRAVERSE_CURRENT);
864 }
865 }
866
cmdFollowLink(GString * args[],int nArgs,XEvent * event)867 void XPDFViewer::cmdFollowLink(GString *args[], int nArgs,
868 XEvent *event) {
869 doLink(mouseX(event), mouseY(event), gFalse, gFalse);
870 }
871
cmdFollowLinkInNewWin(GString * args[],int nArgs,XEvent * event)872 void XPDFViewer::cmdFollowLinkInNewWin(GString *args[], int nArgs,
873 XEvent *event) {
874 doLink(mouseX(event), mouseY(event), gFalse, gTrue);
875 }
876
cmdFollowLinkInNewWinNoSel(GString * args[],int nArgs,XEvent * event)877 void XPDFViewer::cmdFollowLinkInNewWinNoSel(GString *args[], int nArgs,
878 XEvent *event) {
879 doLink(mouseX(event), mouseY(event), gTrue, gTrue);
880 }
881
cmdFollowLinkNoSel(GString * args[],int nArgs,XEvent * event)882 void XPDFViewer::cmdFollowLinkNoSel(GString *args[], int nArgs,
883 XEvent *event) {
884 doLink(mouseX(event), mouseY(event), gTrue, gFalse);
885 }
886
cmdFullScreenMode(GString * args[],int nArgs,XEvent * event)887 void XPDFViewer::cmdFullScreenMode(GString *args[], int nArgs,
888 XEvent *event) {
889 PDFDoc *doc;
890 XPDFViewer *viewer;
891 int pg;
892 Widget btn;
893
894 if (core->getFullScreen()) {
895 return;
896 }
897 pg = core->getPageNum();
898 XtPopdown(win);
899 doc = core->takeDoc(gFalse);
900 viewer = app->reopen(this, doc, pg, gTrue);
901
902 btn = XtNameToWidget(viewer->popupMenu, "fullScreen");
903 XtVaSetValues(btn, XmNset, XmSET, NULL);
904 }
905
cmdGoBackward(GString * args[],int nArgs,XEvent * event)906 void XPDFViewer::cmdGoBackward(GString *args[], int nArgs,
907 XEvent *event) {
908 core->goBackward();
909 }
910
cmdGoForward(GString * args[],int nArgs,XEvent * event)911 void XPDFViewer::cmdGoForward(GString *args[], int nArgs,
912 XEvent *event) {
913 core->goForward();
914 }
915
cmdGotoDest(GString * args[],int nArgs,XEvent * event)916 void XPDFViewer::cmdGotoDest(GString *args[], int nArgs,
917 XEvent *event) {
918 int pg;
919 LinkDest *dest;
920
921 getPageAndDest(1, args[0], &pg, &dest);
922 if (dest) {
923 displayDest(dest, core->getZoom(), core->getRotate(), gTrue);
924 delete dest;
925 }
926 }
927
cmdGotoLastPage(GString * args[],int nArgs,XEvent * event)928 void XPDFViewer::cmdGotoLastPage(GString *args[], int nArgs,
929 XEvent *event) {
930 displayPage(core->getDoc()->getNumPages(),
931 core->getZoom(), core->getRotate(),
932 gTrue, gTrue);
933 }
934
cmdGotoLastPageNoScroll(GString * args[],int nArgs,XEvent * event)935 void XPDFViewer::cmdGotoLastPageNoScroll(GString *args[], int nArgs,
936 XEvent *event) {
937 displayPage(core->getDoc()->getNumPages(),
938 core->getZoom(), core->getRotate(),
939 gFalse, gTrue);
940 }
941
cmdGotoPage(GString * args[],int nArgs,XEvent * event)942 void XPDFViewer::cmdGotoPage(GString *args[], int nArgs,
943 XEvent *event) {
944 int pg;
945
946 pg = atoi(args[0]->getCString());
947 if (pg < 1 || pg > core->getDoc()->getNumPages()) {
948 return;
949 }
950 displayPage(pg, core->getZoom(), core->getRotate(), gTrue, gTrue);
951 }
952
cmdGotoPageNoScroll(GString * args[],int nArgs,XEvent * event)953 void XPDFViewer::cmdGotoPageNoScroll(GString *args[], int nArgs,
954 XEvent *event) {
955 int pg;
956
957 pg = atoi(args[0]->getCString());
958 if (pg < 1 || pg > core->getDoc()->getNumPages()) {
959 return;
960 }
961 displayPage(pg, core->getZoom(), core->getRotate(), gFalse, gTrue);
962 }
963
cmdNextPage(GString * args[],int nArgs,XEvent * event)964 void XPDFViewer::cmdNextPage(GString *args[], int nArgs,
965 XEvent *event) {
966 core->gotoNextPage(1, gTrue);
967 }
968
cmdNextPageNoScroll(GString * args[],int nArgs,XEvent * event)969 void XPDFViewer::cmdNextPageNoScroll(GString *args[], int nArgs,
970 XEvent *event) {
971 core->gotoNextPage(1, gFalse);
972 }
973
cmdOpen(GString * args[],int nArgs,XEvent * event)974 void XPDFViewer::cmdOpen(GString *args[], int nArgs,
975 XEvent *event) {
976 mapOpenDialog(gFalse);
977 }
978
cmdOpenFile(GString * args[],int nArgs,XEvent * event)979 void XPDFViewer::cmdOpenFile(GString *args[], int nArgs,
980 XEvent *event) {
981 open(args[0], 1, NULL);
982 }
983
cmdOpenFileAtDest(GString * args[],int nArgs,XEvent * event)984 void XPDFViewer::cmdOpenFileAtDest(GString *args[], int nArgs,
985 XEvent *event) {
986 open(args[0], 1, args[1]);
987 }
988
cmdOpenFileAtDestInNewWin(GString * args[],int nArgs,XEvent * event)989 void XPDFViewer::cmdOpenFileAtDestInNewWin(GString *args[], int nArgs,
990 XEvent *event) {
991 app->openAtDest(args[0], args[1]);
992 }
993
cmdOpenFileAtPage(GString * args[],int nArgs,XEvent * event)994 void XPDFViewer::cmdOpenFileAtPage(GString *args[], int nArgs,
995 XEvent *event) {
996 open(args[0], atoi(args[1]->getCString()), NULL);
997 }
998
cmdOpenFileAtPageInNewWin(GString * args[],int nArgs,XEvent * event)999 void XPDFViewer::cmdOpenFileAtPageInNewWin(GString *args[], int nArgs,
1000 XEvent *event) {
1001 app->open(args[0], atoi(args[1]->getCString()));
1002 }
1003
cmdOpenFileInNewWin(GString * args[],int nArgs,XEvent * event)1004 void XPDFViewer::cmdOpenFileInNewWin(GString *args[], int nArgs,
1005 XEvent *event) {
1006 app->open(args[0]);
1007 }
1008
cmdOpenInNewWin(GString * args[],int nArgs,XEvent * event)1009 void XPDFViewer::cmdOpenInNewWin(GString *args[], int nArgs,
1010 XEvent *event) {
1011 mapOpenDialog(gTrue);
1012 }
1013
cmdOpenOutline(GString * args[],int nArgs,XEvent * event)1014 void XPDFViewer::cmdOpenOutline(GString *args[], int nArgs,
1015 XEvent *event) {
1016 #ifndef DISABLE_OUTLINE
1017 Dimension w;
1018
1019 if (outlineScroll == None) {
1020 return;
1021 }
1022 XtVaGetValues(outlineScroll, XmNwidth, &w, NULL);
1023 if (w == 1) {
1024 // this ugly kludge is apparently the only way to resize the panes
1025 // within an XmPanedWindow
1026 XtVaSetValues(outlineScroll, XmNpaneMinimum, outlinePaneWidth,
1027 XmNpaneMaximum, outlinePaneWidth, NULL);
1028 XtVaSetValues(outlineScroll, XmNpaneMinimum, 1,
1029 XmNpaneMaximum, 10000, NULL);
1030 }
1031 #endif
1032 }
1033
cmdPageDown(GString * args[],int nArgs,XEvent * event)1034 void XPDFViewer::cmdPageDown(GString *args[], int nArgs,
1035 XEvent *event) {
1036 core->scrollPageDown();
1037 }
1038
cmdPageUp(GString * args[],int nArgs,XEvent * event)1039 void XPDFViewer::cmdPageUp(GString *args[], int nArgs,
1040 XEvent *event) {
1041 core->scrollPageUp();
1042 }
1043
cmdPostPopupMenu(GString * args[],int nArgs,XEvent * event)1044 void XPDFViewer::cmdPostPopupMenu(GString *args[], int nArgs,
1045 XEvent *event) {
1046 XmMenuPosition(popupMenu, event->type == ButtonPress ? &event->xbutton
1047 : (XButtonEvent *)NULL);
1048 XtManageChild(popupMenu);
1049
1050 // this is magic (taken from DDD) - weird things happen if this
1051 // call isn't made (this is done in two different places, in hopes
1052 // of squashing this stupid bug)
1053 XtUngrabButton(core->getDrawAreaWidget(), AnyButton, AnyModifier);
1054 }
1055
cmdPrevPage(GString * args[],int nArgs,XEvent * event)1056 void XPDFViewer::cmdPrevPage(GString *args[], int nArgs,
1057 XEvent *event) {
1058 core->gotoPrevPage(1, gTrue, gFalse);
1059 }
1060
cmdPrevPageNoScroll(GString * args[],int nArgs,XEvent * event)1061 void XPDFViewer::cmdPrevPageNoScroll(GString *args[], int nArgs,
1062 XEvent *event) {
1063 core->gotoPrevPage(1, gFalse, gFalse);
1064 }
1065
cmdPrint(GString * args[],int nArgs,XEvent * event)1066 void XPDFViewer::cmdPrint(GString *args[], int nArgs,
1067 XEvent *event) {
1068 XtManageChild(printDialog);
1069 }
1070
cmdQuit(GString * args[],int nArgs,XEvent * event)1071 void XPDFViewer::cmdQuit(GString *args[], int nArgs,
1072 XEvent *event) {
1073 app->quit();
1074 }
1075
cmdRaise(GString * args[],int nArgs,XEvent * event)1076 void XPDFViewer::cmdRaise(GString *args[], int nArgs,
1077 XEvent *event) {
1078 XMapRaised(display, XtWindow(win));
1079 XFlush(display);
1080 }
1081
cmdRedraw(GString * args[],int nArgs,XEvent * event)1082 void XPDFViewer::cmdRedraw(GString *args[], int nArgs,
1083 XEvent *event) {
1084 displayPage(core->getPageNum(), core->getZoom(), core->getRotate(),
1085 gFalse, gFalse);
1086 }
1087
cmdReload(GString * args[],int nArgs,XEvent * event)1088 void XPDFViewer::cmdReload(GString *args[], int nArgs,
1089 XEvent *event) {
1090 reloadFile();
1091 }
1092
cmdRotateCCW(GString * args[],int nArgs,XEvent * event)1093 void XPDFViewer::cmdRotateCCW(GString *args[], int nArgs,
1094 XEvent *event) {
1095 int r;
1096
1097 r = core->getRotate();
1098 r = (r == 0) ? 270 : r - 90;
1099 displayPage(core->getPageNum(), core->getZoom(), r, gTrue, gFalse);
1100 }
1101
cmdRotateCW(GString * args[],int nArgs,XEvent * event)1102 void XPDFViewer::cmdRotateCW(GString *args[], int nArgs,
1103 XEvent *event) {
1104 int r;
1105
1106 r = core->getRotate();
1107 r = (r == 270) ? 0 : r + 90;
1108 displayPage(core->getPageNum(), core->getZoom(), r, gTrue, gFalse);
1109 }
1110
cmdRun(GString * args[],int nArgs,XEvent * event)1111 void XPDFViewer::cmdRun(GString *args[], int nArgs,
1112 XEvent *event) {
1113 GString *fmt, *cmd, *s;
1114 LinkAction *action;
1115 double selLRX, selLRY, selURX, selURY, mouseX, mouseY;
1116 int selPage, mousePage;
1117 GBool gotSel, gotMouse;
1118 char buf[64];
1119 char *p;
1120 char c0, c1;
1121 int i;
1122
1123 cmd = new GString();
1124 fmt = args[0];
1125 i = 0;
1126 gotSel = gotMouse = gFalse;
1127 while (i < fmt->getLength()) {
1128 c0 = fmt->getChar(i);
1129 if (c0 == '%' && i+1 < fmt->getLength()) {
1130 c1 = fmt->getChar(i+1);
1131 switch (c1) {
1132 case 'f':
1133 if (core->getDoc() && (s = core->getDoc()->getFileName())) {
1134 cmd->append(s);
1135 }
1136 break;
1137 case 'b':
1138 if (core->getDoc() && (s = core->getDoc()->getFileName())) {
1139 if ((p = strrchr(s->getCString(), '.'))) {
1140 cmd->append(s->getCString(), p - s->getCString());
1141 } else {
1142 cmd->append(s);
1143 }
1144 }
1145 break;
1146 case 'u':
1147 if ((action = core->getLinkAction()) &&
1148 action->getKind() == actionURI) {
1149 s = core->mungeURL(((LinkURI *)action)->getURI());
1150 cmd->append(s);
1151 delete s;
1152 }
1153 break;
1154 case 'p':
1155 if (core->getDoc()) {
1156 sprintf(buf, "%d", core->getPageNum());
1157 cmd->append(buf);
1158 }
1159 break;
1160 case 'x':
1161 case 'y':
1162 case 'X':
1163 case 'Y':
1164 if (!gotSel) {
1165 if (!core->getSelection(&selPage, &selURX, &selURY,
1166 &selLRX, &selLRY)) {
1167 selPage = 0;
1168 selURX = selURY = selLRX = selLRY = 0;
1169 }
1170 gotSel = gTrue;
1171 }
1172 sprintf(buf, "%g",
1173 (c1 == 'x') ? selURX :
1174 (c1 == 'y') ? selURY :
1175 (c1 == 'X') ? selLRX : selLRY);
1176 cmd->append(buf);
1177 break;
1178 case 'i':
1179 case 'j':
1180 case 'k':
1181 if (!gotMouse) {
1182 if (event->type == ButtonPress || event->type == ButtonRelease) {
1183 core->cvtWindowToUser(event->xbutton.x, event->xbutton.y,
1184 &mousePage, &mouseX, &mouseY);
1185 } else if (event->type == KeyPress) {
1186 core->cvtWindowToUser(event->xkey.x, event->xkey.y,
1187 &mousePage, &mouseX, &mouseY);
1188 } else {
1189 mousePage = 0;
1190 mouseX = mouseY = 0;
1191 }
1192 gotMouse = gTrue;
1193 }
1194 if (c1 == 'i') {
1195 sprintf(buf, "%d", mousePage);
1196 } else {
1197 sprintf(buf, "%g", (c1 == 'j') ? mouseX : mouseY);
1198 }
1199 cmd->append(buf);
1200 break;
1201 default:
1202 cmd->append(c1);
1203 break;
1204 }
1205 i += 2;
1206 } else {
1207 cmd->append(c0);
1208 ++i;
1209 }
1210 }
1211 #ifdef VMS
1212 cmd->insert(0, "spawn/nowait ");
1213 #elif defined(__EMX__)
1214 cmd->insert(0, "start /min /n ");
1215 #else
1216 cmd->append(" &");
1217 #endif
1218 system(cmd->getCString());
1219 delete cmd;
1220 }
1221
cmdScrollDown(GString * args[],int nArgs,XEvent * event)1222 void XPDFViewer::cmdScrollDown(GString *args[], int nArgs,
1223 XEvent *event) {
1224 core->scrollDown(atoi(args[0]->getCString()));
1225 }
1226
cmdScrollDownNextPage(GString * args[],int nArgs,XEvent * event)1227 void XPDFViewer::cmdScrollDownNextPage(GString *args[], int nArgs,
1228 XEvent *event) {
1229 core->scrollDownNextPage(atoi(args[0]->getCString()));
1230 }
1231
cmdScrollLeft(GString * args[],int nArgs,XEvent * event)1232 void XPDFViewer::cmdScrollLeft(GString *args[], int nArgs,
1233 XEvent *event) {
1234 core->scrollLeft(atoi(args[0]->getCString()));
1235 }
1236
cmdScrollOutlineDown(GString * args[],int nArgs,XEvent * event)1237 void XPDFViewer::cmdScrollOutlineDown(GString *args[], int nArgs,
1238 XEvent *event) {
1239 #ifndef DISABLE_OUTLINE
1240 Widget sb;
1241 int val, inc, pageInc, m, slider;
1242
1243 if (outlineScroll == None) {
1244 return;
1245 }
1246 if ((sb = XtNameToWidget(outlineScroll, "VertScrollBar"))) {
1247 XtVaGetValues(sb, XmNvalue, &val, XmNincrement, &inc,
1248 XmNpageIncrement, &pageInc, XmNmaximum, &m,
1249 XmNsliderSize, &slider, NULL);
1250 if ((val += inc * atoi(args[0]->getCString())) > m - slider) {
1251 val = m - slider;
1252 }
1253 XmScrollBarSetValues(sb, val, slider, inc, pageInc, True);
1254 }
1255 #endif
1256 }
1257
cmdScrollOutlineUp(GString * args[],int nArgs,XEvent * event)1258 void XPDFViewer::cmdScrollOutlineUp(GString *args[], int nArgs,
1259 XEvent *event) {
1260 #ifndef DISABLE_OUTLINE
1261 Widget sb;
1262 int val, inc, pageInc, m, slider;
1263
1264 if (outlineScroll == None) {
1265 return;
1266 }
1267 if ((sb = XtNameToWidget(outlineScroll, "VertScrollBar"))) {
1268 XtVaGetValues(sb, XmNvalue, &val, XmNincrement, &inc,
1269 XmNpageIncrement, &pageInc, XmNminimum, &m,
1270 XmNsliderSize, &slider, NULL);
1271 if ((val -= inc * atoi(args[0]->getCString())) < m) {
1272 val = m;
1273 }
1274 XmScrollBarSetValues(sb, val, slider, inc, pageInc, True);
1275 }
1276 #endif
1277 }
1278
cmdScrollRight(GString * args[],int nArgs,XEvent * event)1279 void XPDFViewer::cmdScrollRight(GString *args[], int nArgs,
1280 XEvent *event) {
1281 core->scrollRight(atoi(args[0]->getCString()));
1282 }
1283
cmdScrollToBottomEdge(GString * args[],int nArgs,XEvent * event)1284 void XPDFViewer::cmdScrollToBottomEdge(GString *args[], int nArgs,
1285 XEvent *event) {
1286 core->scrollToBottomEdge();
1287 }
1288
cmdScrollToBottomRight(GString * args[],int nArgs,XEvent * event)1289 void XPDFViewer::cmdScrollToBottomRight(GString *args[], int nArgs,
1290 XEvent *event) {
1291 core->scrollToBottomRight();
1292 }
1293
cmdScrollToLeftEdge(GString * args[],int nArgs,XEvent * event)1294 void XPDFViewer::cmdScrollToLeftEdge(GString *args[], int nArgs,
1295 XEvent *event) {
1296 core->scrollToLeftEdge();
1297 }
1298
cmdScrollToRightEdge(GString * args[],int nArgs,XEvent * event)1299 void XPDFViewer::cmdScrollToRightEdge(GString *args[], int nArgs,
1300 XEvent *event) {
1301 core->scrollToRightEdge();
1302 }
1303
cmdScrollToTopEdge(GString * args[],int nArgs,XEvent * event)1304 void XPDFViewer::cmdScrollToTopEdge(GString *args[], int nArgs,
1305 XEvent *event) {
1306 core->scrollToTopEdge();
1307 }
1308
cmdScrollToTopLeft(GString * args[],int nArgs,XEvent * event)1309 void XPDFViewer::cmdScrollToTopLeft(GString *args[], int nArgs,
1310 XEvent *event) {
1311 core->scrollToTopLeft();
1312 }
1313
cmdScrollUp(GString * args[],int nArgs,XEvent * event)1314 void XPDFViewer::cmdScrollUp(GString *args[], int nArgs,
1315 XEvent *event) {
1316 core->scrollUp(atoi(args[0]->getCString()));
1317 }
1318
cmdScrollUpPrevPage(GString * args[],int nArgs,XEvent * event)1319 void XPDFViewer::cmdScrollUpPrevPage(GString *args[], int nArgs,
1320 XEvent *event) {
1321 core->scrollUpPrevPage(atoi(args[0]->getCString()));
1322 }
1323
cmdSetSelection(GString * args[],int nArgs,XEvent * event)1324 void XPDFViewer::cmdSetSelection(GString *args[], int nArgs, XEvent *event) {
1325 int pg, ulx, uly, lrx, lry;
1326
1327 pg = atoi(args[0]->getCString());
1328 core->cvtUserToDev(core->getPageNum(),
1329 atof(args[1]->getCString()), atof(args[2]->getCString()),
1330 &ulx, &uly);
1331 core->cvtUserToDev(core->getPageNum(),
1332 atof(args[3]->getCString()), atof(args[4]->getCString()),
1333 &lrx, &lry);
1334 core->setSelection(pg, ulx, uly, lrx, lry);
1335 }
1336
cmdSinglePageMode(GString * args[],int nArgs,XEvent * event)1337 void XPDFViewer::cmdSinglePageMode(GString *args[], int nArgs,
1338 XEvent *event) {
1339 Widget btn;
1340
1341 if (!core->getContinuousMode()) {
1342 return;
1343 }
1344 core->setContinuousMode(gFalse);
1345
1346 btn = XtNameToWidget(popupMenu, "continuousMode");
1347 XtVaSetValues(btn, XmNset, XmUNSET, NULL);
1348 }
1349
cmdStartPan(GString * args[],int nArgs,XEvent * event)1350 void XPDFViewer::cmdStartPan(GString *args[], int nArgs,
1351 XEvent *event) {
1352 core->startPan(mouseX(event), mouseY(event));
1353 }
1354
cmdStartSelection(GString * args[],int nArgs,XEvent * event)1355 void XPDFViewer::cmdStartSelection(GString *args[], int nArgs,
1356 XEvent *event) {
1357 core->startSelection(mouseX(event), mouseY(event));
1358 }
1359
cmdToggleContinuousMode(GString * args[],int nArgs,XEvent * event)1360 void XPDFViewer::cmdToggleContinuousMode(GString *args[], int nArgs,
1361 XEvent *event) {
1362 if (core->getContinuousMode()) {
1363 cmdSinglePageMode(NULL, 0, event);
1364 } else {
1365 cmdContinuousMode(NULL, 0, event);
1366 }
1367 }
1368
cmdToggleFullScreenMode(GString * args[],int nArgs,XEvent * event)1369 void XPDFViewer::cmdToggleFullScreenMode(GString *args[], int nArgs,
1370 XEvent *event) {
1371 if (core->getFullScreen()) {
1372 cmdWindowMode(NULL, 0, event);
1373 } else {
1374 cmdFullScreenMode(NULL, 0, event);
1375 }
1376 }
1377
cmdToggleOutline(GString * args[],int nArgs,XEvent * event)1378 void XPDFViewer::cmdToggleOutline(GString *args[], int nArgs,
1379 XEvent *event) {
1380 #ifndef DISABLE_OUTLINE
1381 Dimension w;
1382
1383 if (outlineScroll == None) {
1384 return;
1385 }
1386 XtVaGetValues(outlineScroll, XmNwidth, &w, NULL);
1387 if (w > 1) {
1388 cmdCloseOutline(NULL, 0, event);
1389 } else {
1390 cmdOpenOutline(NULL, 0, event);
1391 }
1392 #endif
1393 }
1394
cmdWindowMode(GString * args[],int nArgs,XEvent * event)1395 void XPDFViewer::cmdWindowMode(GString *args[], int nArgs,
1396 XEvent *event) {
1397 PDFDoc *doc;
1398 XPDFViewer *viewer;
1399 int pg;
1400 Widget btn;
1401
1402 if (!core->getFullScreen()) {
1403 return;
1404 }
1405 pg = core->getPageNum();
1406 XtPopdown(win);
1407 doc = core->takeDoc(gFalse);
1408 viewer = app->reopen(this, doc, pg, gFalse);
1409
1410 btn = XtNameToWidget(viewer->popupMenu, "fullScreen");
1411 XtVaSetValues(btn, XmNset, XmUNSET, NULL);
1412 }
1413
cmdZoomFitPage(GString * args[],int nArgs,XEvent * event)1414 void XPDFViewer::cmdZoomFitPage(GString *args[], int nArgs,
1415 XEvent *event) {
1416 if (core->getZoom() != zoomPage) {
1417 setZoomIdx(zoomPageIdx);
1418 displayPage(core->getPageNum(), zoomPage,
1419 core->getRotate(), gTrue, gFalse);
1420 }
1421 }
1422
cmdZoomFitWidth(GString * args[],int nArgs,XEvent * event)1423 void XPDFViewer::cmdZoomFitWidth(GString *args[], int nArgs,
1424 XEvent *event) {
1425 if (core->getZoom() != zoomWidth) {
1426 setZoomIdx(zoomWidthIdx);
1427 displayPage(core->getPageNum(), zoomWidth,
1428 core->getRotate(), gTrue, gFalse);
1429 }
1430 }
1431
cmdZoomIn(GString * args[],int nArgs,XEvent * event)1432 void XPDFViewer::cmdZoomIn(GString *args[], int nArgs,
1433 XEvent *event) {
1434 int z;
1435
1436 z = getZoomIdx();
1437 if (z <= minZoomIdx && z > maxZoomIdx) {
1438 --z;
1439 setZoomIdx(z);
1440 displayPage(core->getPageNum(), zoomMenuInfo[z].zoom,
1441 core->getRotate(), gTrue, gFalse);
1442 }
1443 }
1444
cmdZoomOut(GString * args[],int nArgs,XEvent * event)1445 void XPDFViewer::cmdZoomOut(GString *args[], int nArgs,
1446 XEvent *event) {
1447 int z;
1448
1449 z = getZoomIdx();
1450 if (z < minZoomIdx && z >= maxZoomIdx) {
1451 ++z;
1452 setZoomIdx(z);
1453 displayPage(core->getPageNum(), zoomMenuInfo[z].zoom,
1454 core->getRotate(), gTrue, gFalse);
1455 }
1456 }
1457
cmdZoomPercent(GString * args[],int nArgs,XEvent * event)1458 void XPDFViewer::cmdZoomPercent(GString *args[], int nArgs,
1459 XEvent *event) {
1460 double z;
1461
1462 z = atof(args[0]->getCString());
1463 setZoomVal(z);
1464 displayPage(core->getPageNum(), z, core->getRotate(), gTrue, gFalse);
1465 }
1466
cmdZoomToSelection(GString * args[],int nArgs,XEvent * event)1467 void XPDFViewer::cmdZoomToSelection(GString *args[], int nArgs,
1468 XEvent *event) {
1469 int pg;
1470 double ulx, uly, lrx, lry;
1471
1472 if (core->getSelection(&pg, &ulx, &uly, &lrx, &lry)) {
1473 core->zoomToRect(pg, ulx, uly, lrx, lry);
1474 }
1475 }
1476
1477 //------------------------------------------------------------------------
1478 // GUI code: main window
1479 //------------------------------------------------------------------------
1480
initWindow(GBool fullScreen)1481 void XPDFViewer::initWindow(GBool fullScreen) {
1482 Colormap colormap;
1483 XColor xcol;
1484 Atom state, val;
1485 Arg args[20];
1486 int n;
1487 char *title;
1488
1489 display = XtDisplay(app->getAppShell());
1490 screenNum = XScreenNumberOfScreen(XtScreen(app->getAppShell()));
1491
1492 toolBar = None;
1493 #ifndef DISABLE_OUTLINE
1494 outlineScroll = None;
1495 #endif
1496
1497 // private colormap
1498 if (app->getInstallCmap()) {
1499 XtVaGetValues(app->getAppShell(), XmNcolormap, &colormap, NULL);
1500 // ensure that BlackPixel and WhitePixel are reserved in the
1501 // new colormap
1502 xcol.red = xcol.green = xcol.blue = 0;
1503 XAllocColor(display, colormap, &xcol);
1504 xcol.red = xcol.green = xcol.blue = 65535;
1505 XAllocColor(display, colormap, &xcol);
1506 colormap = XCopyColormapAndFree(display, colormap);
1507 }
1508
1509 // top-level window
1510 n = 0;
1511 title = app->getTitle() ? app->getTitle()->getCString()
1512 : (char *)xpdfAppName;
1513 XtSetArg(args[n], XmNtitle, title); ++n;
1514 XtSetArg(args[n], XmNiconName, title); ++n;
1515 XtSetArg(args[n], XmNminWidth, 100); ++n;
1516 XtSetArg(args[n], XmNminHeight, 100); ++n;
1517 XtSetArg(args[n], XmNbaseWidth, 0); ++n;
1518 XtSetArg(args[n], XmNbaseHeight, 0); ++n;
1519 XtSetArg(args[n], XmNdeleteResponse, XmDO_NOTHING); ++n;
1520 win = XtCreatePopupShell("win", topLevelShellWidgetClass,
1521 app->getAppShell(), args, n);
1522 if (app->getInstallCmap()) {
1523 XtVaSetValues(win, XmNcolormap, colormap, NULL);
1524 }
1525 XmAddWMProtocolCallback(win, XInternAtom(display, "WM_DELETE_WINDOW", False),
1526 &closeMsgCbk, this);
1527
1528 // create the full-screen window
1529 if (fullScreen) {
1530 initCore(win, gTrue);
1531
1532 // create the normal (non-full-screen) window
1533 } else {
1534 if (app->getGeometry()) {
1535 n = 0;
1536 XtSetArg(args[n], XmNgeometry, app->getGeometry()->getCString()); ++n;
1537 XtSetValues(win, args, n);
1538 }
1539
1540 n = 0;
1541 form = XmCreateForm(win, "form", args, n);
1542 XtManageChild(form);
1543
1544 #ifdef DISABLE_OUTLINE
1545 initToolbar(form);
1546 n = 0;
1547 XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
1548 XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
1549 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
1550 XtSetValues(toolBar, args, n);
1551
1552 initCore(form, gFalse);
1553 n = 0;
1554 XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
1555 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); ++n;
1556 XtSetArg(args[n], XmNbottomWidget, toolBar); ++n;
1557 XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
1558 XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
1559 XtSetValues(core->getWidget(), args, n);
1560 #else
1561 initToolbar(form);
1562 n = 0;
1563 XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
1564 XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
1565 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
1566 XtSetValues(toolBar, args, n);
1567
1568 initPanedWin(form);
1569 n = 0;
1570 XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
1571 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); ++n;
1572 XtSetArg(args[n], XmNbottomWidget, toolBar); ++n;
1573 XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
1574 XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
1575 XtSetValues(panedWin, args, n);
1576
1577 initCore(panedWin, fullScreen);
1578 n = 0;
1579 XtSetArg(args[n], XmNpositionIndex, 1); ++n;
1580 XtSetArg(args[n], XmNallowResize, True); ++n;
1581 XtSetArg(args[n], XmNpaneMinimum, 1); ++n;
1582 XtSetArg(args[n], XmNpaneMaximum, 10000); ++n;
1583 XtSetValues(core->getWidget(), args, n);
1584 #endif
1585 }
1586
1587 // set the zoom menu to match the initial zoom setting
1588 setZoomVal(core->getZoom());
1589
1590 // set traversal order
1591 XtVaSetValues(core->getDrawAreaWidget(),
1592 XmNnavigationType, XmEXCLUSIVE_TAB_GROUP, NULL);
1593 if (toolBar != None) {
1594 XtVaSetValues(backBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
1595 NULL);
1596 XtVaSetValues(prevTenPageBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
1597 NULL);
1598 XtVaSetValues(prevPageBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
1599 NULL);
1600 XtVaSetValues(nextPageBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
1601 NULL);
1602 XtVaSetValues(nextTenPageBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
1603 NULL);
1604 XtVaSetValues(forwardBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
1605 NULL);
1606 XtVaSetValues(pageNumText, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
1607 NULL);
1608 XtVaSetValues(zoomWidget, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
1609 NULL);
1610 XtVaSetValues(findBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
1611 NULL);
1612 XtVaSetValues(printBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
1613 NULL);
1614 XtVaSetValues(aboutBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
1615 NULL);
1616 XtVaSetValues(quitBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
1617 NULL);
1618 }
1619
1620 initPopupMenu();
1621
1622 if (fullScreen) {
1623 // Set both the old-style Motif decorations hint and the new-style
1624 // _NET_WM_STATE property. This is redundant, but might be useful
1625 // for older window managers. We also set the geometry to +0+0 to
1626 // avoid interactive placement. (Note: we need to realize the
1627 // shell, so it has a Window on which to set the _NET_WM_STATE
1628 // property, but we don't want to map it until later, so we set
1629 // mappedWhenManaged to false.)
1630 n = 0;
1631 XtSetArg(args[n], XmNmappedWhenManaged, False); ++n;
1632 XtSetArg(args[n], XmNmwmDecorations, 0); ++n;
1633 XtSetArg(args[n], XmNgeometry, "+0+0"); ++n;
1634 XtSetValues(win, args, n);
1635 XtRealizeWidget(win);
1636 state = XInternAtom(display, "_NET_WM_STATE", False);
1637 val = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", False);
1638 XChangeProperty(display, XtWindow(win), state, XA_ATOM, 32,
1639 PropModeReplace, (Guchar *)&val, 1);
1640 }
1641 }
1642
initToolbar(Widget parent)1643 void XPDFViewer::initToolbar(Widget parent) {
1644 Widget label, lastBtn;
1645 #ifndef USE_COMBO_BOX
1646 Widget btn;
1647 #endif
1648 Arg args[20];
1649 int n;
1650 XmString s, emptyString;
1651 int i;
1652
1653 // toolbar
1654 n = 0;
1655 toolBar = XmCreateForm(parent, "toolBar", args, n);
1656 XtManageChild(toolBar);
1657
1658 // create an empty string -- this is used for buttons that will get
1659 // pixmaps later
1660 emptyString = XmStringCreateLocalized("");
1661
1662 // page movement buttons
1663 n = 0;
1664 XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
1665 XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
1666 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
1667 XtSetArg(args[n], XmNmarginWidth, 6); ++n;
1668 XtSetArg(args[n], XmNsensitive, False); ++n;
1669 XtSetArg(args[n], XmNlabelString, emptyString); ++n;
1670 backBtn = XmCreatePushButton(toolBar, "back", args, n);
1671 addToolTip(backBtn, "Back");
1672 XtManageChild(backBtn);
1673 XtAddCallback(backBtn, XmNactivateCallback,
1674 &backCbk, (XtPointer)this);
1675 n = 0;
1676 XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
1677 XtSetArg(args[n], XmNleftWidget, backBtn); ++n;
1678 XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
1679 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
1680 XtSetArg(args[n], XmNmarginWidth, 6); ++n;
1681 XtSetArg(args[n], XmNsensitive, False); ++n;
1682 XtSetArg(args[n], XmNlabelString, emptyString); ++n;
1683 prevTenPageBtn = XmCreatePushButton(toolBar, "prevTenPage", args, n);
1684 addToolTip(prevTenPageBtn, "-10 pages");
1685 XtManageChild(prevTenPageBtn);
1686 XtAddCallback(prevTenPageBtn, XmNactivateCallback,
1687 &prevTenPageCbk, (XtPointer)this);
1688 n = 0;
1689 XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
1690 XtSetArg(args[n], XmNleftWidget, prevTenPageBtn); ++n;
1691 XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
1692 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
1693 XtSetArg(args[n], XmNmarginWidth, 6); ++n;
1694 XtSetArg(args[n], XmNsensitive, False); ++n;
1695 XtSetArg(args[n], XmNlabelString, emptyString); ++n;
1696 prevPageBtn = XmCreatePushButton(toolBar, "prevPage", args, n);
1697 addToolTip(prevPageBtn, "Previous page");
1698 XtManageChild(prevPageBtn);
1699 XtAddCallback(prevPageBtn, XmNactivateCallback,
1700 &prevPageCbk, (XtPointer)this);
1701 n = 0;
1702 XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
1703 XtSetArg(args[n], XmNleftWidget, prevPageBtn); ++n;
1704 XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
1705 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
1706 XtSetArg(args[n], XmNmarginWidth, 6); ++n;
1707 XtSetArg(args[n], XmNsensitive, False); ++n;
1708 XtSetArg(args[n], XmNlabelString, emptyString); ++n;
1709 nextPageBtn = XmCreatePushButton(toolBar, "nextPage", args, n);
1710 addToolTip(nextPageBtn, "Next page");
1711 XtManageChild(nextPageBtn);
1712 XtAddCallback(nextPageBtn, XmNactivateCallback,
1713 &nextPageCbk, (XtPointer)this);
1714 n = 0;
1715 XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
1716 XtSetArg(args[n], XmNleftWidget, nextPageBtn); ++n;
1717 XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
1718 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
1719 XtSetArg(args[n], XmNmarginWidth, 6); ++n;
1720 XtSetArg(args[n], XmNsensitive, False); ++n;
1721 XtSetArg(args[n], XmNlabelString, emptyString); ++n;
1722 nextTenPageBtn = XmCreatePushButton(toolBar, "nextTenPage", args, n);
1723 addToolTip(nextTenPageBtn, "+10 pages");
1724 XtManageChild(nextTenPageBtn);
1725 XtAddCallback(nextTenPageBtn, XmNactivateCallback,
1726 &nextTenPageCbk, (XtPointer)this);
1727 n = 0;
1728 XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
1729 XtSetArg(args[n], XmNleftWidget, nextTenPageBtn); ++n;
1730 XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
1731 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
1732 XtSetArg(args[n], XmNmarginWidth, 6); ++n;
1733 XtSetArg(args[n], XmNsensitive, False); ++n;
1734 XtSetArg(args[n], XmNlabelString, emptyString); ++n;
1735 forwardBtn = XmCreatePushButton(toolBar, "forward", args, n);
1736 addToolTip(forwardBtn, "Forward");
1737 XtManageChild(forwardBtn);
1738 XtAddCallback(forwardBtn, XmNactivateCallback,
1739 &forwardCbk, (XtPointer)this);
1740
1741 // page number display
1742 n = 0;
1743 XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
1744 XtSetArg(args[n], XmNleftWidget, forwardBtn); ++n;
1745 XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
1746 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
1747 s = XmStringCreateLocalized("Page ");
1748 XtSetArg(args[n], XmNlabelString, s); ++n;
1749 label = XmCreateLabel(toolBar, "pageLabel", args, n);
1750 XmStringFree(s);
1751 XtManageChild(label);
1752 n = 0;
1753 XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
1754 XtSetArg(args[n], XmNleftWidget, label); ++n;
1755 XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
1756 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
1757 XtSetArg(args[n], XmNmarginWidth, 3); ++n;
1758 XtSetArg(args[n], XmNmarginHeight, 3); ++n;
1759 XtSetArg(args[n], XmNcolumns, 5); ++n;
1760 pageNumText = XmCreateTextField(toolBar, "pageNum", args, n);
1761 XtManageChild(pageNumText);
1762 XtAddCallback(pageNumText, XmNactivateCallback,
1763 &pageNumCbk, (XtPointer)this);
1764 n = 0;
1765 XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
1766 XtSetArg(args[n], XmNleftWidget, pageNumText); ++n;
1767 XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
1768 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
1769 s = XmStringCreateLocalized(" of 00000");
1770 XtSetArg(args[n], XmNlabelString, s); ++n;
1771 XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); ++n;
1772 XtSetArg(args[n], XmNrecomputeSize, False); ++n;
1773 pageCountLabel = XmCreateLabel(toolBar, "pageCountLabel", args, n);
1774 XmStringFree(s);
1775 XtManageChild(pageCountLabel);
1776 s = XmStringCreateLocalized(" of 0");
1777 XtVaSetValues(pageCountLabel, XmNlabelString, s, NULL);
1778 XmStringFree(s);
1779
1780 // zoom menu
1781 #if USE_COMBO_BOX
1782 XmString st[nZoomMenuItems];
1783 n = 0;
1784 XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
1785 XtSetArg(args[n], XmNleftWidget, pageCountLabel); ++n;
1786 XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
1787 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
1788 XtSetArg(args[n], XmNmarginWidth, 0); ++n;
1789 XtSetArg(args[n], XmNmarginHeight, 0); ++n;
1790 XtSetArg(args[n], XmNcomboBoxType, XmDROP_DOWN_COMBO_BOX); ++n;
1791 XtSetArg(args[n], XmNpositionMode, XmONE_BASED); ++n;
1792 XtSetArg(args[n], XmNcolumns, 7); ++n;
1793 for (i = 0; i < nZoomMenuItems; ++i) {
1794 st[i] = XmStringCreateLocalized((char *)zoomMenuInfo[i].label);
1795 }
1796 XtSetArg(args[n], XmNitems, st); ++n;
1797 XtSetArg(args[n], XmNitemCount, nZoomMenuItems); ++n;
1798 zoomComboBox = XmCreateComboBox(toolBar, "zoomComboBox", args, n);
1799 for (i = 0; i < nZoomMenuItems; ++i) {
1800 XmStringFree(st[i]);
1801 }
1802 addToolTip(zoomComboBox, "Zoom");
1803 XtAddCallback(zoomComboBox, XmNselectionCallback,
1804 &zoomComboBoxCbk, (XtPointer)this);
1805 XtManageChild(zoomComboBox);
1806 zoomWidget = zoomComboBox;
1807 #else
1808 Widget menuPane;
1809 char buf[16];
1810 n = 0;
1811 menuPane = XmCreatePulldownMenu(toolBar, "zoomMenuPane", args, n);
1812 for (i = 0; i < nZoomMenuItems; ++i) {
1813 n = 0;
1814 s = XmStringCreateLocalized((char *)zoomMenuInfo[i].label);
1815 XtSetArg(args[n], XmNlabelString, s); ++n;
1816 XtSetArg(args[n], XmNuserData, (XtPointer)i); ++n;
1817 sprintf(buf, "zoom%d", i);
1818 btn = XmCreatePushButton(menuPane, buf, args, n);
1819 XmStringFree(s);
1820 XtManageChild(btn);
1821 XtAddCallback(btn, XmNactivateCallback,
1822 &zoomMenuCbk, (XtPointer)this);
1823 zoomMenuBtns[i] = btn;
1824 }
1825 n = 0;
1826 XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
1827 XtSetArg(args[n], XmNleftWidget, pageCountLabel); ++n;
1828 XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
1829 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
1830 XtSetArg(args[n], XmNmarginWidth, 0); ++n;
1831 XtSetArg(args[n], XmNmarginHeight, 0); ++n;
1832 XtSetArg(args[n], XmNsubMenuId, menuPane); ++n;
1833 zoomMenu = XmCreateOptionMenu(toolBar, "zoomMenu", args, n);
1834 addToolTip(zoomMenu, "Zoom");
1835 XtManageChild(zoomMenu);
1836 zoomWidget = zoomMenu;
1837 #endif
1838
1839 // find/print/about buttons
1840 n = 0;
1841 XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
1842 XtSetArg(args[n], XmNleftWidget, zoomWidget); ++n;
1843 XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
1844 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
1845 XtSetArg(args[n], XmNmarginWidth, 6); ++n;
1846 XtSetArg(args[n], XmNlabelString, emptyString); ++n;
1847 findBtn = XmCreatePushButton(toolBar, "find", args, n);
1848 addToolTip(findBtn, "Find");
1849 XtManageChild(findBtn);
1850 XtAddCallback(findBtn, XmNactivateCallback,
1851 &findCbk, (XtPointer)this);
1852 n = 0;
1853 XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
1854 XtSetArg(args[n], XmNleftWidget, findBtn); ++n;
1855 XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
1856 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
1857 XtSetArg(args[n], XmNmarginWidth, 6); ++n;
1858 XtSetArg(args[n], XmNlabelString, emptyString); ++n;
1859 printBtn = XmCreatePushButton(toolBar, "print", args, n);
1860 addToolTip(printBtn, "Print");
1861 XtManageChild(printBtn);
1862 XtAddCallback(printBtn, XmNactivateCallback,
1863 &printCbk, (XtPointer)this);
1864 n = 0;
1865 XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
1866 XtSetArg(args[n], XmNleftWidget, printBtn); ++n;
1867 XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
1868 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
1869 XtSetArg(args[n], XmNmarginWidth, 6); ++n;
1870 XtSetArg(args[n], XmNlabelString, emptyString); ++n;
1871 aboutBtn = XmCreatePushButton(toolBar, "about", args, n);
1872 addToolTip(aboutBtn, "About / help");
1873 XtManageChild(aboutBtn);
1874 XtAddCallback(aboutBtn, XmNactivateCallback,
1875 &aboutCbk, (XtPointer)this);
1876 lastBtn = aboutBtn;
1877
1878 // quit button
1879 n = 0;
1880 XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
1881 XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
1882 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
1883 XtSetArg(args[n], XmNmarginWidth, 6); ++n;
1884 s = XmStringCreateLocalized("Quit");
1885 XtSetArg(args[n], XmNlabelString, s); ++n;
1886 quitBtn = XmCreatePushButton(toolBar, "quit", args, n);
1887 XmStringFree(s);
1888 XtManageChild(quitBtn);
1889 XtAddCallback(quitBtn, XmNactivateCallback,
1890 &quitCbk, (XtPointer)this);
1891
1892 // link label
1893 n = 0;
1894 XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
1895 XtSetArg(args[n], XmNleftWidget, lastBtn); ++n;
1896 XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); ++n;
1897 XtSetArg(args[n], XmNrightWidget, quitBtn); ++n;
1898 XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
1899 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
1900 s = XmStringCreateLocalized("");
1901 XtSetArg(args[n], XmNlabelString, s); ++n;
1902 XtSetArg(args[n], XmNrecomputeSize, True); ++n;
1903 XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); ++n;
1904 linkLabel = XmCreateLabel(toolBar, "linkLabel", args, n);
1905 XmStringFree(s);
1906 XtManageChild(linkLabel);
1907
1908 XmStringFree(emptyString);
1909 }
1910
1911 #ifndef DISABLE_OUTLINE
initPanedWin(Widget parent)1912 void XPDFViewer::initPanedWin(Widget parent) {
1913 Widget clipWin;
1914 Arg args[20];
1915 int n;
1916
1917 // paned window
1918 n = 0;
1919 XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
1920 #if defined(__sgi) && (XmVERSION <= 1)
1921 panedWin = SgCreateHorzPanedWindow(parent, "panedWin", args, n);
1922 #else
1923 panedWin = XmCreatePanedWindow(parent, "panedWin", args, n);
1924 #endif
1925 XtManageChild(panedWin);
1926
1927 // scrolled window for outline container
1928 n = 0;
1929 XtSetArg(args[n], XmNpositionIndex, 0); ++n;
1930 XtSetArg(args[n], XmNallowResize, True); ++n;
1931 XtSetArg(args[n], XmNpaneMinimum, 1); ++n;
1932 XtSetArg(args[n], XmNpaneMaximum, 10000); ++n;
1933 #if !(defined(__sgi) && (XmVERSION <= 1))
1934 XtSetArg(args[n], XmNwidth, 1); ++n;
1935 #endif
1936 XtSetArg(args[n], XmNscrollingPolicy, XmAUTOMATIC); ++n;
1937 outlineScroll = XmCreateScrolledWindow(panedWin, "outlineScroll", args, n);
1938 XtManageChild(outlineScroll);
1939 XtVaGetValues(outlineScroll, XmNclipWindow, &clipWin, NULL);
1940 XtVaSetValues(clipWin, XmNbackground, app->getPaperPixel(), NULL);
1941
1942 // outline tree
1943 n = 0;
1944 XtSetArg(args[n], XmNbackground, app->getPaperPixel()); ++n;
1945 outlineTree = XPDFCreateTree(outlineScroll, "outlineTree", args, n);
1946 XtManageChild(outlineTree);
1947 XtAddCallback(outlineTree, XPDFNselectionCallback, &outlineSelectCbk,
1948 (XtPointer)this);
1949 }
1950 #endif
1951
initCore(Widget parent,GBool fullScreen)1952 void XPDFViewer::initCore(Widget parent, GBool fullScreen) {
1953 core = new XPDFCore(win, parent,
1954 app->getPaperRGB(), app->getPaperPixel(),
1955 app->getMattePixel(fullScreen),
1956 fullScreen, app->getReverseVideo(),
1957 app->getInstallCmap(), app->getRGBCubeSize());
1958 core->setUpdateCbk(&updateCbk, this);
1959 core->setActionCbk(&actionCbk, this);
1960 core->setKeyPressCbk(&keyPressCbk, this);
1961 core->setMouseCbk(&mouseCbk, this);
1962 }
1963
initPopupMenu()1964 void XPDFViewer::initPopupMenu() {
1965 Widget btn;
1966 Arg args[20];
1967 int n;
1968 XmString s, s2;
1969
1970 n = 0;
1971 #if XmVersion < 1002
1972 // older versions of Motif need this, newer ones choke on it,
1973 // sometimes not displaying the menu at all, maybe depending on the
1974 // state of the NumLock key (taken from DDD)
1975 XtSetArg(args[n], XmNmenuPost, "<Btn3Down>"); ++n;
1976 #endif
1977 popupMenu = XmCreatePopupMenu(core->getDrawAreaWidget(), "popupMenu",
1978 args, n);
1979 n = 0;
1980 s = XmStringCreateLocalized("Open...");
1981 XtSetArg(args[n], XmNlabelString, s); ++n;
1982 s2 = XmStringCreateLocalized("O");
1983 XtSetArg(args[n], XmNacceleratorText, s2); ++n;
1984 btn = XmCreatePushButton(popupMenu, "open", args, n);
1985 XmStringFree(s);
1986 XmStringFree(s2);
1987 XtManageChild(btn);
1988 XtAddCallback(btn, XmNactivateCallback,
1989 &openCbk, (XtPointer)this);
1990 n = 0;
1991 s = XmStringCreateLocalized("Open in new window...");
1992 XtSetArg(args[n], XmNlabelString, s); ++n;
1993 btn = XmCreatePushButton(popupMenu, "openInNewWindow", args, n);
1994 XmStringFree(s);
1995 XtManageChild(btn);
1996 XtAddCallback(btn, XmNactivateCallback,
1997 &openInNewWindowCbk, (XtPointer)this);
1998 n = 0;
1999 s = XmStringCreateLocalized("Reload");
2000 XtSetArg(args[n], XmNlabelString, s); ++n;
2001 s2 = XmStringCreateLocalized("R");
2002 XtSetArg(args[n], XmNacceleratorText, s2); ++n;
2003 btn = XmCreatePushButton(popupMenu, "reload", args, n);
2004 XmStringFree(s);
2005 XmStringFree(s2);
2006 XtManageChild(btn);
2007 XtAddCallback(btn, XmNactivateCallback,
2008 &reloadCbk, (XtPointer)this);
2009 n = 0;
2010 s = XmStringCreateLocalized("Save as...");
2011 XtSetArg(args[n], XmNlabelString, s); ++n;
2012 btn = XmCreatePushButton(popupMenu, "saveAs", args, n);
2013 XmStringFree(s);
2014 XtManageChild(btn);
2015 XtAddCallback(btn, XmNactivateCallback,
2016 &saveAsCbk, (XtPointer)this);
2017 n = 0;
2018 btn = XmCreateSeparator(popupMenu, "sep1", args, n);
2019 XtManageChild(btn);
2020 n = 0;
2021 s = XmStringCreateLocalized("Continuous view");
2022 XtSetArg(args[n], XmNlabelString, s); ++n;
2023 XtSetArg(args[n], XmNindicatorType, XmN_OF_MANY); ++n;
2024 XtSetArg(args[n], XmNvisibleWhenOff, True); ++n;
2025 XtSetArg(args[n], XmNset, core->getContinuousMode() ? XmSET : XmUNSET); ++n;
2026 btn = XmCreateToggleButton(popupMenu, "continuousMode", args, n);
2027 XmStringFree(s);
2028 XtManageChild(btn);
2029 XtAddCallback(btn, XmNvalueChangedCallback,
2030 &continuousModeToggleCbk, (XtPointer)this);
2031 n = 0;
2032 s = XmStringCreateLocalized("Full screen");
2033 XtSetArg(args[n], XmNlabelString, s); ++n;
2034 XtSetArg(args[n], XmNindicatorType, XmN_OF_MANY); ++n;
2035 XtSetArg(args[n], XmNvisibleWhenOff, True); ++n;
2036 XtSetArg(args[n], XmNset, core->getFullScreen() ? XmSET : XmUNSET); ++n;
2037 btn = XmCreateToggleButton(popupMenu, "fullScreen", args, n);
2038 XmStringFree(s);
2039 XtManageChild(btn);
2040 XtAddCallback(btn, XmNvalueChangedCallback,
2041 &fullScreenToggleCbk, (XtPointer)this);
2042 n = 0;
2043 s = XmStringCreateLocalized("Rotate counterclockwise");
2044 XtSetArg(args[n], XmNlabelString, s); ++n;
2045 btn = XmCreatePushButton(popupMenu, "rotateCCW", args, n);
2046 XmStringFree(s);
2047 XtManageChild(btn);
2048 XtAddCallback(btn, XmNactivateCallback,
2049 &rotateCCWCbk, (XtPointer)this);
2050 n = 0;
2051 s = XmStringCreateLocalized("Rotate clockwise");
2052 XtSetArg(args[n], XmNlabelString, s); ++n;
2053 btn = XmCreatePushButton(popupMenu, "rotateCW", args, n);
2054 XmStringFree(s);
2055 XtManageChild(btn);
2056 XtAddCallback(btn, XmNactivateCallback,
2057 &rotateCWCbk, (XtPointer)this);
2058 n = 0;
2059 s = XmStringCreateLocalized("Zoom to selection");
2060 XtSetArg(args[n], XmNlabelString, s); ++n;
2061 btn = XmCreatePushButton(popupMenu, "zoomToSelection", args, n);
2062 XmStringFree(s);
2063 XtManageChild(btn);
2064 XtAddCallback(btn, XmNactivateCallback,
2065 &zoomToSelectionCbk, (XtPointer)this);
2066 n = 0;
2067 btn = XmCreateSeparator(popupMenu, "sep2", args, n);
2068 XtManageChild(btn);
2069 n = 0;
2070 s = XmStringCreateLocalized("Close");
2071 XtSetArg(args[n], XmNlabelString, s); ++n;
2072 s2 = XmStringCreateLocalized("Ctrl+W");
2073 XtSetArg(args[n], XmNacceleratorText, s2); ++n;
2074 btn = XmCreatePushButton(popupMenu, "close", args, n);
2075 XmStringFree(s);
2076 XmStringFree(s2);
2077 XtManageChild(btn);
2078 XtAddCallback(btn, XmNactivateCallback,
2079 &closeCbk, (XtPointer)this);
2080 n = 0;
2081 s = XmStringCreateLocalized("Quit");
2082 XtSetArg(args[n], XmNlabelString, s); ++n;
2083 s2 = XmStringCreateLocalized("Q");
2084 XtSetArg(args[n], XmNacceleratorText, s2); ++n;
2085 btn = XmCreatePushButton(popupMenu, "quit", args, n);
2086 XmStringFree(s);
2087 XmStringFree(s2);
2088 XtManageChild(btn);
2089 XtAddCallback(btn, XmNactivateCallback,
2090 &quitCbk, (XtPointer)this);
2091
2092 // this is magic (taken from DDD) - weird things happen if this
2093 // call isn't made
2094 XtUngrabButton(core->getDrawAreaWidget(), AnyButton, AnyModifier);
2095 }
2096
addToolTip(Widget widget,char * text)2097 void XPDFViewer::addToolTip(Widget widget, char *text) {
2098 #ifdef XmNtoolTipString
2099 XmString s;
2100 Cardinal n, i;
2101 WidgetList children;
2102
2103 if (XtIsComposite(widget)) {
2104 XtVaGetValues(widget, XmNnumChildren, &n, XmNchildren, &children, NULL);
2105 for (i = 0; i < n; ++i) {
2106 addToolTip(children[i], text);
2107 }
2108 } else {
2109 s = XmStringCreateLocalized(text);
2110 XtVaSetValues(widget, XmNtoolTipString, s, NULL);
2111 XmStringFree(s);
2112 }
2113 #endif
2114 }
2115
mapWindow()2116 void XPDFViewer::mapWindow() {
2117 #ifdef HAVE_X11_XPM_H
2118 Pixmap iconPixmap;
2119 #endif
2120 int depth;
2121 Pixel fg, bg, arm;
2122
2123 // show the window
2124 XtPopup(win, XtGrabNone);
2125 core->takeFocus();
2126
2127 // create the icon
2128 #ifdef HAVE_X11_XPM_H
2129 if (XpmCreatePixmapFromData(display, XtWindow(win), xpdfIcon,
2130 &iconPixmap, NULL, NULL) == XpmSuccess) {
2131 XtVaSetValues(win, XmNiconPixmap, iconPixmap, NULL);
2132 }
2133 #endif
2134
2135 // set button bitmaps (must be done after the window is mapped)
2136 if (toolBar != None) {
2137 XtVaGetValues(backBtn, XmNdepth, &depth,
2138 XmNforeground, &fg, XmNbackground, &bg,
2139 XmNarmColor, &arm, NULL);
2140 XtVaSetValues(backBtn, XmNlabelType, XmPIXMAP,
2141 XmNlabelPixmap,
2142 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
2143 (char *)backArrow_bits,
2144 backArrow_width,
2145 backArrow_height,
2146 fg, bg, depth),
2147 XmNarmPixmap,
2148 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
2149 (char *)backArrow_bits,
2150 backArrow_width,
2151 backArrow_height,
2152 fg, arm, depth),
2153 XmNlabelInsensitivePixmap,
2154 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
2155 (char *)backArrowDis_bits,
2156 backArrowDis_width,
2157 backArrowDis_height,
2158 fg, bg, depth),
2159 NULL);
2160 XtVaSetValues(prevTenPageBtn, XmNlabelType, XmPIXMAP,
2161 XmNlabelPixmap,
2162 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
2163 (char *)dblLeftArrow_bits,
2164 dblLeftArrow_width,
2165 dblLeftArrow_height,
2166 fg, bg, depth),
2167 XmNarmPixmap,
2168 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
2169 (char *)dblLeftArrow_bits,
2170 dblLeftArrow_width,
2171 dblLeftArrow_height,
2172 fg, arm, depth),
2173 XmNlabelInsensitivePixmap,
2174 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
2175 (char *)dblLeftArrowDis_bits,
2176 dblLeftArrowDis_width,
2177 dblLeftArrowDis_height,
2178 fg, bg, depth),
2179 NULL);
2180 XtVaSetValues(prevPageBtn, XmNlabelType, XmPIXMAP,
2181 XmNlabelPixmap,
2182 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
2183 (char *)leftArrow_bits,
2184 leftArrow_width,
2185 leftArrow_height,
2186 fg, bg, depth),
2187 XmNarmPixmap,
2188 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
2189 (char *)leftArrow_bits,
2190 leftArrow_width,
2191 leftArrow_height,
2192 fg, arm, depth),
2193 XmNlabelInsensitivePixmap,
2194 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
2195 (char *)leftArrowDis_bits,
2196 leftArrowDis_width,
2197 leftArrowDis_height,
2198 fg, bg, depth),
2199 NULL);
2200 XtVaSetValues(nextPageBtn, XmNlabelType, XmPIXMAP,
2201 XmNlabelPixmap,
2202 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
2203 (char *)rightArrow_bits,
2204 rightArrow_width,
2205 rightArrow_height,
2206 fg, bg, depth),
2207 XmNarmPixmap,
2208 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
2209 (char *)rightArrow_bits,
2210 rightArrow_width,
2211 rightArrow_height,
2212 fg, arm, depth),
2213 XmNlabelInsensitivePixmap,
2214 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
2215 (char *)rightArrowDis_bits,
2216 rightArrowDis_width,
2217 rightArrowDis_height,
2218 fg, bg, depth),
2219 NULL);
2220 XtVaSetValues(nextTenPageBtn, XmNlabelType, XmPIXMAP,
2221 XmNlabelPixmap,
2222 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
2223 (char *)dblRightArrow_bits,
2224 dblRightArrow_width,
2225 dblRightArrow_height,
2226 fg, bg, depth),
2227 XmNarmPixmap,
2228 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
2229 (char *)dblRightArrow_bits,
2230 dblRightArrow_width,
2231 dblRightArrow_height,
2232 fg, arm, depth),
2233 XmNlabelInsensitivePixmap,
2234 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
2235 (char *)dblRightArrowDis_bits,
2236 dblRightArrowDis_width,
2237 dblRightArrowDis_height,
2238 fg, bg, depth),
2239 NULL);
2240 XtVaSetValues(forwardBtn, XmNlabelType, XmPIXMAP,
2241 XmNlabelPixmap,
2242 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
2243 (char *)forwardArrow_bits,
2244 forwardArrow_width,
2245 forwardArrow_height,
2246 fg, bg, depth),
2247 XmNarmPixmap,
2248 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
2249 (char *)forwardArrow_bits,
2250 forwardArrow_width,
2251 forwardArrow_height,
2252 fg, arm, depth),
2253 XmNlabelInsensitivePixmap,
2254 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
2255 (char *)forwardArrowDis_bits,
2256 forwardArrowDis_width,
2257 forwardArrowDis_height,
2258 fg, bg, depth),
2259 NULL);
2260 XtVaSetValues(findBtn, XmNlabelType, XmPIXMAP,
2261 XmNlabelPixmap,
2262 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
2263 (char *)find_bits,
2264 find_width,
2265 find_height,
2266 fg, bg, depth),
2267 XmNarmPixmap,
2268 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
2269 (char *)find_bits,
2270 find_width,
2271 find_height,
2272 fg, arm, depth),
2273 XmNlabelInsensitivePixmap,
2274 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
2275 (char *)findDis_bits,
2276 findDis_width,
2277 findDis_height,
2278 fg, bg, depth),
2279 NULL);
2280 XtVaSetValues(printBtn, XmNlabelType, XmPIXMAP,
2281 XmNlabelPixmap,
2282 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
2283 (char *)print_bits,
2284 print_width,
2285 print_height,
2286 fg, bg, depth),
2287 XmNarmPixmap,
2288 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
2289 (char *)print_bits,
2290 print_width,
2291 print_height,
2292 fg, arm, depth),
2293 XmNlabelInsensitivePixmap,
2294 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
2295 (char *)printDis_bits,
2296 printDis_width,
2297 printDis_height,
2298 fg, bg, depth),
2299 NULL);
2300 XtVaSetValues(aboutBtn, XmNlabelType, XmPIXMAP,
2301 XmNlabelPixmap,
2302 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
2303 (char *)about_bits,
2304 about_width,
2305 about_height,
2306 fg, bg, depth),
2307 XmNarmPixmap,
2308 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
2309 (char *)about_bits,
2310 about_width,
2311 about_height,
2312 fg, arm, depth),
2313 NULL);
2314 }
2315 }
2316
closeWindow()2317 void XPDFViewer::closeWindow() {
2318 XtPopdown(win);
2319 XtDestroyWidget(win);
2320 }
2321
getZoomIdx()2322 int XPDFViewer::getZoomIdx() {
2323 int i;
2324
2325 for (i = 0; i < nZoomMenuItems; ++i) {
2326 if (core->getZoom() == zoomMenuInfo[i].zoom) {
2327 return i;
2328 }
2329 }
2330 return -1;
2331 }
2332
setZoomIdx(int idx)2333 void XPDFViewer::setZoomIdx(int idx) {
2334 if (toolBar == None) {
2335 return;
2336 }
2337 #if USE_COMBO_BOX
2338 XtVaSetValues(zoomComboBox, XmNselectedPosition, idx + 1, NULL);
2339 #else
2340 XtVaSetValues(zoomMenu, XmNmenuHistory, zoomMenuBtns[idx], NULL);
2341 #endif
2342 }
2343
setZoomVal(double z)2344 void XPDFViewer::setZoomVal(double z) {
2345 if (toolBar == None) {
2346 return;
2347 }
2348
2349 #if USE_COMBO_BOX
2350 char buf[32];
2351 XmString s;
2352 int i;
2353
2354 for (i = 0; i < nZoomMenuItems; ++i) {
2355 if (z == zoomMenuInfo[i].zoom) {
2356 XtVaSetValues(zoomComboBox, XmNselectedPosition, i + 1, NULL);
2357 return;
2358 }
2359 }
2360 sprintf(buf, "%d%%", (int)z);
2361 s = XmStringCreateLocalized(buf);
2362 XtVaSetValues(zoomComboBox, XmNselectedItem, s, NULL);
2363 XmStringFree(s);
2364 #else
2365 int i;
2366
2367 for (i = 0; i < nZoomMenuItems; ++i) {
2368 if (z == zoomMenuInfo[i].zoom) {
2369 XtVaSetValues(zoomMenu, XmNmenuHistory, zoomMenuBtns[i], NULL);
2370 return;
2371 }
2372 }
2373 for (i = maxZoomIdx; i < minZoomIdx; ++i) {
2374 if (z > zoomMenuInfo[i].zoom) {
2375 break;
2376 }
2377 }
2378 XtVaSetValues(zoomMenu, XmNmenuHistory, zoomMenuBtns[i], NULL);
2379 #endif
2380 }
2381
prevPageCbk(Widget widget,XtPointer ptr,XtPointer callData)2382 void XPDFViewer::prevPageCbk(Widget widget, XtPointer ptr,
2383 XtPointer callData) {
2384 XPDFViewer *viewer = (XPDFViewer *)ptr;
2385
2386 viewer->core->gotoPrevPage(1, gTrue, gFalse);
2387 viewer->core->takeFocus();
2388 }
2389
prevTenPageCbk(Widget widget,XtPointer ptr,XtPointer callData)2390 void XPDFViewer::prevTenPageCbk(Widget widget, XtPointer ptr,
2391 XtPointer callData) {
2392 XPDFViewer *viewer = (XPDFViewer *)ptr;
2393
2394 viewer->core->gotoPrevPage(10, gTrue, gFalse);
2395 viewer->core->takeFocus();
2396 }
2397
nextPageCbk(Widget widget,XtPointer ptr,XtPointer callData)2398 void XPDFViewer::nextPageCbk(Widget widget, XtPointer ptr,
2399 XtPointer callData) {
2400 XPDFViewer *viewer = (XPDFViewer *)ptr;
2401
2402 viewer->core->gotoNextPage(1, gTrue);
2403 viewer->core->takeFocus();
2404 }
2405
nextTenPageCbk(Widget widget,XtPointer ptr,XtPointer callData)2406 void XPDFViewer::nextTenPageCbk(Widget widget, XtPointer ptr,
2407 XtPointer callData) {
2408 XPDFViewer *viewer = (XPDFViewer *)ptr;
2409
2410 viewer->core->gotoNextPage(10, gTrue);
2411 viewer->core->takeFocus();
2412 }
2413
backCbk(Widget widget,XtPointer ptr,XtPointer callData)2414 void XPDFViewer::backCbk(Widget widget, XtPointer ptr,
2415 XtPointer callData) {
2416 XPDFViewer *viewer = (XPDFViewer *)ptr;
2417
2418 viewer->core->goBackward();
2419 viewer->core->takeFocus();
2420 }
2421
forwardCbk(Widget widget,XtPointer ptr,XtPointer callData)2422 void XPDFViewer::forwardCbk(Widget widget, XtPointer ptr,
2423 XtPointer callData) {
2424 XPDFViewer *viewer = (XPDFViewer *)ptr;
2425
2426 viewer->core->goForward();
2427 viewer->core->takeFocus();
2428 }
2429
2430 #if USE_COMBO_BOX
2431
zoomComboBoxCbk(Widget widget,XtPointer ptr,XtPointer callData)2432 void XPDFViewer::zoomComboBoxCbk(Widget widget, XtPointer ptr,
2433 XtPointer callData) {
2434 XPDFViewer *viewer = (XPDFViewer *)ptr;
2435 XmComboBoxCallbackStruct *data = (XmComboBoxCallbackStruct *)callData;
2436 double z;
2437 char *s;
2438 XmStringContext context;
2439 XmStringCharSet charSet;
2440 XmStringDirection dir;
2441 Boolean sep;
2442
2443 z = viewer->core->getZoom();
2444 if (data->item_position == 0) {
2445 XmStringInitContext(&context, data->item_or_text);
2446 if (XmStringGetNextSegment(context, &s, &charSet, &dir, &sep)) {
2447 z = atof(s);
2448 if (z <= 1) {
2449 z = defZoom;
2450 }
2451 XtFree(charSet);
2452 XtFree(s);
2453 }
2454 XmStringFreeContext(context);
2455 } else {
2456 z = zoomMenuInfo[data->item_position - 1].zoom;
2457 }
2458 // only redraw if this was triggered by an event; otherwise
2459 // the caller is responsible for doing the redraw
2460 if (z != viewer->core->getZoom() && data->event) {
2461 viewer->displayPage(viewer->core->getPageNum(), z,
2462 viewer->core->getRotate(), gTrue, gFalse);
2463 }
2464 viewer->core->takeFocus();
2465 }
2466
2467 #else // USE_COMBO_BOX
2468
zoomMenuCbk(Widget widget,XtPointer ptr,XtPointer callData)2469 void XPDFViewer::zoomMenuCbk(Widget widget, XtPointer ptr,
2470 XtPointer callData) {
2471 XPDFViewer *viewer = (XPDFViewer *)ptr;
2472 XmPushButtonCallbackStruct *data = (XmPushButtonCallbackStruct *)callData;
2473 XtPointer userData;
2474 double z;
2475
2476 XtVaGetValues(widget, XmNuserData, &userData, NULL);
2477 z = zoomMenuInfo[(long)userData].zoom;
2478 // only redraw if this was triggered by an event; otherwise
2479 // the caller is responsible for doing the redraw
2480 if (z != viewer->core->getZoom() && data->event) {
2481 viewer->displayPage(viewer->core->getPageNum(), z,
2482 viewer->core->getRotate(), gTrue, gFalse);
2483 }
2484 viewer->core->takeFocus();
2485 }
2486
2487 #endif // USE_COMBO_BOX
2488
findCbk(Widget widget,XtPointer ptr,XtPointer callData)2489 void XPDFViewer::findCbk(Widget widget, XtPointer ptr,
2490 XtPointer callData) {
2491 XPDFViewer *viewer = (XPDFViewer *)ptr;
2492
2493 if (!viewer->core->getDoc()) {
2494 return;
2495 }
2496 viewer->mapFindDialog();
2497 }
2498
printCbk(Widget widget,XtPointer ptr,XtPointer callData)2499 void XPDFViewer::printCbk(Widget widget, XtPointer ptr,
2500 XtPointer callData) {
2501 XPDFViewer *viewer = (XPDFViewer *)ptr;
2502
2503 if (!viewer->core->getDoc()) {
2504 return;
2505 }
2506 XtManageChild(viewer->printDialog);
2507 }
2508
aboutCbk(Widget widget,XtPointer ptr,XtPointer callData)2509 void XPDFViewer::aboutCbk(Widget widget, XtPointer ptr,
2510 XtPointer callData) {
2511 XPDFViewer *viewer = (XPDFViewer *)ptr;
2512
2513 XtManageChild(viewer->aboutDialog);
2514 }
2515
quitCbk(Widget widget,XtPointer ptr,XtPointer callData)2516 void XPDFViewer::quitCbk(Widget widget, XtPointer ptr,
2517 XtPointer callData) {
2518 XPDFViewer *viewer = (XPDFViewer *)ptr;
2519
2520 viewer->app->quit();
2521 }
2522
openCbk(Widget widget,XtPointer ptr,XtPointer callData)2523 void XPDFViewer::openCbk(Widget widget, XtPointer ptr,
2524 XtPointer callData) {
2525 XPDFViewer *viewer = (XPDFViewer *)ptr;
2526
2527 viewer->mapOpenDialog(gFalse);
2528 }
2529
openInNewWindowCbk(Widget widget,XtPointer ptr,XtPointer callData)2530 void XPDFViewer::openInNewWindowCbk(Widget widget, XtPointer ptr,
2531 XtPointer callData) {
2532 XPDFViewer *viewer = (XPDFViewer *)ptr;
2533
2534 viewer->mapOpenDialog(gTrue);
2535 }
2536
reloadCbk(Widget widget,XtPointer ptr,XtPointer callData)2537 void XPDFViewer::reloadCbk(Widget widget, XtPointer ptr,
2538 XtPointer callData) {
2539 XPDFViewer *viewer = (XPDFViewer *)ptr;
2540
2541 viewer->reloadFile();
2542 }
2543
saveAsCbk(Widget widget,XtPointer ptr,XtPointer callData)2544 void XPDFViewer::saveAsCbk(Widget widget, XtPointer ptr,
2545 XtPointer callData) {
2546 XPDFViewer *viewer = (XPDFViewer *)ptr;
2547
2548 if (!viewer->core->getDoc()) {
2549 return;
2550 }
2551 viewer->mapSaveAsDialog();
2552 }
2553
continuousModeToggleCbk(Widget widget,XtPointer ptr,XtPointer callData)2554 void XPDFViewer::continuousModeToggleCbk(Widget widget, XtPointer ptr,
2555 XtPointer callData) {
2556 XPDFViewer *viewer = (XPDFViewer *)ptr;
2557 XmToggleButtonCallbackStruct *data =
2558 (XmToggleButtonCallbackStruct *)callData;
2559
2560 viewer->core->setContinuousMode(data->set == XmSET);
2561 }
2562
fullScreenToggleCbk(Widget widget,XtPointer ptr,XtPointer callData)2563 void XPDFViewer::fullScreenToggleCbk(Widget widget, XtPointer ptr,
2564 XtPointer callData) {
2565 XPDFViewer *viewer = (XPDFViewer *)ptr;
2566 XmToggleButtonCallbackStruct *data =
2567 (XmToggleButtonCallbackStruct *)callData;
2568
2569 if (data->set == XmSET) {
2570 viewer->cmdFullScreenMode(NULL, 0, NULL);
2571 } else {
2572 viewer->cmdWindowMode(NULL, 0, NULL);
2573 }
2574 }
2575
rotateCCWCbk(Widget widget,XtPointer ptr,XtPointer callData)2576 void XPDFViewer::rotateCCWCbk(Widget widget, XtPointer ptr,
2577 XtPointer callData) {
2578 XPDFViewer *viewer = (XPDFViewer *)ptr;
2579
2580 viewer->cmdRotateCCW(NULL, 0, NULL);
2581 }
2582
rotateCWCbk(Widget widget,XtPointer ptr,XtPointer callData)2583 void XPDFViewer::rotateCWCbk(Widget widget, XtPointer ptr,
2584 XtPointer callData) {
2585 XPDFViewer *viewer = (XPDFViewer *)ptr;
2586
2587 viewer->cmdRotateCW(NULL, 0, NULL);
2588 }
2589
zoomToSelectionCbk(Widget widget,XtPointer ptr,XtPointer callData)2590 void XPDFViewer::zoomToSelectionCbk(Widget widget, XtPointer ptr,
2591 XtPointer callData) {
2592 XPDFViewer *viewer = (XPDFViewer *)ptr;
2593 int pg;
2594 double ulx, uly, lrx, lry;
2595
2596 if (viewer->core->getSelection(&pg, &ulx, &uly, &lrx, &lry)) {
2597 viewer->core->zoomToRect(pg, ulx, uly, lrx, lry);
2598 }
2599 }
2600
closeCbk(Widget widget,XtPointer ptr,XtPointer callData)2601 void XPDFViewer::closeCbk(Widget widget, XtPointer ptr,
2602 XtPointer callData) {
2603 XPDFViewer *viewer = (XPDFViewer *)ptr;
2604
2605 viewer->app->close(viewer, gFalse);
2606 }
2607
closeMsgCbk(Widget widget,XtPointer ptr,XtPointer callData)2608 void XPDFViewer::closeMsgCbk(Widget widget, XtPointer ptr,
2609 XtPointer callData) {
2610 XPDFViewer *viewer = (XPDFViewer *)ptr;
2611
2612 viewer->app->close(viewer, gTrue);
2613 }
2614
pageNumCbk(Widget widget,XtPointer ptr,XtPointer callData)2615 void XPDFViewer::pageNumCbk(Widget widget, XtPointer ptr,
2616 XtPointer callData) {
2617 XPDFViewer *viewer = (XPDFViewer *)ptr;
2618 char *s, *p;
2619 int pg;
2620 char buf[20];
2621
2622 if (!viewer->core->getDoc()) {
2623 goto err;
2624 }
2625 s = XmTextFieldGetString(viewer->pageNumText);
2626 for (p = s; *p; ++p) {
2627 if (!isdigit(*p)) {
2628 goto err;
2629 }
2630 }
2631 pg = atoi(s);
2632 if (pg < 1 || pg > viewer->core->getDoc()->getNumPages()) {
2633 goto err;
2634 }
2635 viewer->displayPage(pg, viewer->core->getZoom(),
2636 viewer->core->getRotate(), gFalse, gTrue);
2637 viewer->core->takeFocus();
2638 return;
2639
2640 err:
2641 XBell(viewer->display, 0);
2642 sprintf(buf, "%d", viewer->core->getPageNum());
2643 XmTextFieldSetString(viewer->pageNumText, buf);
2644 }
2645
updateCbk(void * data,GString * fileName,int pageNum,int numPages,const char * linkString)2646 void XPDFViewer::updateCbk(void *data, GString *fileName,
2647 int pageNum, int numPages, const char *linkString) {
2648 XPDFViewer *viewer = (XPDFViewer *)data;
2649 GString *title;
2650 char buf[20];
2651 XmString s;
2652
2653 if (fileName) {
2654 if (!(title = viewer->app->getTitle())) {
2655 title = (new GString(xpdfAppName))->append(": ")->append(fileName);
2656 }
2657 XtVaSetValues(viewer->win, XmNtitle, title->getCString(),
2658 XmNiconName, title->getCString(), NULL);
2659 if (!viewer->app->getTitle()) {
2660 delete title;
2661 }
2662 #ifndef DISABLE_OUTLINE
2663 viewer->setupOutline();
2664 #endif
2665 viewer->setupPrintDialog();
2666 }
2667
2668 if (viewer->toolBar != None) {
2669 if (pageNum >= 0) {
2670 s = XmStringCreateLocalized("");
2671 XtVaSetValues(viewer->linkLabel, XmNlabelString, s, NULL);
2672 XmStringFree(s);
2673 sprintf(buf, "%d", pageNum);
2674 XmTextFieldSetString(viewer->pageNumText, buf);
2675 XtVaSetValues(viewer->prevTenPageBtn, XmNsensitive,
2676 pageNum > 1, NULL);
2677 XtVaSetValues(viewer->prevPageBtn, XmNsensitive,
2678 pageNum > 1, NULL);
2679 XtVaSetValues(viewer->nextTenPageBtn, XmNsensitive,
2680 pageNum < viewer->core->getDoc()->getNumPages(), NULL);
2681 XtVaSetValues(viewer->nextPageBtn, XmNsensitive,
2682 pageNum < viewer->core->getDoc()->getNumPages(), NULL);
2683 XtVaSetValues(viewer->backBtn, XmNsensitive,
2684 viewer->core->canGoBack(), NULL);
2685 XtVaSetValues(viewer->forwardBtn, XmNsensitive,
2686 viewer->core->canGoForward(), NULL);
2687 }
2688
2689 if (numPages >= 0) {
2690 sprintf(buf, " of %d", numPages);
2691 s = XmStringCreateLocalized(buf);
2692 XtVaSetValues(viewer->pageCountLabel, XmNlabelString, s, NULL);
2693 XmStringFree(s);
2694 }
2695
2696 if (linkString) {
2697 s = XmStringCreateLocalized((char *)linkString);
2698 XtVaSetValues(viewer->linkLabel, XmNlabelString, s, NULL);
2699 XmStringFree(s);
2700 }
2701 }
2702 }
2703
2704 //------------------------------------------------------------------------
2705 // GUI code: outline
2706 //------------------------------------------------------------------------
2707
2708 #ifndef DISABLE_OUTLINE
2709
setupOutline()2710 void XPDFViewer::setupOutline() {
2711 GList *items;
2712 UnicodeMap *uMap;
2713 GString *enc;
2714 int i;
2715
2716 if (outlineScroll == None) {
2717 return;
2718 }
2719
2720 // unmanage and destroy the old labels
2721 if (outlineLabels) {
2722 XtUnmanageChildren(outlineLabels, outlineLabelsLength);
2723 for (i = 0; i < outlineLabelsLength; ++i) {
2724 XtDestroyWidget(outlineLabels[i]);
2725 }
2726 gfree(outlineLabels);
2727 outlineLabels = NULL;
2728 outlineLabelsLength = outlineLabelsSize = 0;
2729 }
2730
2731 if (core->getDoc()) {
2732
2733 // create the new labels
2734 items = core->getDoc()->getOutline()->getItems();
2735 if (items && items->getLength() > 0) {
2736 enc = new GString("Latin1");
2737 uMap = globalParams->getUnicodeMap(enc);
2738 delete enc;
2739 setupOutlineItems(items, NULL, uMap);
2740 uMap->decRefCnt();
2741 }
2742
2743 // manage the new labels
2744 XtManageChildren(outlineLabels, outlineLabelsLength);
2745 }
2746 }
2747
setupOutlineItems(GList * items,Widget parent,UnicodeMap * uMap)2748 void XPDFViewer::setupOutlineItems(GList *items, Widget parent,
2749 UnicodeMap *uMap) {
2750 OutlineItem *item;
2751 GList *kids;
2752 Widget label;
2753 Arg args[20];
2754 GString *title;
2755 char buf[8];
2756 XmString s;
2757 int i, j, n;
2758
2759 for (i = 0; i < items->getLength(); ++i) {
2760 item = (OutlineItem *)items->get(i);
2761 title = new GString();
2762 for (j = 0; j < item->getTitleLength(); ++j) {
2763 n = uMap->mapUnicode(item->getTitle()[j], buf, sizeof(buf));
2764 title->append(buf, n);
2765 }
2766 n = 0;
2767 XtSetArg(args[n], XPDFNentryPosition, i); ++n;
2768 if (parent) {
2769 XtSetArg(args[n], XPDFNentryParent, parent); ++n;
2770 }
2771 XtSetArg(args[n], XPDFNentryExpanded, item->isOpen()); ++n;
2772 s = XmStringCreateLocalized(title->getCString());
2773 delete title;
2774 XtSetArg(args[n], XmNlabelString, s); ++n;
2775 XtSetArg(args[n], XmNuserData, item); ++n;
2776 XtSetArg(args[n], XmNmarginWidth, 0); ++n;
2777 XtSetArg(args[n], XmNmarginHeight, 2); ++n;
2778 XtSetArg(args[n], XmNshadowThickness, 0); ++n;
2779 XtSetArg(args[n], XmNforeground,
2780 app->getReverseVideo() ? WhitePixel(display, screenNum)
2781 : BlackPixel(display, screenNum)); ++n;
2782 XtSetArg(args[n], XmNbackground, app->getPaperPixel()); ++n;
2783 label = XmCreateLabelGadget(outlineTree, "label", args, n);
2784 XmStringFree(s);
2785 if (outlineLabelsLength == outlineLabelsSize) {
2786 outlineLabelsSize += 64;
2787 outlineLabels = (Widget *)greallocn(outlineLabels,
2788 outlineLabelsSize, sizeof(Widget *));
2789 }
2790 outlineLabels[outlineLabelsLength++] = label;
2791 item->open();
2792 if ((kids = item->getKids())) {
2793 setupOutlineItems(kids, label, uMap);
2794 }
2795 }
2796 }
2797
outlineSelectCbk(Widget widget,XtPointer ptr,XtPointer callData)2798 void XPDFViewer::outlineSelectCbk(Widget widget, XtPointer ptr,
2799 XtPointer callData) {
2800 XPDFViewer *viewer = (XPDFViewer *)ptr;
2801 XPDFTreeSelectCallbackStruct *data =
2802 (XPDFTreeSelectCallbackStruct *)callData;
2803 OutlineItem *item;
2804
2805 XtVaGetValues(data->selectedItem, XmNuserData, &item, NULL);
2806 if (item) {
2807 if (item->getAction()) {
2808 viewer->core->doAction(item->getAction());
2809 }
2810 }
2811 viewer->core->takeFocus();
2812 }
2813
2814 #endif // !DISABLE_OUTLINE
2815
2816 //------------------------------------------------------------------------
2817 // GUI code: "about" dialog
2818 //------------------------------------------------------------------------
2819
initAboutDialog()2820 void XPDFViewer::initAboutDialog() {
2821 Widget scrolledWin, col, label, sep, closeBtn;
2822 Arg args[20];
2823 int n, i;
2824 XmString s;
2825 char buf[20];
2826
2827 //----- dialog
2828 n = 0;
2829 s = XmStringCreateLocalized(xpdfAppName ": About");
2830 XtSetArg(args[n], XmNdialogTitle, s); ++n;
2831 XtSetArg(args[n], XmNwidth, 450); ++n;
2832 XtSetArg(args[n], XmNheight, 300); ++n;
2833 aboutDialog = XmCreateFormDialog(win, "aboutDialog", args, n);
2834 XmStringFree(s);
2835
2836 //----- "close" button
2837 n = 0;
2838 XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
2839 XtSetArg(args[n], XmNrightOffset, 4); ++n;
2840 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
2841 XtSetArg(args[n], XmNbottomOffset, 4); ++n;
2842 closeBtn = XmCreatePushButton(aboutDialog, "Close", args, n);
2843 XtManageChild(closeBtn);
2844 n = 0;
2845 XtSetArg(args[n], XmNdefaultButton, closeBtn); ++n;
2846 XtSetArg(args[n], XmNcancelButton, closeBtn); ++n;
2847 XtSetValues(aboutDialog, args, n);
2848
2849 //----- scrolled window and RowColumn
2850 n = 0;
2851 XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
2852 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); ++n;
2853 XtSetArg(args[n], XmNbottomWidget, closeBtn); ++n;
2854 XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
2855 XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
2856 XtSetArg(args[n], XmNscrollingPolicy, XmAUTOMATIC); ++n;
2857 scrolledWin = XmCreateScrolledWindow(aboutDialog, "scrolledWin", args, n);
2858 XtManageChild(scrolledWin);
2859 n = 0;
2860 XtSetArg(args[n], XmNorientation, XmVERTICAL); ++n;
2861 XtSetArg(args[n], XmNpacking, XmPACK_TIGHT); ++n;
2862 col = XmCreateRowColumn(scrolledWin, "col", args, n);
2863 XtManageChild(col);
2864
2865 //----- fonts
2866 aboutBigFont =
2867 createFontList("-*-times-bold-i-normal--20-*-*-*-*-*-iso8859-1");
2868 aboutVersionFont =
2869 createFontList("-*-times-medium-r-normal--16-*-*-*-*-*-iso8859-1");
2870 aboutFixedFont =
2871 createFontList("-*-courier-medium-r-normal--12-*-*-*-*-*-iso8859-1");
2872
2873 //----- heading
2874 n = 0;
2875 s = XmStringCreateLocalized("Xpdf");
2876 XtSetArg(args[n], XmNlabelString, s); ++n;
2877 XtSetArg(args[n], XmNfontList, aboutBigFont); ++n;
2878 label = XmCreateLabel(col, "h0", args, n);
2879 XmStringFree(s);
2880 XtManageChild(label);
2881 n = 0;
2882 s = XmStringCreateLocalized("Version " xpdfVersion);
2883 XtSetArg(args[n], XmNlabelString, s); ++n;
2884 XtSetArg(args[n], XmNfontList, aboutVersionFont); ++n;
2885 label = XmCreateLabel(col, "h1", args, n);
2886 XmStringFree(s);
2887 XtManageChild(label);
2888 n = 0;
2889 s = XmStringCreateLocalized(xpdfCopyright);
2890 XtSetArg(args[n], XmNlabelString, s); ++n;
2891 XtSetArg(args[n], XmNfontList, aboutVersionFont); ++n;
2892 label = XmCreateLabel(col, "h2", args, n);
2893 XmStringFree(s);
2894 XtManageChild(label);
2895 n = 0;
2896 s = XmStringCreateLocalized(" ");
2897 XtSetArg(args[n], XmNlabelString, s); ++n;
2898 XtSetArg(args[n], XmNfontList, aboutVersionFont); ++n;
2899 label = XmCreateLabel(col, "h3", args, n);
2900 XmStringFree(s);
2901 XtManageChild(label);
2902 n = 0;
2903 XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
2904 sep = XmCreateSeparator(col, "sep", args, n);
2905 XtManageChild(sep);
2906 n = 0;
2907 s = XmStringCreateLocalized(" ");
2908 XtSetArg(args[n], XmNlabelString, s); ++n;
2909 XtSetArg(args[n], XmNfontList, aboutVersionFont); ++n;
2910 label = XmCreateLabel(col, "h4", args, n);
2911 XmStringFree(s);
2912 XtManageChild(label);
2913 n = 0;
2914
2915 //----- text
2916 for (i = 0; aboutWinText[i]; ++i) {
2917 n = 0;
2918 s = XmStringCreateLocalized((char *)aboutWinText[i]);
2919 XtSetArg(args[n], XmNlabelString, s); ++n;
2920 XtSetArg(args[n], XmNfontList, aboutFixedFont); ++n;
2921 sprintf(buf, "t%d", i);
2922 label = XmCreateLabel(col, buf, args, n);
2923 XtManageChild(label);
2924 XmStringFree(s);
2925 }
2926 }
2927
2928 //------------------------------------------------------------------------
2929 // GUI code: "open" dialog
2930 //------------------------------------------------------------------------
2931
initOpenDialog()2932 void XPDFViewer::initOpenDialog() {
2933 Arg args[20];
2934 int n;
2935 XmString s1, s2, s3;
2936 GString *dir;
2937
2938 n = 0;
2939 s1 = XmStringCreateLocalized("Open");
2940 XtSetArg(args[n], XmNokLabelString, s1); ++n;
2941 s2 = XmStringCreateLocalized("*.[Pp][Dd][Ff]");
2942 XtSetArg(args[n], XmNpattern, s2); ++n;
2943 s3 = XmStringCreateLocalized(xpdfAppName ": Open");
2944 XtSetArg(args[n], XmNdialogTitle, s3); ++n;
2945 XtSetArg(args[n], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); ++n;
2946 XtSetArg(args[n], XmNautoUnmanage, True); ++n;
2947 openDialog = XmCreateFileSelectionDialog(win, "openDialog", args, n);
2948 XmStringFree(s1);
2949 XmStringFree(s2);
2950 XmStringFree(s3);
2951 XtUnmanageChild(XmFileSelectionBoxGetChild(openDialog,
2952 XmDIALOG_HELP_BUTTON));
2953 XtAddCallback(openDialog, XmNokCallback,
2954 &openOkCbk, (XtPointer)this);
2955
2956 if (core->getDoc() && core->getDoc()->getFileName()) {
2957 dir = makePathAbsolute(grabPath(
2958 core->getDoc()->getFileName()->getCString()));
2959 s1 = XmStringCreateLocalized(dir->getCString());
2960 XtVaSetValues(openDialog, XmNdirectory, s1, NULL);
2961 XmStringFree(s1);
2962 delete dir;
2963 }
2964 }
2965
mapOpenDialog(GBool openInNewWindowA)2966 void XPDFViewer::mapOpenDialog(GBool openInNewWindowA) {
2967 if (!openDialog) {
2968 initOpenDialog();
2969 }
2970 openInNewWindow = openInNewWindowA;
2971 XmFileSelectionDoSearch(openDialog, NULL);
2972 XtManageChild(openDialog);
2973 }
2974
openOkCbk(Widget widget,XtPointer ptr,XtPointer callData)2975 void XPDFViewer::openOkCbk(Widget widget, XtPointer ptr,
2976 XtPointer callData) {
2977 XPDFViewer *viewer = (XPDFViewer *)ptr;
2978 XmFileSelectionBoxCallbackStruct *data =
2979 (XmFileSelectionBoxCallbackStruct *)callData;
2980 char *fileName;
2981 XmStringContext context;
2982 XmStringCharSet charSet;
2983 XmStringDirection dir;
2984 Boolean sep;
2985 GString *fileNameStr;
2986
2987 XmStringInitContext(&context, data->value);
2988 if (XmStringGetNextSegment(context, &fileName, &charSet, &dir, &sep)) {
2989 fileNameStr = new GString(fileName);
2990 if (viewer->openInNewWindow) {
2991 viewer->app->open(fileNameStr);
2992 } else {
2993 if (viewer->loadFile(fileNameStr)) {
2994 viewer->displayPage(1, viewer->core->getZoom(),
2995 viewer->core->getRotate(), gTrue, gTrue);
2996 }
2997 }
2998 delete fileNameStr;
2999 XtFree(charSet);
3000 XtFree(fileName);
3001 }
3002 XmStringFreeContext(context);
3003 }
3004
3005 //------------------------------------------------------------------------
3006 // GUI code: "find" dialog
3007 //------------------------------------------------------------------------
3008
initFindDialog()3009 void XPDFViewer::initFindDialog() {
3010 Widget form1, label, okBtn, closeBtn;
3011 Arg args[20];
3012 int n;
3013 XmString s;
3014
3015 //----- dialog
3016 n = 0;
3017 s = XmStringCreateLocalized(xpdfAppName ": Find");
3018 XtSetArg(args[n], XmNdialogTitle, s); ++n;
3019 XtSetArg(args[n], XmNnavigationType, XmNONE); ++n;
3020 XtSetArg(args[n], XmNautoUnmanage, False); ++n;
3021 findDialog = XmCreateFormDialog(win, "findDialog", args, n);
3022 XmStringFree(s);
3023
3024 //----- "find" and "close" buttons
3025 n = 0;
3026 XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
3027 XtSetArg(args[n], XmNleftOffset, 4); ++n;
3028 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
3029 XtSetArg(args[n], XmNbottomOffset, 4); ++n;
3030 XtSetArg(args[n], XmNnavigationType, XmEXCLUSIVE_TAB_GROUP); ++n;
3031 okBtn = XmCreatePushButton(findDialog, "Find", args, n);
3032 XtManageChild(okBtn);
3033 XtAddCallback(okBtn, XmNactivateCallback,
3034 &findFindCbk, (XtPointer)this);
3035 n = 0;
3036 XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
3037 XtSetArg(args[n], XmNrightOffset, 4); ++n;
3038 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
3039 XtSetArg(args[n], XmNbottomOffset, 4); ++n;
3040 XtSetArg(args[n], XmNnavigationType, XmEXCLUSIVE_TAB_GROUP); ++n;
3041 closeBtn = XmCreatePushButton(findDialog, "Close", args, n);
3042 XtManageChild(closeBtn);
3043 XtAddCallback(closeBtn, XmNactivateCallback,
3044 &findCloseCbk, (XtPointer)this);
3045
3046 //----- checkboxes
3047 n = 0;
3048 XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
3049 XtSetArg(args[n], XmNleftOffset, 4); ++n;
3050 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); ++n;
3051 XtSetArg(args[n], XmNbottomWidget, okBtn); ++n;
3052 XtSetArg(args[n], XmNindicatorType, XmN_OF_MANY); ++n;
3053 #if XmVERSION <= 1
3054 XtSetArg(args[n], XmNindicatorOn, True); ++n;
3055 #else
3056 XtSetArg(args[n], XmNindicatorOn, XmINDICATOR_FILL); ++n;
3057 #endif
3058 XtSetArg(args[n], XmNset, XmUNSET); ++n;
3059 s = XmStringCreateLocalized("Search backward");
3060 XtSetArg(args[n], XmNlabelString, s); ++n;
3061 findBackwardToggle = XmCreateToggleButton(findDialog, "backward", args, n);
3062 XmStringFree(s);
3063 XtManageChild(findBackwardToggle);
3064 n = 0;
3065 XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
3066 XtSetArg(args[n], XmNleftWidget, findBackwardToggle); ++n;
3067 XtSetArg(args[n], XmNleftOffset, 16); ++n;
3068 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); ++n;
3069 XtSetArg(args[n], XmNbottomWidget, okBtn); ++n;
3070 XtSetArg(args[n], XmNindicatorType, XmN_OF_MANY); ++n;
3071 #if XmVERSION <= 1
3072 XtSetArg(args[n], XmNindicatorOn, True); ++n;
3073 #else
3074 XtSetArg(args[n], XmNindicatorOn, XmINDICATOR_FILL); ++n;
3075 #endif
3076 XtSetArg(args[n], XmNset, XmUNSET); ++n;
3077 s = XmStringCreateLocalized("Match case");
3078 XtSetArg(args[n], XmNlabelString, s); ++n;
3079 findCaseSensitiveToggle =
3080 XmCreateToggleButton(findDialog, "matchCase", args, n);
3081 XmStringFree(s);
3082 XtManageChild(findCaseSensitiveToggle);
3083 n = 0;
3084 XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
3085 XtSetArg(args[n], XmNleftWidget, findCaseSensitiveToggle); ++n;
3086 XtSetArg(args[n], XmNleftOffset, 16); ++n;
3087 XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
3088 XtSetArg(args[n], XmNrightOffset, 4); ++n;
3089 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); ++n;
3090 XtSetArg(args[n], XmNbottomWidget, okBtn); ++n;
3091 XtSetArg(args[n], XmNindicatorType, XmN_OF_MANY); ++n;
3092 #if XmVERSION <= 1
3093 XtSetArg(args[n], XmNindicatorOn, True); ++n;
3094 #else
3095 XtSetArg(args[n], XmNindicatorOn, XmINDICATOR_FILL); ++n;
3096 #endif
3097 XtSetArg(args[n], XmNset, XmUNSET); ++n;
3098 s = XmStringCreateLocalized("Whole words only");
3099 XtSetArg(args[n], XmNlabelString, s); ++n;
3100 findWholeWordToggle = XmCreateToggleButton(findDialog, "wholeWord", args, n);
3101 XmStringFree(s);
3102 XtManageChild(findWholeWordToggle);
3103
3104 //----- search string entry
3105 n = 0;
3106 XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
3107 XtSetArg(args[n], XmNtopOffset, 4); ++n;
3108 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); ++n;
3109 XtSetArg(args[n], XmNbottomWidget, findBackwardToggle); ++n;
3110 XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
3111 XtSetArg(args[n], XmNleftOffset, 2); ++n;
3112 XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
3113 XtSetArg(args[n], XmNrightOffset, 2); ++n;
3114 form1 = XmCreateForm(findDialog, "form", args, n);
3115 XtManageChild(form1);
3116 n = 0;
3117 XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
3118 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
3119 XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
3120 s = XmStringCreateLocalized("Find text: ");
3121 XtSetArg(args[n], XmNlabelString, s); ++n;
3122 label = XmCreateLabel(form1, "label", args, n);
3123 XmStringFree(s);
3124 XtManageChild(label);
3125 n = 0;
3126 XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
3127 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
3128 XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
3129 XtSetArg(args[n], XmNleftWidget, label); ++n;
3130 XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
3131 findText = XmCreateTextField(form1, "text", args, n);
3132 XtManageChild(findText);
3133 #ifdef LESSTIF_VERSION
3134 XtAddCallback(findText, XmNactivateCallback,
3135 &findFindCbk, (XtPointer)this);
3136 #endif
3137
3138 //----- dialog parameters
3139 n = 0;
3140 XtSetArg(args[n], XmNdefaultButton, okBtn); ++n;
3141 XtSetArg(args[n], XmNcancelButton, closeBtn); ++n;
3142 #if XmVersion > 1001
3143 XtSetArg(args[n], XmNinitialFocus, findText); ++n;
3144 #endif
3145 XtSetValues(findDialog, args, n);
3146 }
3147
findFindCbk(Widget widget,XtPointer ptr,XtPointer callData)3148 void XPDFViewer::findFindCbk(Widget widget, XtPointer ptr,
3149 XtPointer callData) {
3150 XPDFViewer *viewer = (XPDFViewer *)ptr;
3151
3152 viewer->doFind(gFalse);
3153 }
3154
mapFindDialog()3155 void XPDFViewer::mapFindDialog() {
3156 XmTextFieldSetSelection(findText, 0, XmTextFieldGetLastPosition(findText),
3157 XtLastTimestampProcessed(display));
3158 XmTextFieldSetInsertionPosition(findText, 0);
3159 XtManageChild(findDialog);
3160 }
3161
doFind(GBool next)3162 void XPDFViewer::doFind(GBool next) {
3163 if (XtWindow(findDialog)) {
3164 XDefineCursor(display, XtWindow(findDialog), core->getBusyCursor());
3165 }
3166 core->find(XmTextFieldGetString(findText),
3167 XmToggleButtonGetState(findCaseSensitiveToggle),
3168 next,
3169 XmToggleButtonGetState(findBackwardToggle),
3170 XmToggleButtonGetState(findWholeWordToggle),
3171 gFalse);
3172 if (XtWindow(findDialog)) {
3173 XUndefineCursor(display, XtWindow(findDialog));
3174 }
3175 }
3176
findCloseCbk(Widget widget,XtPointer ptr,XtPointer callData)3177 void XPDFViewer::findCloseCbk(Widget widget, XtPointer ptr,
3178 XtPointer callData) {
3179 XPDFViewer *viewer = (XPDFViewer *)ptr;
3180
3181 XtUnmanageChild(viewer->findDialog);
3182 }
3183
3184 //------------------------------------------------------------------------
3185 // GUI code: "save as" dialog
3186 //------------------------------------------------------------------------
3187
initSaveAsDialog()3188 void XPDFViewer::initSaveAsDialog() {
3189 Arg args[20];
3190 int n;
3191 XmString s1, s2, s3;
3192 GString *dir;
3193
3194 n = 0;
3195 s1 = XmStringCreateLocalized("Save");
3196 XtSetArg(args[n], XmNokLabelString, s1); ++n;
3197 s2 = XmStringCreateLocalized("*.[Pp][Dd][Ff]");
3198 XtSetArg(args[n], XmNpattern, s2); ++n;
3199 s3 = XmStringCreateLocalized(xpdfAppName ": Save as");
3200 XtSetArg(args[n], XmNdialogTitle, s3); ++n;
3201 XtSetArg(args[n], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); ++n;
3202 XtSetArg(args[n], XmNautoUnmanage, True); ++n;
3203 saveAsDialog = XmCreateFileSelectionDialog(win, "saveAsDialog", args, n);
3204 XmStringFree(s1);
3205 XmStringFree(s2);
3206 XmStringFree(s3);
3207 XtUnmanageChild(XmFileSelectionBoxGetChild(saveAsDialog,
3208 XmDIALOG_HELP_BUTTON));
3209 XtAddCallback(saveAsDialog, XmNokCallback,
3210 &saveAsOkCbk, (XtPointer)this);
3211
3212 if (core->getDoc() && core->getDoc()->getFileName()) {
3213 dir = makePathAbsolute(grabPath(
3214 core->getDoc()->getFileName()->getCString()));
3215 s1 = XmStringCreateLocalized(dir->getCString());
3216 XtVaSetValues(saveAsDialog, XmNdirectory, s1, NULL);
3217 XmStringFree(s1);
3218 delete dir;
3219 }
3220 }
3221
mapSaveAsDialog()3222 void XPDFViewer::mapSaveAsDialog() {
3223 if (!saveAsDialog) {
3224 initSaveAsDialog();
3225 }
3226 XmFileSelectionDoSearch(saveAsDialog, NULL);
3227 XtManageChild(saveAsDialog);
3228 }
3229
saveAsOkCbk(Widget widget,XtPointer ptr,XtPointer callData)3230 void XPDFViewer::saveAsOkCbk(Widget widget, XtPointer ptr,
3231 XtPointer callData) {
3232 XPDFViewer *viewer = (XPDFViewer *)ptr;
3233 XmFileSelectionBoxCallbackStruct *data =
3234 (XmFileSelectionBoxCallbackStruct *)callData;
3235 char *fileName;
3236 GString *fileNameStr;
3237 XmStringContext context;
3238 XmStringCharSet charSet;
3239 XmStringDirection dir;
3240 Boolean sep;
3241
3242 XmStringInitContext(&context, data->value);
3243 if (XmStringGetNextSegment(context, &fileName, &charSet, &dir, &sep)) {
3244 fileNameStr = new GString(fileName);
3245 viewer->core->getDoc()->saveAs(fileNameStr);
3246 delete fileNameStr;
3247 XtFree(charSet);
3248 XtFree(fileName);
3249 }
3250 XmStringFreeContext(context);
3251 }
3252
3253 //------------------------------------------------------------------------
3254 // GUI code: "print" dialog
3255 //------------------------------------------------------------------------
3256
initPrintDialog()3257 void XPDFViewer::initPrintDialog() {
3258 Widget sep1, sep2, row, label1, label2, okBtn, cancelBtn;
3259 Arg args[20];
3260 int n;
3261 XmString s;
3262 GString *psFileName;
3263
3264 //----- dialog
3265 n = 0;
3266 s = XmStringCreateLocalized(xpdfAppName ": Print");
3267 XtSetArg(args[n], XmNdialogTitle, s); ++n;
3268 XtSetArg(args[n], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); ++n;
3269 printDialog = XmCreateFormDialog(win, "printDialog", args, n);
3270 XmStringFree(s);
3271
3272 //----- "print with command"
3273 n = 0;
3274 XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
3275 XtSetArg(args[n], XmNtopOffset, 4); ++n;
3276 XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
3277 XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); ++n;
3278 XtSetArg(args[n], XmNset, XmSET); ++n;
3279 s = XmStringCreateLocalized("Print with command:");
3280 XtSetArg(args[n], XmNlabelString, s); ++n;
3281 printWithCmdBtn = XmCreateToggleButton(printDialog, "printWithCmd", args, n);
3282 XmStringFree(s);
3283 XtManageChild(printWithCmdBtn);
3284 XtAddCallback(printWithCmdBtn, XmNvalueChangedCallback,
3285 &printWithCmdBtnCbk, (XtPointer)this);
3286 n = 0;
3287 XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
3288 XtSetArg(args[n], XmNtopWidget, printWithCmdBtn); ++n;
3289 XtSetArg(args[n], XmNtopOffset, 2); ++n;
3290 XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
3291 XtSetArg(args[n], XmNleftOffset, 16); ++n;
3292 XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
3293 XtSetArg(args[n], XmNrightOffset, 4); ++n;
3294 XtSetArg(args[n], XmNcolumns, 40); ++n;
3295 printCmdText = XmCreateTextField(printDialog, "printCmd", args, n);
3296 XtManageChild(printCmdText);
3297
3298 //----- "print to file"
3299 n = 0;
3300 XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
3301 XtSetArg(args[n], XmNtopWidget, printCmdText); ++n;
3302 XtSetArg(args[n], XmNtopOffset, 4); ++n;
3303 XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
3304 XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); ++n;
3305 XtSetArg(args[n], XmNset, XmUNSET); ++n;
3306 s = XmStringCreateLocalized("Print to file:");
3307 XtSetArg(args[n], XmNlabelString, s); ++n;
3308 printToFileBtn = XmCreateToggleButton(printDialog, "printToFile", args, n);
3309 XmStringFree(s);
3310 XtManageChild(printToFileBtn);
3311 XtAddCallback(printToFileBtn, XmNvalueChangedCallback,
3312 &printToFileBtnCbk, (XtPointer)this);
3313 n = 0;
3314 XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
3315 XtSetArg(args[n], XmNtopWidget, printToFileBtn); ++n;
3316 XtSetArg(args[n], XmNtopOffset, 2); ++n;
3317 XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
3318 XtSetArg(args[n], XmNleftOffset, 16); ++n;
3319 XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
3320 XtSetArg(args[n], XmNrightOffset, 4); ++n;
3321 XtSetArg(args[n], XmNcolumns, 40); ++n;
3322 XtSetArg(args[n], XmNsensitive, False); ++n;
3323 printFileText = XmCreateTextField(printDialog, "printFile", args, n);
3324 XtManageChild(printFileText);
3325
3326 //----- separator
3327 n = 0;
3328 XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
3329 XtSetArg(args[n], XmNtopWidget, printFileText); ++n;
3330 XtSetArg(args[n], XmNtopOffset, 8); ++n;
3331 XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
3332 XtSetArg(args[n], XmNleftOffset, 8); ++n;
3333 XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
3334 XtSetArg(args[n], XmNrightOffset, 8); ++n;
3335 XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
3336 sep1 = XmCreateSeparator(printDialog, "sep1", args, n);
3337 XtManageChild(sep1);
3338
3339 //----- page range
3340 n = 0;
3341 XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
3342 XtSetArg(args[n], XmNtopWidget, sep1); ++n;
3343 XtSetArg(args[n], XmNtopOffset, 8); ++n;
3344 XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
3345 XtSetArg(args[n], XmNleftOffset, 4); ++n;
3346 XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
3347 XtSetArg(args[n], XmNpacking, XmPACK_TIGHT); ++n;
3348 row = XmCreateRowColumn(printDialog, "row", args, n);
3349 XtManageChild(row);
3350 n = 0;
3351 s = XmStringCreateLocalized("Pages:");
3352 XtSetArg(args[n], XmNlabelString, s); ++n;
3353 label1 = XmCreateLabel(row, "label1", args, n);
3354 XmStringFree(s);
3355 XtManageChild(label1);
3356 n = 0;
3357 XtSetArg(args[n], XmNcolumns, 5); ++n;
3358 printFirstPage = XmCreateTextField(row, "printFirstPage", args, n);
3359 XtManageChild(printFirstPage);
3360 n = 0;
3361 s = XmStringCreateLocalized("to");
3362 XtSetArg(args[n], XmNlabelString, s); ++n;
3363 label2 = XmCreateLabel(row, "label2", args, n);
3364 XmStringFree(s);
3365 XtManageChild(label2);
3366 n = 0;
3367 XtSetArg(args[n], XmNcolumns, 5); ++n;
3368 printLastPage = XmCreateTextField(row, "printLastPage", args, n);
3369 XtManageChild(printLastPage);
3370
3371 //----- separator
3372 n = 0;
3373 XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
3374 XtSetArg(args[n], XmNtopWidget, row); ++n;
3375 XtSetArg(args[n], XmNtopOffset, 8); ++n;
3376 XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
3377 XtSetArg(args[n], XmNleftOffset, 8); ++n;
3378 XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
3379 XtSetArg(args[n], XmNrightOffset, 8); ++n;
3380 XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
3381 sep2 = XmCreateSeparator(printDialog, "sep2", args, n);
3382 XtManageChild(sep2);
3383
3384 //----- "print" and "cancel" buttons
3385 n = 0;
3386 XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
3387 XtSetArg(args[n], XmNtopWidget, sep2); ++n;
3388 XtSetArg(args[n], XmNtopOffset, 8); ++n;
3389 XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
3390 XtSetArg(args[n], XmNleftOffset, 4); ++n;
3391 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
3392 XtSetArg(args[n], XmNbottomOffset, 4); ++n;
3393 okBtn = XmCreatePushButton(printDialog, "Print", args, n);
3394 XtManageChild(okBtn);
3395 XtAddCallback(okBtn, XmNactivateCallback,
3396 &printPrintCbk, (XtPointer)this);
3397 n = 0;
3398 XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
3399 XtSetArg(args[n], XmNtopWidget, sep2); ++n;
3400 XtSetArg(args[n], XmNtopOffset, 8); ++n;
3401 XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
3402 XtSetArg(args[n], XmNrightOffset, 4); ++n;
3403 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
3404 XtSetArg(args[n], XmNbottomOffset, 4); ++n;
3405 cancelBtn = XmCreatePushButton(printDialog, "Cancel", args, n);
3406 XtManageChild(cancelBtn);
3407 n = 0;
3408 XtSetArg(args[n], XmNdefaultButton, okBtn); ++n;
3409 XtSetArg(args[n], XmNcancelButton, cancelBtn); ++n;
3410 XtSetValues(printDialog, args, n);
3411
3412 //----- initial values
3413 if ((psFileName = globalParams->getPSFile())) {
3414 if (psFileName->getChar(0) == '|') {
3415 XmTextFieldSetString(printCmdText,
3416 psFileName->getCString() + 1);
3417 } else {
3418 XmTextFieldSetString(printFileText, psFileName->getCString());
3419 }
3420 delete psFileName;
3421 }
3422 }
3423
setupPrintDialog()3424 void XPDFViewer::setupPrintDialog() {
3425 PDFDoc *doc;
3426 char buf[20];
3427 GString *pdfFileName, *psFileName, *psFileName2;
3428 char *p;
3429
3430 doc = core->getDoc();
3431 psFileName = globalParams->getPSFile();
3432 if (!psFileName || psFileName->getChar(0) == '|') {
3433 if ((pdfFileName = doc->getFileName())) {
3434 p = pdfFileName->getCString() + pdfFileName->getLength() - 4;
3435 if (!strcmp(p, ".pdf") || !strcmp(p, ".PDF")) {
3436 psFileName2 = new GString(pdfFileName->getCString(),
3437 pdfFileName->getLength() - 4);
3438 } else {
3439 psFileName2 = pdfFileName->copy();
3440 }
3441 psFileName2->append(".ps");
3442 XmTextFieldSetString(printFileText, psFileName2->getCString());
3443 delete psFileName2;
3444 }
3445 }
3446 if (psFileName && psFileName->getChar(0) == '|') {
3447 XmToggleButtonSetState(printWithCmdBtn, True, False);
3448 XmToggleButtonSetState(printToFileBtn, False, False);
3449 XtVaSetValues(printCmdText, XmNsensitive, True, NULL);
3450 XtVaSetValues(printFileText, XmNsensitive, False, NULL);
3451 } else {
3452 XmToggleButtonSetState(printWithCmdBtn, False, False);
3453 XmToggleButtonSetState(printToFileBtn, True, False);
3454 XtVaSetValues(printCmdText, XmNsensitive, False, NULL);
3455 XtVaSetValues(printFileText, XmNsensitive, True, NULL);
3456 }
3457 if (psFileName) {
3458 delete psFileName;
3459 }
3460
3461 sprintf(buf, "%d", doc->getNumPages());
3462 XmTextFieldSetString(printFirstPage, "1");
3463 XmTextFieldSetString(printLastPage, buf);
3464 }
3465
printWithCmdBtnCbk(Widget widget,XtPointer ptr,XtPointer callData)3466 void XPDFViewer::printWithCmdBtnCbk(Widget widget, XtPointer ptr,
3467 XtPointer callData) {
3468 XPDFViewer *viewer = (XPDFViewer *)ptr;
3469 XmToggleButtonCallbackStruct *data =
3470 (XmToggleButtonCallbackStruct *)callData;
3471
3472 if (data->set != XmSET) {
3473 XmToggleButtonSetState(viewer->printWithCmdBtn, True, False);
3474 }
3475 XmToggleButtonSetState(viewer->printToFileBtn, False, False);
3476 XtVaSetValues(viewer->printCmdText, XmNsensitive, True, NULL);
3477 XtVaSetValues(viewer->printFileText, XmNsensitive, False, NULL);
3478 }
3479
printToFileBtnCbk(Widget widget,XtPointer ptr,XtPointer callData)3480 void XPDFViewer::printToFileBtnCbk(Widget widget, XtPointer ptr,
3481 XtPointer callData) {
3482 XPDFViewer *viewer = (XPDFViewer *)ptr;
3483 XmToggleButtonCallbackStruct *data =
3484 (XmToggleButtonCallbackStruct *)callData;
3485
3486 if (data->set != XmSET) {
3487 XmToggleButtonSetState(viewer->printToFileBtn, True, False);
3488 }
3489 XmToggleButtonSetState(viewer->printWithCmdBtn, False, False);
3490 XtVaSetValues(viewer->printFileText, XmNsensitive, True, NULL);
3491 XtVaSetValues(viewer->printCmdText, XmNsensitive, False, NULL);
3492 }
3493
printPrintCbk(Widget widget,XtPointer ptr,XtPointer callData)3494 void XPDFViewer::printPrintCbk(Widget widget, XtPointer ptr,
3495 XtPointer callData) {
3496 XPDFViewer *viewer = (XPDFViewer *)ptr;
3497 unsigned char withCmd;
3498 GString *psFileName;
3499 int firstPage, lastPage;
3500 PDFDoc *doc;
3501 PSOutputDev *psOut;
3502
3503 doc = viewer->core->getDoc();
3504 if (!doc->okToPrint()) {
3505 error(errNotAllowed, -1, "Printing this document is not allowed.");
3506 return;
3507 }
3508
3509 viewer->core->setBusyCursor(gTrue);
3510
3511 XtVaGetValues(viewer->printWithCmdBtn, XmNset, &withCmd, NULL);
3512 if (withCmd) {
3513 psFileName = new GString(XmTextFieldGetString(viewer->printCmdText));
3514 psFileName->insert(0, '|');
3515 } else {
3516 psFileName = new GString(XmTextFieldGetString(viewer->printFileText));
3517 }
3518
3519 firstPage = atoi(XmTextFieldGetString(viewer->printFirstPage));
3520 lastPage = atoi(XmTextFieldGetString(viewer->printLastPage));
3521 if (firstPage < 1) {
3522 firstPage = 1;
3523 } else if (firstPage > doc->getNumPages()) {
3524 firstPage = doc->getNumPages();
3525 }
3526 if (lastPage < firstPage) {
3527 lastPage = firstPage;
3528 } else if (lastPage > doc->getNumPages()) {
3529 lastPage = doc->getNumPages();
3530 }
3531
3532 psOut = new PSOutputDev(psFileName->getCString(), doc,
3533 firstPage, lastPage, psModePS);
3534 if (psOut->isOk()) {
3535 doc->displayPages(psOut, firstPage, lastPage, 72, 72,
3536 0, gTrue, globalParams->getPSCrop(), gTrue);
3537 }
3538 delete psOut;
3539 delete psFileName;
3540
3541 viewer->core->setBusyCursor(gFalse);
3542 }
3543
3544 //------------------------------------------------------------------------
3545 // Motif support
3546 //------------------------------------------------------------------------
3547
createFontList(char * xlfd)3548 XmFontList XPDFViewer::createFontList(char *xlfd) {
3549 XmFontList fontList;
3550
3551 #if XmVersion <= 1001
3552
3553 XFontStruct *font;
3554 String params;
3555 Cardinal nParams;
3556
3557 font = XLoadQueryFont(display, xlfd);
3558 if (font) {
3559 fontList = XmFontListCreate(font, XmSTRING_DEFAULT_CHARSET);
3560 } else {
3561 params = (String)xlfd;
3562 nParams = 1;
3563 XtAppWarningMsg(app->getAppContext(),
3564 "noSuchFont", "CvtStringToXmFontList",
3565 "XtToolkitError", "No such font: %s",
3566 ¶ms, &nParams);
3567 fontList = NULL;
3568 }
3569
3570 #else
3571
3572 XmFontListEntry entry;
3573
3574 entry = XmFontListEntryLoad(display, xlfd,
3575 XmFONT_IS_FONT, XmFONTLIST_DEFAULT_TAG);
3576 fontList = XmFontListAppendEntry(NULL, entry);
3577 XmFontListEntryFree(&entry);
3578
3579 #endif
3580
3581 return fontList;
3582 }
3583