The R Project SVN R

Rev

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