2 * Grace - GRaphing, Advanced Computation and Exploration of data
4 * Home page: http://plasma-gate.weizmann.ac.il/Grace/
6 * Copyright (c) 1991-1995 Paul J Turner, Portland, OR
7 * Copyright (c) 1996-2003 Grace Development Team
9 * Maintained by Evgeny Stambulchik
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
41 #define NO_HELP "doc/nohelp.html"
44 # include <XmHTML/XmHTML.h>
45 void create_helper_frame(char *fname
);
48 int force_external_viewer
=
49 #if defined WITH_XMHTML
55 void HelpCB(Widget w
, void *data
)
66 if (strstr(ha
, "http:") || strstr(ha
, "ftp:") || strstr(ha
, "mailto:")) {
67 URL
= copy_string(NULL
, ha
);
72 if (ha
== strstr(ha
, "file:")) {
80 char *base
= copy_string(NULL
, p
);
82 URL
= copy_string(NULL
, grace_path(grace
, base
));
83 URL
= concat_strings(URL
, pa
);
86 URL
= copy_string(NULL
, grace_path(grace
, p
));
92 if (remote
|| force_external_viewer
) {
93 char *help_viewer
, *command
;
94 int i
, j
, len
, urllen
, comlen
;
96 help_viewer
= get_help_viewer(grace
);
97 len
= strlen(help_viewer
);
99 for (i
= 0, comlen
= len
; i
< len
- 1; i
++) {
100 if ((help_viewer
[i
] == '%') && (help_viewer
[i
+ 1] == 's')){
101 comlen
+= urllen
- 2;
105 command
= xmalloc((comlen
+ 1)*SIZEOF_CHAR
);
106 command
[comlen
] = '\0';
107 for (i
= 0, j
= 0; i
< len
; i
++) {
108 if ((help_viewer
[i
] == '%') && (help_viewer
[i
+ 1] == 's')){
109 strcpy (&command
[j
], URL
);
113 command
[j
++] = help_viewer
[i
];
117 system_spawn(command
);
119 command
= concat_strings(command
, "&");
120 system_wrap(command
);
125 create_helper_frame(URL
);
133 * say a few things about Grace
135 static Widget about_frame
;
137 void create_about_grtool(Widget but
, void *data
)
141 if (about_frame
== NULL
) {
142 Widget wbut
, fr
, rc
, about_panel
;
145 about_frame
= CreateDialogForm(app_shell
, "About");
147 about_panel
= CreateVContainer(about_frame
);
148 AddDialogFormChild(about_frame
, about_panel
);
150 fr
= CreateFrame(about_panel
, NULL
);
151 rc
= CreateVContainer(fr
);
152 CreateLabel(rc
, bi_version_string());
154 CreateLabel(rc
, "Debugging is enabled");
157 fr
= CreateFrame(about_panel
, "Legal stuff");
158 rc
= CreateVContainer(fr
);
159 CreateLabel(rc
, "Copyright (c) 1991-1995 Paul J Turner");
160 CreateLabel(rc
, "Copyright (c) 1996-2004 Grace Development Team");
161 CreateLabel(rc
, "Maintained by Evgeny Stambulchik");
162 CreateLabel(rc
, "All rights reserved");
164 "The program is distributed under the terms of the GNU General Public License");
166 fr
= CreateFrame(about_panel
, "Third party copyrights");
167 rc
= CreateVContainer(fr
);
169 "Tab widget, Copyright (c) 1997 Pralay Dakua");
170 CreateLabel(rc
, "Xbae widget,");
172 " Copyright (c) 1991, 1992 Bell Communications Research, Inc. (Bellcore)");
174 " Copyright (c) 1995-1999 Andrew Lister");
176 CreateLabel(rc
, "PDFlib library, Copyright (c) 1997-2004 Thomas Merz and PDFlib GmbH");
179 fr
= CreateFrame(about_panel
, "Build info");
180 rc
= CreateVContainer(fr
);
181 sprintf(buf
, "Host: %s", bi_system());
182 CreateLabel(rc
, buf
);
183 sprintf(buf
, "Time: %s", bi_date());
184 CreateLabel(rc
, buf
);
185 sprintf(buf
, "GUI toolkit: %s ", bi_gui());
186 CreateLabel(rc
, buf
);
187 sprintf(buf
, "Xbae version: %s ", bi_gui_xbae());
188 CreateLabel(rc
, buf
);
189 sprintf(buf
, "T1lib: %s ", bi_t1lib());
190 CreateLabel(rc
, buf
);
192 fr
= CreateFrame(about_panel
, "Home page");
193 rc
= CreateVContainer(fr
);
194 CreateLabel(rc
, "http://plasma-gate.weizmann.ac.il/Grace/");
196 CreateSeparator(about_panel
);
198 wbut
= CreateButton(about_panel
, "Close");
199 AlignLabel(wbut
, ALIGN_CENTER
);
200 AddButtonCB(wbut
, destroy_dialog_cb
, GetParent(about_frame
));
202 ManageChild(about_frame
);
205 RaiseWindow(GetParent(about_frame
));
213 * Simplistic HTML viewer
216 typedef struct _html_ui
{
219 TextStructure
*location
;
226 TextStructure
*input
;
227 Widget case_sensitive
;
228 Widget find_backwards
;
230 XmHTMLTextFinder finder
;
234 static char *loadFile(char *URL
)
240 /* open the given file */
241 if ((file
= grace_openr(grace
, URL
, SOURCE_DISK
)) == NULL
) {
245 /* see how large this file is */
246 fseek(file
, 0, SEEK_END
);
250 /* allocate a buffer large enough to contain the entire file */
251 if ((content
= xmalloc(size
+ 1)) == NULL
) {
252 errmsg("xmalloc failed");
256 /* now read the contents of this file */
257 if ((fread(content
, 1, size
, file
)) != size
) {
258 errmsg("Warning: did not read entire file!");
264 content
[size
] = '\0';
269 static char *translateURL(char *url
, char *base
)
278 type
= XmHTMLGetURLType(url
);
279 if (type
!= ANCHOR_FILE_LOCAL
|| url
[0] == '/') {
280 fname
= copy_string(NULL
, url
);
283 fname
= copy_string(NULL
, base
);
284 p
= strrchr(fname
, '/');
288 fname
= concat_strings(fname
, url
);
290 fname
= copy_string(NULL
, url
);
297 static void anchorCB(Widget w
, XtPointer client_data
, XtPointer call_data
)
300 XmHTMLAnchorPtr href_data
= (XmHTMLAnchorPtr
) call_data
;
301 html_ui
*ui
= (html_ui
*) client_data
;
304 /* see if we have been called with a valid reason */
305 if (href_data
->reason
!= XmCR_ACTIVATE
) {
309 switch (href_data
->url_type
) {
312 /* see if XmHTML knows this anchor */
313 if ((id
= XmHTMLAnchorGetId(w
, href_data
->href
)) != -1) {
314 /* and let XmHTML jump and mark as visited */
315 href_data
->doit
= True
;
316 href_data
->visited
= True
;
318 ui
->url
= copy_string(ui
->url
, ui
->base
);
319 ui
->url
= concat_strings(ui
->url
, href_data
->href
);
320 SetTextString(ui
->location
, ui
->url
);
323 /* let HelpCB check all other types */
325 turl
= translateURL(href_data
->href
, ui
->base
);
332 static void trackCB(Widget w
, XtPointer client_data
, XtPointer call_data
)
334 XmHTMLAnchorPtr href_data
= (XmHTMLAnchorPtr
) call_data
;
335 html_ui
*ui
= (html_ui
*) client_data
;
337 /* see if we have been called with a valid reason */
338 if (href_data
->reason
!= XmCR_HTML_ANCHORTRACK
) {
342 if (href_data
->href
) {
343 /* a valid anchor, eg, moving into an anchor */
344 SetLabel(ui
->track
, href_data
->href
);
346 /* a valid anchor, eg, moving away from an anchor */
347 SetLabel(ui
->track
, "");
351 static int find_cb(void *data
)
354 int case_sensitive
, find_backwards
;
355 XmHTMLTextPosition start
, end
;
356 html_ui
*ui
= (html_ui
*) data
;
359 return RETURN_FAILURE
;
362 s
= GetTextString(ui
->input
);
364 if (is_empty_string(s
)) {
366 return RETURN_FAILURE
;
369 if (ui
->finder
== NULL
) {
370 ui
->finder
= XmHTMLTextFinderCreate(ui
->html
);
371 if (ui
->finder
== NULL
) {
372 errmsg("XmHTMLTextFinderCreate failed!");
374 return RETURN_FAILURE
;
378 case_sensitive
= GetToggleButtonState(ui
->case_sensitive
);
379 find_backwards
= GetToggleButtonState(ui
->find_backwards
);
382 * The second arg represent regcomp flags, the default being
383 * REG_EXTENDED. Using -1 for this arg instructs the finder to
384 * keep the current flags. See man regcomp on possible values for
385 * your system. The third arg specifies whether or not the search
386 * should be done case-insensitive (True) or not (False). The last arg
387 * specifies the search direction. Currently only forward (top to
388 * bottom) is supported.
390 XmHTMLTextFinderSetPatternFlags(ui
->finder
,
392 case_sensitive
? False
: True
,
393 find_backwards
? XmHTML_BACKWARD
: XmHTML_FORWARD
);
395 if (ui
->last
== NULL
|| strcmp(ui
->last
, s
)) {
396 if(!XmHTMLTextFinderSetPattern(ui
->finder
, s
)) {
398 ptr
= XmHTMLTextFinderGetErrorString(ui
->finder
);
400 errmsg(ptr
? ptr
: "(unknown error)");
406 return RETURN_FAILURE
;
410 switch (XmHTMLTextFindString(ui
->html
, ui
->finder
)) {
412 ptr
= XmHTMLTextFinderGetErrorString(ui
->finder
);
413 errmsg(ptr
? ptr
: "(unknown error)");
417 if (yesno("End of document reached; continue from beginning?",
418 NULL
, NULL
, NULL
) == TRUE
) {
425 if (XmHTMLTextFindToPosition(ui
->html
, ui
->finder
, &start
, &end
)) {
426 XmHTMLTextShowPosition(ui
->html
, start
);
427 XmHTMLTextSetHighlight(ui
->html
, start
, end
, XmHIGHLIGHT_SELECTED
);
435 return RETURN_SUCCESS
;
438 static void create_find_dialog(Widget but
, void *data
)
440 static Widget dialog
= NULL
;
441 html_ui
*ui
= (html_ui
*) data
;
446 dialog
= CreateDialogForm(ui
->html
, "Find Dialog");
448 rc
= CreateVContainer(dialog
);
449 ui
->input
= CreateTextInput(rc
, "Find:");
450 rc2
= CreateHContainer(rc
);
451 ui
->case_sensitive
= CreateToggleButton(rc2
, "Case sensitive");
452 ui
->find_backwards
= CreateToggleButton(rc2
, "Find backwards (N/I)");
454 CreateAACDialog(dialog
, rc
, find_cb
, data
);
459 RaiseWindow(GetParent(dialog
));
462 static void refresh_cb(Widget but
, void *data
)
464 html_ui
*ui
= (html_ui
*) data
;
465 XmHTMLRedisplay(ui
->html
);
468 static XmImageInfo
*loadImage(Widget w
,
469 String url
, Dimension width
, Dimension height
, XtPointer client_data
)
473 html_ui
*ui
= (html_ui
*) client_data
;
475 fname
= translateURL(url
, ui
->base
);
480 image
= XmHTMLImageDefaultProc(w
, fname
, NULL
, 0);
487 void location_cb(TextStructure
*cst
, char *s
, void *data
)
492 static void find_again_cb(Widget but
, void *data
)
497 void create_helper_frame(char *URL
)
499 static html_ui
*ui
= NULL
;
505 Widget fr1
, fr2
, menubar
, menupane
, rc
;
507 ui
= xmalloc(sizeof(html_ui
));
508 memset(ui
, 0, sizeof(html_ui
));
510 ui
->top
= CreateDialogForm(app_shell
, "Gracilla");
512 menubar
= CreateMenuBar(ui
->top
);
513 ManageChild(menubar
);
514 AddDialogFormChild(ui
->top
, menubar
);
516 menupane
= CreateMenu(menubar
, "File", 'F', FALSE
);
517 CreateMenuCloseButton(menupane
, ui
->top
);
519 menupane
= CreateMenu(menubar
, "Edit", 'E', FALSE
);
520 CreateMenuButton(menupane
, "Find", 'F', create_find_dialog
, ui
);
521 CreateMenuButton(menupane
, "Find again", 'g', find_again_cb
, ui
);
523 menupane
= CreateMenu(menubar
, "View", 'V', FALSE
);
524 CreateMenuButton(menupane
, "Refresh", 'R', refresh_cb
, ui
);
526 menupane
= CreateMenu(menubar
, "Help", 'H', TRUE
);
527 CreateMenuButton(menupane
, "User's Guide", 'G', HelpCB
, "doc/UsersGuide.html");
528 CreateMenuButton(menupane
, "FAQ", 'Q', HelpCB
, "doc/FAQ.html");
529 CreateMenuButton(menupane
, "Changes", 'C', HelpCB
, "doc/CHANGES.html");
530 CreateMenuSeparator(menupane
);
531 CreateMenuButton(menupane
, "License terms", 'L', HelpCB
, "doc/GPL.html");
533 ui
->location
= CreateTextInput(ui
->top
, "Location:");
534 AddTextInputCB(ui
->location
, location_cb
, ui
->location
);
535 AddDialogFormChild(ui
->top
, ui
->location
->form
);
537 fr1
= CreateFrame(ui
->top
, NULL
);
538 AddDialogFormChild(ui
->top
, fr1
);
539 ui
->html
= XtVaCreateManagedWidget("html",
540 xmHTMLWidgetClass
, fr1
,
541 XmNimageProc
, loadImage
,
542 XmNclientData
, (XtPointer
) ui
,
543 XmNenableBadHTMLWarnings
, XmHTML_NONE
,
544 XmNanchorButtons
, False
,
549 XtAddCallback(ui
->html
, XmNactivateCallback
, anchorCB
, ui
);
550 XtAddCallback(ui
->html
, XmNanchorTrackCallback
, trackCB
, ui
);
552 fr2
= CreateFrame(ui
->top
, NULL
);
553 AddDialogFormChild(ui
->top
, fr2
);
554 rc
= CreateVContainer(fr2
);
555 ui
->track
= CreateLabel(rc
, "Welcome to Gracilla!");
558 XmNbottomAttachment
, XmATTACH_WIDGET
,
559 XmNbottomWidget
, fr2
,
562 XmNtopAttachment
, XmATTACH_NONE
,
565 ManageChild(ui
->top
);
567 XtVaSetValues(rc
, XmNresizeHeight
, False
, NULL
);
569 ManageChild(GetParent(ui
->top
));
572 ui
->url
= copy_string(ui
->url
, URL
);
573 ui
->base
= copy_string(ui
->base
, URL
);
577 p
= strchr(ui
->url
, '#');
579 ui
->base
[p
- ui
->url
] = '\0';
580 ui
->anchor
= copy_string(ui
->anchor
, p
);
586 SetTextString(ui
->location
, ui
->url
);
589 XmHTMLTextFinderDestroy(ui
->finder
);
594 content
= loadFile(ui
->base
);
595 if (content
!= NULL
) {
596 XmHTMLTextSetString(ui
->html
, content
);
598 int id
= XmHTMLAnchorGetId(ui
->html
, ui
->anchor
);
600 XmHTMLAnchorScrollToId(ui
->html
, id
);
603 XmHTMLTextScrollToLine(ui
->html
, 0);
607 RaiseWindow(GetParent(ui
->top
));
612 #endif /* WITH_XMHTML */