The R Project SVN R

Rev

Rev 68956 | Rev 83709 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
9212 ripley 1
/*
2
 *  R : A Computer Language for Statistical Data Analysis
3
 *  file pager.c
21959 ripley 4
 *  Copyright (C) 1998--2002  Guido Masarotto and Brian Ripley
67595 ripley 5
 *  Copyright (C) 2004--8     The R Foundation
6
 *  Copyright (C) 2004--2014  The R Core Team
9212 ripley 7
 *
8
 *  This program is free software; you can redistribute it and/or modify
9
 *  it under the terms of the GNU General Public License as published by
10
 *  the Free Software Foundation; either version 2 of the License, or
11
 *  (at your option) any later version.
12
 *
13
 *  This program is distributed in the hope that it will be useful,
14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 *  GNU General Public License for more details.
17
 *
18
 *  You should have received a copy of the GNU General Public License
42300 ripley 19
 *  along with this program; if not, a copy is available at
68956 ripley 20
 *  https://www.R-project.org/Licenses/
9212 ripley 21
 */
22
 
23
#ifdef HAVE_CONFIG_H
24
#include <config.h>
25
#endif
26
 
32888 ripley 27
#include "win-nls.h"
28
 
9212 ripley 29
#ifdef Win32
30
#define USE_MDI 1
31
#endif
32
 
36901 ripley 33
#define WIN32_LEAN_AND_MEAN 1
9212 ripley 34
#include <windows.h>
35
#include "graphapp/ga.h"
36
#ifdef USE_MDI
37
#include "graphapp/stdimg.h"
38
#endif
39
#include "console.h"
40
#include "consolestructs.h"
41
#include "rui.h"
66108 ripley 42
#include <Startup.h> /* for CharacterMode */
9212 ripley 43
 
44016 ripley 44
#define CE_UTF8 1
45
extern size_t Rf_utf8towcs(wchar_t *wc, const char *s, size_t n);
46
 
9212 ripley 47
#define PAGERMAXKEPT 12
48
#define PAGERMAXTITLE 128
49
 
50
static int pagerActualKept = 0, pagerActualShown;
51
static pager pagerInstance = NULL;
52
static menubar pagerBar = NULL;
53
static xbuf pagerXbuf[PAGERMAXKEPT];
54
static char pagerTitles[PAGERMAXKEPT][PAGERMAXTITLE+8];
55
static menuitem pagerMenus[PAGERMAXKEPT];
56
static int pagerRow[PAGERMAXKEPT];
44201 ripley 57
static void pagerupdateview(void);
9212 ripley 58
 
28991 murdoch 59
void menueditoropen(control m);
60
void menueditornew(control m);
61
 
9212 ripley 62
int pagerMultiple, haveusedapager;
63
 
64
 
65
/*
66
   To be fixed: during creation, memory is allocated two times
67
   (faster for small files but a big waste otherwise)
68
*/
44016 ripley 69
static xbuf file2xbuf(const char *name, int enc, int del)
9212 ripley 70
{
71
    HANDLE f;
72
    DWORD rr, vv;
43882 ripley 73
    char *p;
74
    xlong dim, cnt;
9212 ripley 75
    xint  ms;
76
    xbuf  xb;
43882 ripley 77
    wchar_t *wp, *q;
78
 
44016 ripley 79
    if (enc == CE_UTF8) {
80
	wchar_t wfn[MAX_PATH+1];
81
	Rf_utf8towcs(wfn, name, MAX_PATH+1);
82
	f = CreateFileW(wfn, GENERIC_READ, FILE_SHARE_READ,
45070 ripley 83
			NULL, OPEN_EXISTING, 0, NULL);
44016 ripley 84
    } else
85
	f = CreateFile(name, GENERIC_READ, FILE_SHARE_READ,
86
		       NULL, OPEN_EXISTING, 0, NULL);
9212 ripley 87
    if (f == INVALID_HANDLE_VALUE) {
33001 ripley 88
	R_ShowMessage(G_("Error opening file"));
9212 ripley 89
	return NULL;
90
    }
91
    vv = GetFileSize(f, NULL);
11169 ripley 92
    p = (char *) malloc((size_t) vv + 1);
9212 ripley 93
    if (!p) {
94
	CloseHandle(f);
33001 ripley 95
	R_ShowMessage(G_("Insufficient memory to display file in internal pager"));
9212 ripley 96
	return NULL;
97
    }
98
    ReadFile(f, p, vv, &rr, NULL);
99
    CloseHandle(f);
100
    if (del) DeleteFile(name);
101
    p[rr] = '\0';
43882 ripley 102
    cnt = mbstowcs(NULL, p, 0);
103
    wp = (wchar_t *) malloc((cnt+1) * sizeof(wchar_t));
104
    mbstowcs(wp, p, cnt+1);
105
    for (q = wp, ms = 1, dim = cnt; *q; q++) {
9212 ripley 106
	if (*q == '\t')
107
	    dim += TABSIZE;
108
	else if (*q == '\n') {
45070 ripley 109
	    dim++;
9212 ripley 110
	    ms++;
45070 ripley 111
	}
9212 ripley 112
    }
43882 ripley 113
    free(p);
12256 pd 114
    if ((xb = newxbuf(dim + 1, ms + 1, 1)))
43882 ripley 115
	for (q = wp, ms = 0; *q; q++) {
116
	    if (*q == L'\r') continue;
117
	    if (*q == L'\n') {
9212 ripley 118
		ms++;
43882 ripley 119
		xbufaddxc(xb, *q);
9212 ripley 120
		/* next line interprets underlining in help files */
43882 ripley 121
		if (q[1] ==  L'_' && q[2] == L'\b') xb->user[ms] = -2;
122
	    } else xbufaddxc(xb, *q);
9212 ripley 123
	}
43882 ripley 124
    free(wp);
9212 ripley 125
    return xb;
126
}
127
 
128
static void delpager(control m)
129
{
130
    int i;
131
 
132
    ConsoleData p = getdata(m);
133
    if (!pagerMultiple) {
43882 ripley 134
	for (i = 0; i < pagerActualKept; i++) xbufdel(pagerXbuf[i]);
9212 ripley 135
	pagerActualKept = 0;
136
    }
137
    else
138
	xbufdel(p->lbuf);
139
    freeConsoleData(getdata(m));
140
}
141
 
21959 ripley 142
void pagerbclose(control m)
9212 ripley 143
{
144
    show(RConsole);
145
    if (!pagerMultiple) {
45070 ripley 146
	hide(pagerInstance);
9212 ripley 147
	del(pagerInstance);
148
	pagerInstance = pagerBar = NULL;
149
    }
150
    else {
45070 ripley 151
	hide(m);
9212 ripley 152
	del(m);
153
    }
154
}
155
 
156
static void pagerclose(control m)
157
{
158
    pagerbclose(getdata(m));
159
}
160
 
161
static void pagerprint(control m)
162
{
163
    consoleprint(getdata(m));
164
}
165
 
10987 ripley 166
static void pagersavefile(control m)
167
{
17261 ripley 168
    consolesavefile(getdata(m), 1);
10987 ripley 169
}
170
 
9212 ripley 171
static void pagercopy(control m)
172
{
173
    control c = getdata(m);
174
 
175
    if (consolecancopy(c)) consolecopy(c);
33001 ripley 176
    else R_ShowMessage(G_("No selection"));
9212 ripley 177
}
178
 
179
static void pagerpaste(control m)
180
{
181
    control c = getdata(m);
182
 
10345 ripley 183
    if (CharacterMode != RGui) {
45070 ripley 184
	R_ShowMessage(G_("No RGui console to paste to"));
185
	return;
10345 ripley 186
    }
9212 ripley 187
    if (!consolecancopy(c)) {
45070 ripley 188
	R_ShowMessage(G_("No selection"));
189
	return;
9212 ripley 190
    } else {
45070 ripley 191
	consolecopy(c);
9212 ripley 192
    }
193
    if (consolecanpaste(RConsole)) {
194
	consolepaste(RConsole);
195
	show(RConsole);
196
    }
197
}
198
 
28544 murdoch 199
static void pagerpastecmds(control m)
200
{
201
    control c = getdata(m);
202
 
203
    if (CharacterMode != RGui) {
45070 ripley 204
	R_ShowMessage(G_("No RGui console to paste to"));
205
	return;
28544 murdoch 206
    }
207
    if (!consolecancopy(c)) {
45070 ripley 208
	R_ShowMessage(G_("No selection"));
209
	return;
28544 murdoch 210
    } else {
45070 ripley 211
	consolecopy(c);
28544 murdoch 212
    }
213
    if (consolecanpaste(RConsole)) {
214
	consolepastecmds(RConsole);
215
	show(RConsole);
216
    }
217
}
218
 
9212 ripley 219
static void pagerselectall(control m)
220
{
221
    control c = getdata(m);
222
 
223
    consoleselectall(c);
224
}
225
 
27662 murdoch 226
static void pagerstayontop(control m)
227
{
228
    control c = getdata(m);
229
 
27686 murdoch 230
    BringToTop(c, 2);
27662 murdoch 231
}
232
 
9212 ripley 233
static void pagerconsole(control m)
234
{
235
    show(RConsole);
236
}
237
 
238
static void pagerchangeview(control m)
239
{
240
    ConsoleData p = getdata(pagerInstance);
241
    int i = getvalue(m);
242
 
243
    if (i >= pagerActualKept) return;
244
    uncheck(pagerMenus[pagerActualShown]);
245
    /* save position of middle line of pager display */
246
    pagerRow[pagerActualShown] = FV + ROWS/2;
247
    pagerActualShown = i;
248
    check(pagerMenus[i]);
249
    pagerupdateview();
250
}
251
 
44201 ripley 252
static void pagerupdateview(void)
9212 ripley 253
{
254
    control c = pagerInstance;
255
    ConsoleData p = getdata(c);
256
 
257
    settext(pagerInstance, &pagerTitles[pagerActualShown][4]);
258
    p->lbuf = pagerXbuf[pagerActualShown];
259
    setfirstvisible(c, pagerRow[pagerActualShown] - ROWS/2);
260
    setfirstcol(c, 0);
261
    show(c);
262
}
263
 
45070 ripley 264
static int pageraddfile(const char *wtitle,
44016 ripley 265
			const char *filename, int enc,
43767 ripley 266
			int deleteonexit)
9212 ripley 267
{
268
    ConsoleData p = getdata(pagerInstance);
269
    int i;
44016 ripley 270
    xbuf nxbuf = file2xbuf(filename, enc, deleteonexit);
9212 ripley 271
 
272
    if (!nxbuf) {
22614 ripley 273
	/* R_ShowMessage("File not found or memory insufficient"); */
9212 ripley 274
	return 0;
275
    }
276
    if (pagerActualKept == PAGERMAXKEPT) {
45070 ripley 277
	pagerActualKept -= 1;
278
	xbufdel(pagerXbuf[pagerActualKept]);
9212 ripley 279
    }
280
    if(pagerActualKept > 0)
281
	pagerRow[0] = FV;
282
    for (i = pagerActualKept; i > 0; i--) {
283
	pagerXbuf[i] = pagerXbuf[i - 1];
284
	pagerRow[i] = pagerRow[i - 1];
285
	strcpy(&pagerTitles[i][4], &pagerTitles[i - 1][4]);
286
    }
287
    pagerXbuf[0] = nxbuf;
288
    pagerRow[0] = 0;
289
    strcpy(&pagerTitles[0][4], wtitle);
290
    pagerActualKept += 1;
291
    for (i = 0; i < pagerActualKept; i++) {
292
	enable(pagerMenus[i]);
293
	settext(pagerMenus[i], pagerTitles[i]);
294
    }
295
    for (i = pagerActualKept; i < PAGERMAXKEPT; i++)
296
	disable(pagerMenus[i]);
297
    uncheck(pagerMenus[pagerActualShown]);
298
    pagerActualShown = 0;
299
    check(pagerMenus[pagerActualShown]);
300
    return 1;
301
}
302
 
28544 murdoch 303
static MenuItem PagerPopup[] = {		   /* Numbers used below */
33001 ripley 304
    {GN_("Copy"), pagercopy, 'C', 0},			   /* 0 */
305
    {GN_("Paste to console"), pagerpaste, 'V', 0},	   /* 1 */
306
    {GN_("Paste commands to console"), pagerpastecmds, 0, 0},   /* 2 */
307
    {GN_("Select all"), pagerselectall, 'A', 0},		   /* 3 */
28991 murdoch 308
    {"-", 0, 0, 0},
33001 ripley 309
    {GN_("Stay on top"), pagerstayontop, 0, 0},		   /* 5 */
28991 murdoch 310
    {"-", 0, 0, 0},
33001 ripley 311
    {GN_("Close"), pagerclose, 0, 0},			   /* 7 */
9212 ripley 312
    LASTMENUITEM
313
};
314
 
315
static void pagermenuact(control m)
316
{
317
    control c = getdata(m);
318
    ConsoleData p = getdata(c);
319
    if (consolecancopy(c)) {
45070 ripley 320
	enable(p->mcopy);
321
	enable(p->mpopcopy);
322
	if (CharacterMode == RGui) {
10345 ripley 323
	    enable(p->mpaste);
28544 murdoch 324
	    enable(p->mpastecmds);
10345 ripley 325
	    enable(p->mpoppaste);
28544 murdoch 326
	    enable(p->mpoppastecmds);
10345 ripley 327
	}
9212 ripley 328
    } else {
45070 ripley 329
	disable(p->mcopy);
330
	disable(p->mpopcopy);
331
	disable(p->mpaste);
332
	disable(p->mpastecmds);
333
	disable(p->mpoppaste);
334
	disable(p->mpoppastecmds);
9212 ripley 335
    }
27662 murdoch 336
    if (ismdi())
45070 ripley 337
	disable(PagerPopup[5].m);
27686 murdoch 338
    else {
45070 ripley 339
	enable(PagerPopup[5].m);
340
	if (isTopmost(c))
341
	    check(PagerPopup[5].m);
342
	else
343
	    uncheck(PagerPopup[5].m);
27686 murdoch 344
    }
9212 ripley 345
}
346
 
347
 
27357 murdoch 348
#define MCHECK(a) if (!(a)) {freeConsoleData(p);del(c);return NULL;}
44201 ripley 349
RECT *RgetMDIsize(void); /* in rui.c */
27357 murdoch 350
 
44201 ripley 351
static pager pagercreate(void)
9212 ripley 352
{
353
    ConsoleData p;
354
    int w, h, i, x, y, w0, h0;
355
    pager c;
356
    menuitem m;
357
 
358
    p = newconsoledata((consolefn) ? consolefn : FixedFont,
11588 ripley 359
		       pagerrow, pagercol, 0, 0,
46784 murdoch 360
		       guiColors,
51948 murdoch 361
		       PAGER, 0, 0);
9212 ripley 362
    if (!p) return NULL;
363
 
364
/*    if (ismdi()) {
45070 ripley 365
      x = y = w = h = 0;
366
      }
367
      else {
368
      w = WIDTH ;
369
      h = HEIGHT;
370
      x = (devicewidth(NULL) - w) / 2;
371
      y = (deviceheight(NULL) - h) / 2 ;
372
      } */
9212 ripley 373
    w = WIDTH ;
374
    h = HEIGHT;
375
    /* centre a single pager, randomly place each of multiple pagers */
376
#ifdef USE_MDI
377
    if(ismdi()) {
378
	RECT *pR = RgetMDIsize();
379
	w0 = pR->right;
380
	h0 = pR->bottom;
381
    } else {
382
#endif
383
	w0 = devicewidth(NULL);
384
	h0 = deviceheight(NULL);
385
#ifdef USE_MDI
386
    }
387
#endif
388
    x = (w0 - w) / 2; x = x > 20 ? x:20;
389
    y = (h0 - h) / 2; y = y > 20 ? y:20;
390
    if(pagerMultiple) {
391
#ifdef Win32
392
	DWORD rand = GetTickCount();
393
#else
394
	int rand = 0;
395
#endif
396
	int w0 = 0.4*x, h0 = 0.4*y;
397
	w0 = w0 > 20 ? w0 : 20;
398
	h0 = h0 > 20 ? h0 : 20;
399
	x += (rand % w0) - w0/2;
400
	y += ((rand/w0) % h0) - h0/2;
401
    }
402
    c = (pager) newwindow("PAGER", rect(x, y, w, h),
403
			  Document | StandardWindow | Menubar |
404
			  VScrollbar | HScrollbar | TrackMouse);
405
    if (!c) {
45070 ripley 406
	freeConsoleData(p);
407
	return NULL;
9212 ripley 408
    }
409
    setdata(c, p);
410
    if(h == 0) HEIGHT = getheight(c);
411
    if(w == 0) WIDTH  = getwidth(c);
412
    COLS = WIDTH / FW - 1;
413
    ROWS = HEIGHT / FH - 1;
414
    BORDERX = (WIDTH - COLS*FW) / 2;
415
    BORDERY = (HEIGHT - ROWS*FH) / 2;
416
    gsetcursor(c, ArrowCursor);
417
    gchangescrollbar(c, VWINSB, 0, 0, ROWS, 0);
418
    gchangescrollbar(c, HWINSB, 0, COLS-1, COLS, 1);
46784 murdoch 419
    setbackground(c, guiColors[pagerbg]);
9212 ripley 420
#ifdef USE_MDI
40579 ripley 421
    if (ismdi()) {
45070 ripley 422
	int btsize = 24;
423
	rect r = rect(2, 2, btsize, btsize);
424
	control tb, bt;
425
	addto(c);
426
	MCHECK(tb = newtoolbar(btsize + 4));
9212 ripley 427
	gsetcursor(tb, ArrowCursor);
45070 ripley 428
	addto(tb);
429
	MCHECK(bt = newtoolbutton(open_image, r, menueditoropen));
430
	MCHECK(addtooltip(bt, G_("Open script")));
28991 murdoch 431
	gsetcursor(bt, ArrowCursor);
35234 ripley 432
	/* wants NULL as data, not the pager */
45070 ripley 433
	r.x += (btsize + 6) ;
434
	MCHECK(bt = newtoolbutton(copy1_image, r, pagerpaste));
435
	MCHECK(addtooltip(bt, G_("Paste to console")));
9212 ripley 436
	gsetcursor(bt, ArrowCursor);
45070 ripley 437
	setdata(bt, (void *) c);
438
	r.x += (btsize + 6) ;
439
	MCHECK(bt = newtoolbutton(copy1_image, r, pagerpastecmds));
440
	MCHECK(addtooltip(bt, G_("Paste commands to console")));
28544 murdoch 441
	gsetcursor(bt, ArrowCursor);
45070 ripley 442
	setdata(bt, (void *) c);
443
	r.x += (btsize + 6) ;
444
	MCHECK(bt = newtoolbutton(print_image, r, pagerprint));
445
	MCHECK(addtooltip(bt, G_("Print")));
9212 ripley 446
	gsetcursor(bt, ArrowCursor);
45070 ripley 447
	setdata(bt, (void *) c);
448
	r.x += (btsize + 6) ;
449
	MCHECK(bt = newtoolbutton(console_image, r, pagerconsole));
450
	MCHECK(addtooltip(bt, G_("Return focus to Console")));
9212 ripley 451
	gsetcursor(bt, ArrowCursor);
45070 ripley 452
	setdata(bt, (void *) c);
9212 ripley 453
    }
454
#endif
455
    addto(c);
456
    MCHECK(m = gpopup(pagermenuact, PagerPopup));
457
    setdata(m, c);
458
    setdata(p->mpopcopy = PagerPopup[0].m, c);
459
    setdata(p->mpoppaste = PagerPopup[1].m, c);
28544 murdoch 460
    setdata(p->mpoppastecmds = PagerPopup[2].m, c);
461
    setdata(PagerPopup[3].m, c);
462
    setdata(PagerPopup[5].m, c);
463
    setdata(PagerPopup[7].m, c);
9212 ripley 464
    MCHECK(m = newmenubar(pagermenuact));
465
    setdata(m, c);
33001 ripley 466
    MCHECK(newmenu(G_("File")));
467
    MCHECK(m = newmenuitem(G_("New script"), 'N', menueditornew));
468
    MCHECK(m = newmenuitem(G_("Open script..."), 'O', menueditoropen));
69561 murdoch 469
    MCHECK(m = newmenuitem(G_("Print..."), 'P', pagerprint));
9212 ripley 470
    setdata(m, c);
69561 murdoch 471
    MCHECK(m = newmenuitem(G_("Save to File..."), 'S', pagersavefile));
10987 ripley 472
    setdata(m, c);
9212 ripley 473
    MCHECK(m = newmenuitem("-", 0, NULL));
33001 ripley 474
    MCHECK(m = newmenuitem(G_("Close"), 0, pagerclose));
9212 ripley 475
    setdata(m, c);
33001 ripley 476
    MCHECK(newmenu(G_("Edit")));
477
    MCHECK(p->mcopy = newmenuitem(G_("Copy"), 'C', pagercopy));
9212 ripley 478
    setdata(p->mcopy, c);
33001 ripley 479
    MCHECK(p->mpaste = newmenuitem(G_("Paste to console"), 'V', pagerpaste));
9212 ripley 480
    setdata(p->mpaste, c);
33001 ripley 481
    MCHECK(p->mpastecmds = newmenuitem(G_("Paste commands to console"), 0, pagerpastecmds));
28544 murdoch 482
    setdata(p->mpastecmds, c);
33001 ripley 483
    MCHECK(m = newmenuitem(G_("Select all"), 'A', pagerselectall));
9212 ripley 484
    setdata(m, c);
485
    if (!pagerMultiple) {
33001 ripley 486
	MCHECK(newmenu(G_("View")));
9212 ripley 487
	for (i = 0; i < PAGERMAXKEPT; i++) {
62583 ripley 488
	    snprintf(pagerTitles[i], PAGERMAXTITLE+8, "&%c.  ", 'A' + i);
9212 ripley 489
	    MCHECK(pagerMenus[i] = newmenuitem(&pagerTitles[i][1], 0,
490
					       pagerchangeview));
491
	    setvalue(pagerMenus[i], i);
492
	}
493
    }
494
#ifdef USE_MDI
495
    if (ismdi()) newmdimenu();
40579 ripley 496
    if (ismdi() && !(RguiMDI & RW_TOOLBAR)) toolbar_hide();
9212 ripley 497
#endif
498
    MCHECK(BM = newbitmap(WIDTH, HEIGHT, 2));
499
    setdata(c, p);
500
    sethit(c, console_sbf);
501
    setresize(c, consoleresize);
502
    setredraw(c, drawconsole);
503
    setdel(c, delpager);
504
    setclose(c, pagerbclose);
505
    setkeyaction(c, console_ctrlkeyin);
506
    setkeydown(c, console_normalkeyin);
507
    setmousedrag(c, console_mousedrag);
508
    setmouserepeat(c, console_mouserep);
509
    setmousedown(c, console_mousedown);
510
    return(c);
511
}
512
 
45070 ripley 513
static pager newpager1win(const char *wtitle,
44016 ripley 514
			  const char *filename, int enc,
43767 ripley 515
			  int deleteonexit)
9212 ripley 516
{
517
    if (!pagerInstance && !(pagerInstance = pagercreate())) {
45070 ripley 518
	R_ShowMessage(G_("Unable to create pager window"));
519
	return NULL;
9212 ripley 520
    }
44016 ripley 521
    if (!pageraddfile(wtitle, filename, enc, deleteonexit)) return NULL;
9212 ripley 522
    pagerupdateview();
523
    return pagerInstance;
524
}
525
 
45070 ripley 526
static pager newpagerNwin(const char *wtitle,
44016 ripley 527
			  const char *filename, int enc,
43767 ripley 528
			  int deleteonexit)
9212 ripley 529
{
530
    pager c = pagercreate();
531
    ConsoleData p;
532
 
533
    if (!c) return NULL;
534
    settext(c, wtitle);
535
    p = getdata(c);
44016 ripley 536
    if (!(p->lbuf = file2xbuf(filename, enc, deleteonexit))) {
9212 ripley 537
	del(c);
538
	return NULL;
539
    }
540
    if (c) {
541
	gchangescrollbar(c, VWINSB, 0, NUMLINES - 1 , ROWS, 0);
542
	show(c);
543
    }
544
    return c;
545
}
546
 
45070 ripley 547
pager newpager(const char *title,
44016 ripley 548
	       const char *filename, int enc,
43767 ripley 549
	       const char *header, int deleteonexit)
9212 ripley 550
{
551
    char wtitle[PAGERMAXTITLE+1];
552
    pager c;
553
 
554
    /*    if (ismdi()) pagerMultiple = 1;*/
555
    strncpy(wtitle, title, PAGERMAXTITLE);
556
    wtitle[PAGERMAXTITLE] = '\0';
557
    if(strlen(header) &&
558
       ((strlen(header) + strlen(wtitle) + 4) < PAGERMAXTITLE)) {
559
	if(strlen(wtitle)) strcat(wtitle, " - ");
560
	strcat(wtitle, header);
561
    }
562
    if (!pagerMultiple)
45070 ripley 563
	c = newpager1win(wtitle, filename, enc, deleteonexit);
9212 ripley 564
    else
45070 ripley 565
	c = newpagerNwin(wtitle, filename, enc, deleteonexit);
22614 ripley 566
    if (c) {
567
	haveusedapager++;
27357 murdoch 568
	BringToTop(c, 0);
22614 ripley 569
    }
9212 ripley 570
    return c;
571
}