[comp.sources.misc] v20i027: ivinfo - InterViews emacs info file browser in C++, Part02/04

tom@hcx2.ssd.csd.harris.com (Tom Horsley) (05/30/91)

Submitted-by: Tom Horsley <tom@hcx2.ssd.csd.harris.com>
Posting-number: Volume 20, Issue 27
Archive-name: ivinfo/part02

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 2 (of 4)."
# Contents:  dialogbox.c ivinfo.texinfo
# Wrapped by tom@hcx2 on Wed May 29 10:48:51 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'dialogbox.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'dialogbox.c'\"
else
echo shar: Extracting \"'dialogbox.c'\" \(13155 characters\)
sed "s/^X//" >'dialogbox.c' <<'END_OF_FILE'
X/*
X * Copyright (c) 1987, 1988, 1989 Stanford University
X *
X * Permission to use, copy, modify, distribute, and sell this software and its
X * documentation for any purpose is hereby granted without fee, provided
X * that the above copyright notice appear in all copies and that both that
X * copyright notice and this permission notice appear in supporting
X * documentation, and that the name of Stanford not be used in advertising or
X * publicity pertaining to distribution of the software without specific,
X * written prior permission.  Stanford makes no representations about
X * the suitability of this software for any purpose.  It is provided "as is"
X * without express or implied warranty.
X *
X * STANFORD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
X * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
X * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
X * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
X * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
X * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
X * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
X */
X
X/*
X * $Header: dialogbox.c,v 1.18 90/01/25 16:29:08 interran Exp $
X * implements class DialogBox and DialogBox subclasses.
X */
X
X#include "dialogbox.h"
X#include "istring.h"
X#include <InterViews/box.h>
X#include <InterViews/button.h>
X#include <InterViews/canvas.h>
X#include <InterViews/event.h>
X#include <InterViews/font.h>
X#include <InterViews/frame.h>
X#include <InterViews/glue.h>
X#include <InterViews/message.h>
X#include <InterViews/painter.h>
X#include <InterViews/sensor.h>
X#include <InterViews/shape.h>
X#include <InterViews/streditor.h>
X#include <InterViews/world.h>
X
X#include <os/fs.h>
X#include <sys/param.h>
X
X/*
X * An IMessage displays its own text, not somebody else's.
X */
X
Xclass IMessage : public Message {
Xpublic:
X    IMessage(const char* = nil, Alignment a = Center);
X    ~IMessage();
X
X    void SetText(const char* = nil, const char* = nil);
Xprotected:
X    char* buffer;		/* stores own copy of text */
X};
X
X/*
X * IMessage creates a buffer to store its own copy of the text.
X */
X
XIMessage::IMessage (const char* msg, Alignment a) : (nil, a) {
X    buffer = strdup(msg ? msg : "");
X    text = buffer;
X}
X
X/*
X * Free storage allocated for the text buffer.
X */
X
XIMessage::~IMessage () {
X    delete buffer;
X}
X
X/*
X * SetText stores the new text and changes the IMessage's shape to fit
X * the new text's width.
X */
X
Xvoid IMessage::SetText (const char* beg, const char* end) {
X    beg = beg ? beg : "";
X    end = end ? end : "";
X    delete buffer;
X    buffer = new char[strlen(beg) + strlen(end) + 1];
X    strcpy(buffer, beg);
X    strcat(buffer, end);
X    text = buffer;
X    if (canvas != nil && canvas->Status() == CanvasMapped) {
X	Reconfig();
X	Parent()->Change(this);
X    }
X}
X
X/*
X * DialogBox creates two IMessages to display a message and a warning
X * and stores its underlying Interactor.  DialogBox won't delete the
X * IMessages so its derived classes can put them in boxes which will
X * delete them when the boxes are deleted.
X */
X
XDialogBox::DialogBox (Interactor* u, const char* msg) {
X    SetCanvasType(CanvasSaveUnder); /* speed up expose redrawing if possible */
X    input = allEvents;
X    input->Reference();
X    message = new IMessage(msg);
X    warning = new IMessage;
X    underlying = u;
X}
X
X/*
X * SetMessage sets the message's text.
X */
X
Xvoid DialogBox::SetMessage (const char* beg, const char* end) {
X    message->SetText(beg, end);
X}
X
X/*
X * SetWarning sets the warning's text.
X */
X
Xvoid DialogBox::SetWarning (const char* beg, const char* end) {
X    warning->SetText(beg, end);
X}
X
X/*
X * SetUnderlying sets the underlying Interactor over which the
X * DialogBox will pop up itself.
X */
X
Xvoid DialogBox::SetUnderlying (Interactor* u) {
X    underlying = u;
X}
X
X/*
X * PopUp pops up the DialogBox centered over the underlying
X * Interactor's canvas.
X */
X
Xvoid DialogBox::PopUp () {
X    World* world = underlying->GetWorld();
X    Coord x, y;
X    underlying->Align(Center, 0, 0, x, y);
X    underlying->GetRelative(x, y, world);
X    world->InsertTransient(this, underlying, x, y, Center);
X}
X
X/*
X * Disappear removes the DialogBox.  Since the user should see
X * warnings only once, Disappear clears the warning's text so the next
X * PopUp won't display it.
X */
X
Xvoid DialogBox::Disappear () {
X    Parent()->Remove(this);
X    SetWarning();
X    Sync();
X}
X
X/*
X * Messager creates its button state and initializes its view.
X */
X
XMessager::Messager (Interactor* u, const char* msg) : (u, msg) {
X    ok = new ButtonState(false);
X    okbutton = new PushButton("  OK  ", ok, true);
X    Init();
X}
X
X/*
X * Free storage allocated for the message's button state.
X */
X
XMessager::~Messager () {
X    Unref(ok);
X}
X
X/*
X * Display pops up the Messager and removes it when the user
X * acknowledges the message.
X */
X
Xvoid Messager::Display () {
X    ok->SetValue(false);
X
X    PopUp();
X
X    int okay = false;
X    while (!okay) {
X	Event e;
X	Read(e);
X	if (e.eventType == KeyEvent && e.len > 0) {
X	    switch (e.keystring[0]) {
X	    case '\r':		/* CR */
X	    case '\007':	/* ^G */
X		ok->SetValue(true);
X		break;
X	    default:
X		break;
X	    }
X	} else if (e.target == okbutton) {
X	    e.target->Handle(e);
X	}
X	ok->GetValue(okay);
X    }
X
X    Disappear();
X}
X
X/*
X * Init composes Messager's view with boxes, glue, and frames.
X */
X
Xvoid Messager::Init () {
X    SetClassName("Messager");
X
X    VBox* vbox = new VBox;
X    vbox->Align(Center);
X    vbox->Insert(new VGlue);
X    vbox->Insert(warning);
X    vbox->Insert(new VGlue);
X    vbox->Insert(message);
X    vbox->Insert(new VGlue);
X    vbox->Insert(okbutton);
X    vbox->Insert(new VGlue);
X
X    Insert(new Frame(vbox, 2));
X}
X
X/*
X * Reconfig pads Messager's shape to make the view look less crowded.
X */
X
Xvoid Messager::Reconfig () {
X    DialogBox::Reconfig();
X    Font* font = output->GetFont();
X    shape->width += 2 * font->Width("mmmm");
X    shape->height += 4 * font->Height();
X}
X
X/*
X * Confirmer creates its button states and initializes its view.
X */
X
XConfirmer::Confirmer (Interactor* u, const char* prompt) : (u, prompt) {
X    yes		 = new ButtonState(false);
X    no		 = new ButtonState(false);
X    cancel	 = new ButtonState(false);
X    yesbutton    = new PushButton(" Yes  ", yes, true);
X    nobutton     = new PushButton("  No  ", no, true);
X    cancelbutton = new PushButton("Cancel", cancel, true);
X    Init();
X}
X
X/*
X * Free storage allocated for the button states.
X */
X
XConfirmer::~Confirmer () {
X    Unref(yes);
X    Unref(no);
X    Unref(cancel);
X}
X
X/*
X * Confirm pops up the Confirmer, lets the user confirm the message or
X * not, removes the Confirmer, and returns the confirmation.
X */
X
Xchar Confirmer::Confirm () {
X    yes->SetValue(false);
X    no->SetValue(false);
X    cancel->SetValue(false);
X
X    PopUp();
X
X    int confirmed = false;
X    int denied = false;
X    int cancelled = false;
X    while (!confirmed && !denied && !cancelled) {
X	Event e;
X	Read(e);
X	if (e.eventType == KeyEvent && e.len > 0) {
X	    switch (e.keystring[0]) {
X	    case 'y':
X	    case 'Y':
X		yes->SetValue(true);
X		break;
X	    case 'n':
X	    case 'N':
X		no->SetValue(true);
X		break;
X	    case '\r':		/* CR */
X	    case '\007':	/* ^G */
X		cancel->SetValue(true);
X		break;
X	    default:
X		break;
X	    }
X	} else if (e.target == yesbutton || e.target == nobutton ||
X		   e.target == cancelbutton)
X	{
X	    e.target->Handle(e);
X	}
X	yes->GetValue(confirmed);
X	no->GetValue(denied);
X	cancel->GetValue(cancelled);
X    }
X
X    Disappear();
X
X    char answer = 'n';
X    answer = confirmed ? 'y' : answer;
X    answer = cancelled ? 'c' : answer;
X    return answer;
X}
X
X/*
X * Init composes Confirmer's view with boxes, glue, and frames.
X */
X
Xvoid Confirmer::Init () {
X    SetClassName("Confirmer");
X
X    HBox* buttons = new HBox;
X    buttons->Insert(new HGlue);
X    buttons->Insert(yesbutton);
X    buttons->Insert(new HGlue);
X    buttons->Insert(nobutton);
X    buttons->Insert(new HGlue);
X    buttons->Insert(cancelbutton);
X    buttons->Insert(new HGlue);
X
X    VBox* vbox = new VBox;
X    vbox->Align(Center);
X    vbox->Insert(new VGlue);
X    vbox->Insert(warning);
X    vbox->Insert(new VGlue);
X    vbox->Insert(message);
X    vbox->Insert(new VGlue);
X    vbox->Insert(buttons);
X    vbox->Insert(new VGlue);
X
X    Insert(new Frame(vbox, 2));
X}
X
X/*
X * Reconfig pads Confirmer's shape to make the view look less crowded.
X */
X
Xvoid Confirmer::Reconfig () {
X    DialogBox::Reconfig();
X    Font* font = output->GetFont();
X    shape->width += 4 * font->Width("mmmm");
X    shape->height += 4 * font->Height();
X}
X
X/*
X * Namer creates its button states and initializes its view.
X */
X
XNamer::Namer (Interactor* u, const char* prompt) : (u, prompt) {
X    accept = new ButtonState(false);
X    cancel = new ButtonState(false);
X    acceptbutton = new PushButton("  OK  ", accept, true);
X    cancelbutton = new PushButton("Cancel", cancel, true);
X    const char* sample = "                                                 ";
X    stringeditor = new StringEditor(accept, sample, "\007\015");
X    stringeditor->Message("");
X    Init();
X}
X
X/*
X * Free storage allocated for the button states.
X */
X
XNamer::~Namer () {
X    Unref(accept);
X    Unref(cancel);
X}
X
X/*
X * Edit pops up the Namer, lets the user edit the given string,
X * removes the Namer, and returns the edited string unless the user
X * cancelled it.
X */
X
Xchar* Namer::Edit (const char* string) {
X    accept->SetValue(false);
X    cancel->SetValue(false);
X    if (string != nil) {
X	stringeditor->Message(string);
X    }
X    stringeditor->Select(0, strlen(stringeditor->Text()));
X
X    PopUp();
X
X    int accepted = false;
X    int cancelled = false;
X    while (!accepted && !cancelled) {
X	stringeditor->Edit();
X	accept->GetValue(accepted);
X	if (accepted == '\007') {
X	    accept->SetValue(false);
X	    cancel->SetValue(true);
X	} else if (accepted == '\015') {
X	    accept->SetValue(true);
X	    cancel->SetValue(false);
X	} else {
X	    Event e;
X	    Read(e);
X	    if (e.target == acceptbutton || e.target == cancelbutton) {
X		e.target->Handle(e);
X	    }
X	}
X	accept->GetValue(accepted);
X	cancel->GetValue(cancelled);
X    }
X
X    Disappear();
X
X    char* result = nil;
X    if (accepted) {
X	const char* text = stringeditor->Text();
X	if (text[0] != '\0') {
X	    result = strdup(text);
X	}
X    }
X    return result;
X}
X
X/*
X * Init composes Namer's view with boxes, glue, and frames.
X */
X
Xvoid Namer::Init () {
X    SetClassName("Namer");
X
X    HBox* hboxedit = new HBox;
X    hboxedit->Insert(new HGlue(5, 0, 0));
X    hboxedit->Insert(stringeditor);
X    hboxedit->Insert(new HGlue(5, 0, 0));
X
X    VBox* vboxedit = new VBox;
X    vboxedit->Insert(new VGlue(2, 0, 0));
X    vboxedit->Insert(hboxedit);
X    vboxedit->Insert(new VGlue(2, 0, 0));
X
X    HBox* buttons = new HBox;
X    buttons->Insert(new HGlue);
X    buttons->Insert(acceptbutton);
X    buttons->Insert(new HGlue);
X    buttons->Insert(cancelbutton);
X    buttons->Insert(new HGlue);
X
X    VBox* vbox = new VBox;
X    vbox->Align(Center);
X    vbox->Insert(new VGlue);
X    vbox->Insert(warning);
X    vbox->Insert(new VGlue);
X    vbox->Insert(message);
X    vbox->Insert(new VGlue);
X    vbox->Insert(new Frame(vboxedit, 1));
X    vbox->Insert(new VGlue);
X    vbox->Insert(buttons);
X    vbox->Insert(new VGlue);
X    vbox->Propagate(false);	/* for reshaping stringeditor w/o looping */
X
X    Insert(new Frame(vbox, 2));
X}
X
X/*
X * Reconfig pads Namer's shape to make the view look less crowded.
X */
X
Xvoid Namer::Reconfig () {
X    DialogBox::Reconfig();
X    Shape s = *stringeditor->GetShape();
X    s.Rigid();
X    stringeditor->Reshape(s);
X    Font* font = output->GetFont();
X    shape->width += 2 * font->Width("mmmm");
X    shape->height += 4 * font->Height();
X}
X
X/*
X * Helper function for Finder.
X */
X
Xstatic const char* abspath (const char* file = nil) {
X    const int bufsize = MAXPATHLEN+1;
X    static char buf[bufsize];
X
X    getcwd(buf, bufsize);
X    strcat(buf, "/");
X
X    if (file != nil) {
X        strcat(buf, file);
X    }
X    return buf;
X}
X
XFinder::Finder (
X    Interactor* u, const char* t
X) : (new ButtonState, abspath(), 10, 24, Center) {
X    underlying = u;
X    Init("", t);
X    Insert(Interior());
X}
X
Xstatic const char* ChdirIfNecessary (Finder* finder) {
X    static char buf[MAXPATHLEN+1];
X    const char* filename = finder->Choice();
X    strcpy(buf, filename);
X    char* bufptr = strrchr(buf, '/');
X
X    if (bufptr != NULL) {
X        *bufptr = '\0';
X        if (chdir(buf) == 0) {
X            filename = ++bufptr;
X            finder->Message(abspath(filename));
X        }
X    }
X    finder->SelectFile();
X    return filename;
X}            
X
Xconst char* Finder::Find () {
X    const char* name = nil;
X    Event e;
X    if (Popup(e)) {
X	name = ChdirIfNecessary(this);
X    }
X    return name;
X}
X
XInteractor* Finder::Interior () {
X    return new Frame(FileChooser::Interior(" Open "), 2);
X}
X
Xboolean Finder::Popup (Event&, boolean) {
X    World* world = underlying->GetWorld();
X    Coord x, y;
X    underlying->Align(Center, 0, 0, x, y);
X    underlying->GetRelative(x, y, world);
X    world->InsertTransient(this, underlying, x, y, Center);
X    boolean accepted = Accept();
X    world->Remove(this);
X    SetTitle("");
X    return accepted;
X}
END_OF_FILE
if test 13155 -ne `wc -c <'dialogbox.c'`; then
    echo shar: \"'dialogbox.c'\" unpacked with wrong size!
fi
# end of 'dialogbox.c'
fi
if test -f 'ivinfo.texinfo' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ivinfo.texinfo'\"
else
echo shar: Extracting \"'ivinfo.texinfo'\" \(13687 characters\)
sed "s/^X//" >'ivinfo.texinfo' <<'END_OF_FILE'
X\input texinfo   @c -*-texinfo-*-      
X
X@setfilename ivinfo-info
X@settitle Ivinfo
X
X@ifinfo
XCopyright @copyright{} 1991 Harris Computer Systems Division
X@end ifinfo
X@titlepage
X@sp 10
X
X@title Ivinfo
X@subtitle An X-window based info browser
X@subtitle written using InterViews
X
X@author Tom Horsley
X
X@page
X@vskip 0pt plus 1filll
XCopyright @copyright{} 1991 Harris Computer Systems Division
X@end titlepage
X@node    Top, Tutorial, (dir), (dir)
X
X@ifinfo
XThis document describes the X-window info browser. Typing an @kbd{h} while
Xrunning @code{ivinfo} gets you to this summary page. From here you can
Xaccess additional help describing the ivinfo program and advanced features
Xnot listed here.
X
XClicking your left mouse button while the pointer is in one of the highlighted
Xregions will take you to a new section of the manual. If you want to enter
Xthe tutorial, click on the following highlighted word: @ref{Tutorial}.
X
XYou may also move around the document by using one of the following keystrokes:
X@table @kbd
X@item h
XThe help key brings up this page of the document.
X@item n
XMove to the next node.
X@item p
XMove to the previous node.
X@item u
XMove up one level in the document hierarchy.
X@item l
XMove to the last node you were at (this is the letter ell not the number one).
X@item q
XQuit ivinfo, terminate the program.
X@item g
XPop up a dialog window to prompt for a node name and go directly
Xto that node.
X@item o
XPop up a file browser to prompt for a file name and go to the
Xtop node in that file.
X@item d
XGo to the node named @file{(dir)} (the root node of all the info
Xdocumentation).
X@item t
XGo to the @file{Top} node of the current document.
X@item s
XPop up a dialog window to prompt for a regular expression to search
Xfor in the document.
X@end table
X@end ifinfo
X
X@menu
X* Tutorial::                    Tutorial
X* Info Navigation::             Info Navigation
X* Node History::                Node History
X* Quitting::                    Quitting
X* Advanced Navigation::         Advanced Navigation
X* Shortcuts::                   Shortcuts
X* Cut and Paste::               Cut and Paste
X* Horizontal Scrolling::        Horizontal Scrolling
X* Resources and Options::       Resources and Options
X* Other Documentation::         Other Documentation
X@end menu
X
X@node Tutorial, Info Navigation, Top, Top
X@chapter Tutorial
X
XThis tutorial assumes you are reading it from the @code{ivinfo} program.
XThe first thing you should do is get familiar with all the ways to scroll
Xthe window.
X
XIf hold down the middle mouse button, a hand cursor will appear, and you can
Xshove the text around by `grabbing' it with the hand and moving it.
X
XIf you hold down the right mouse button, a double arrow will appear. If you
Xmove the mouse down a little from the point where you first pressed the button,
Xthe double arrow will switch to pointing down, and the text will begin to
Xscroll down as long as you have the button pressed. The farther you move the
Xmouse away from the original location, the faster the text will scroll.
X
XIf you move the mouse back to the original location and then start moving it
Xup, the text will start scrolling in the other direction.
X
XTo the right of the main text window is a scroll bar. You can grab the scroll
Xbar with a mouse button and reposition it. The text will then
Ximmediately scroll directly to that relative position in the node. If you
Xhold down the control key at the same time you are moving the scroll bar,
Xthe text will move along with the scroll bar.
X
XAt the top and bottom of the scroll bar, some tiny arrows appear. You can
Xclick on these arrows to scroll the text one line at a time, or hold down
Xthe mouse button to continuously scroll the text.
X
XFinally, if all those techniques are not enough, there are several
Xkeystrokes you can use for scrolling.  The @kbd{b} and @kbd{Home} keys
Xwill scroll to the beginning of the node. The @kbd{SPC} (space) or
X@kbd{Page Down} keys will go to the next page and the @kbd{DEL} (Delete)
Xor @kbd{Page Up} keys will go back to previous page.
X
XYou should now type an @kbd{n} to get to the next page of the tutorial.
X
X@node Info Navigation, Node History, Tutorial, Top
X@chapter Info Navigation
X
XAll the highlighted regions of text represent links to other areas of the
Xdocument. The primary means for navigating through the document is by
Xclicking the left mouse button on one of these links.
X
XThe first line in each node of an info document contains the name of the
Xnode and some special links to other nodes. These are the @code{next},
X@code{prev}, and @code{up} links (not every node has all of these defined).
XThese special links organize an info document in a hierarchy much like
Xa book, with sections making up a chapter, subsections making up a section, etc.
X(You may need to widen your window to see the whole first line, some
Xnode names get pretty long).
X
XThe @code{next} link points to the next node at the same level in the
Xhierarchy and the @code{prev} link points to the previous node at the
Xsame level. The @code{up} link moves up to the next higher level.
X
XYou can follow these special links using the @kbd{n}, @kbd{p}, and @kbd{u}
Xkeys.
X
XBesides the special links in the header, links to other nodes may be
Xscattered throughout the body of a node. These links are either menus
X(much like a table of contents in a book) or cross references. There are
Xno keystrokes to follow these links. You must click on one of these with
Xthe left mouse button in order to follow it to the new node.
X
XType @kbd{n} now to read about how to get back to where you came from.
X
X@node Node History, Quitting, Info Navigation, Top
X@chapter Node History
X
XEach time you follow a link to a new node @code{ivinfo} remembers where
Xyou were in the document. If you ever want to get back where you came from,
Xyou can use the @kbd{l} key (@kbd{l} is the letter ell, not the number one).
X
XThis command is an abbreviation for @kbd{last}, and says take me to the
Xnode I was last at.
X
XYou can use @kbd{l} as many times as you want to keep backing up through
Xthe document to get where you came from. Each time you back up, @code{ivinfo}
Xforgets you ever visited that node --- there is no corresponding ``go
Xforward again'' command available.
X
XNote that the @kbd{l} (last) command is very different from the @kbd{p} (prev)
Xcommand. The @kbd{l} command remembers the exact path you traversed while
Xreading through the document. The @kbd{p} command simply goes to the previous
Xnode in the document hierarchy, it doesn't care where you came from.
X
XType @kbd{n} now to to read about the most important command.
X
X@node Quitting, Advanced Navigation, Node History, Top
X@chapter Quitting
X
XProbably the most important thing to learn about any program is how to
Xmake it go away. In @code{ivinfo}, all you have to do is type @kbd{q}.
XThis will pop up a box and ask if you really meant that, and you can
Xclick on yes or no.
X
XThis concludes the tutorial sections of the document. The remainder of
Xthe document describes various advanced commands. You should now know
Xenough to navigate through it on your own.
X
X@node Advanced Navigation, Shortcuts, Quitting, Top
X@chapter Advanced Navigation
X
XThe root of all the info documentation is a node named @code{(dir)}.
XThe @kbd{d} command can be used to go directly to this root node.
X
XBy convention, all info documents have a node named @code{Top}.
XThe @kbd{t} command can be used to go directly to the @code{Top}
Xnode of the current document.
X
XThere may come a time when you wish to examine two separate nodes at the
Xsame time. Rather than starting two copies of @code{ivinfo}, you can
Xsimply tell @code{ivinfo} to create another window. If you hold down the
X@kbd{Meta} key (labeled @code{Alt} on many keyboards) when typing
Xany of the normal navigation commands, then @code{ivinfo} will create a
Xnew window and place the the new node in that window.
X
XYou can make a window go away using the @kbd{c} (for close) command.
XIf you use @kbd{c} and there is only one window, it acts just like @kbd{q}.
X
XYou can search for regular expressions in a document by hitting the @kbd{s}
Xkey. This will pop up a window and prompt you for the pattern to search for.
XIf you just leave the previous pattern in place, it will search for the
Xnext occurrence of the same pattern (for a faster
Xway to search again see @pxref{Shortcuts}).
X
XThe text cursor (a vertical bar) is placed immediately following the
Xmatching pattern. The search command may or may not go to a new node
Xin the document, it all depends on where the next match is found.
X
XThe @kbd{g} command will pop up a window and ask you for a node name.
XThis allows you to go directly to any node by name. This can be used
Xto go to nodes in other files by using the @code{(filename)node name}
Xsyntax for a fully specified node name.
X@inforef{Expert, Node name syntax, info}, for a description of
Xthe syntax used for node names.
X
XSometimes it is not convenient to type a full path name for a @kbd{g}
Xcommand. The @kbd{o} command can be used to pop up a file browser
Xwindow to select a file name. Once you pick a file, @code{ivinfo}
Xautomatically goes to the @file{Top} node in that file.
X
XIf the file does not have a @file{Top} node, then it treats the whole
Xfile like one big node and views the entire file. This means you can use
X@code{ivinfo} to look at any arbitrary file, but you will probably have
Xto use the @code{l}, @code{g}, or @code{o} commands to get out of it.
X
X@node Shortcuts, Cut and Paste, Advanced Navigation, Top
X@chapter Shortcuts
X
XIf you know you really want to quit, it is a pain to wait for the dialog
Xbox to pop up so you can click on the yes button.  You can get around
Xthis by holding down the @kbd{Meta} key when typing either of the @kbd{q}
Xor @kbd{c} commands. This will close a window or quit immediately
Xwithout asking if you really meant that.
X
XA similar shortcut is available for searching --- @kbd{Meta-s} will search
Xfor the last pattern again without popping up a dialog box to query you
Xfor a new regular expression.
X
X@node Cut and Paste, Horizontal Scrolling, Shortcuts, Top
X@chapter Cut and Paste
X
XMany documents contain example code or commands. Sometimes you want to
Xcopy these examples into a program or script to use as a starting
Xplace for your own project. You can select a region of text in an @code{ivinfo}
Xwindow by holding down the left mouse button and moving the mouse.
X
XThis selected text goes in the X cut buffer zero where it can be pasted
Xinto another window (such as an xterm or emacs window).
X
XSince the left mouse button is also used to follow links, make sure you
Xinitially press the button while the mouse pointer is outside of any
Xhighlighted link area.
X
X@node Horizontal Scrolling, Resources and Options, Cut and Paste, Top
X@chapter Horizontal Scrolling
X
XA feature of the @code{InterViews} toolkit (@code{ivinfo} is written
Xusing InterViews), is horizontal scrolling. If you are selecting text
Xby holding down the left mouse button (see @pxref{Cut and Paste}) and
Xyou move the mouse all the way to the right side of the window, then
Xthe text will scroll horizontally (you can scroll it back by moving
Xthe mouse to the left side of the window).
X
XThis feature is not really useful, but you can sometimes do it
Xaccidentally, so it is described here so you will know what happened.
XYou may also want to use it as an alternative to expanding the window to
Xmake the end of a long line visible.
X
X@node Resources and Options, Other Documentation, Horizontal Scrolling, Top
X@chapter Resources and Options
X
XThis chapter documents the command line options used to invoke @code{ivinfo}
Xas well as the resources and environment variables that can modify its
Xbehavior.
X
X@deffn Command ivinfo @code{[-r]} @file{[node name]}@dots{}
X
X@table @code
X@item -r
XThe @code{-r} option is used to get a reverse video window for @code{ivinfo}.
X@item node name
XAn optional list of node names may be given on the command line. @code{Ivinfo}
Xstarts up with one window per node.
X@end table
X@end deffn
X
XThe following resources may be specified in your @file{.Xdefaults} file:
X
X@table @code
X@item ivinfo*path
XThis is a search path for info files. It should be a colon separated list
Xof directory names where info files may be found.
X@item ivinfo*reverseVideo
XSpecify the value @code{on} to make @code{ivinfo} use reverse video for
Xits windows. (@code{Off} is the default).
X@item ivinfo*font
XSelect the default font to use for the windows.
X@end table
X
X@code{Ivinfo} will first look for the @code{path} resource, if that is
Xnot specified it will read the INFO_PATH environment variable to get the
Xsearch path for info files. If neither the path resource or the
XINFO_PATH variables is set, @code{ivinfo} will use
X@file{/usr/lib/emacs/info:.} as its search path.
X
X@node Other Documentation,  , Resources and Options, Top
X@chapter Other Documentation
X
XThe info document format was initially designed for the online documentation
Xfor GNU emacs. @inforef{Help, ,info}, for the emacs tutorial.
X@inforef{Top, ,info}, for general information on info files.
X
XThe texinfo macro package is usually used to generate info files. This
Xpackage allows the same source file to be used to generate a typeset
Xhardcopy as well as an online info file
X(@pxref{Top, The Texinfo Manual, Overview, texinfo.info, The Texinfo Manual},
Xfor details).
X
XIf you are interested in incorporating info as an online help system in
Xa new software product, you may want to examine the source code for
X@code{ivinfo}. The code is all written in C++ and the @code{info} class
Xis independent of the rest of the @code{ivinfo} program, so it may be
Xeasily used in other programs.
X
X@inforef{*, Info Class Header, info.h}.
X
X@inforef{*, Info Class Body, info.c}.
X
X@inforef{*, ivinfo, ivinfo.c}.
X
X@bye
END_OF_FILE
if test 13687 -ne `wc -c <'ivinfo.texinfo'`; then
    echo shar: \"'ivinfo.texinfo'\" unpacked with wrong size!
fi
# end of 'ivinfo.texinfo'
fi
echo shar: End of archive 2 \(of 4\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 4 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 4 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
======================================================================
domain: tahorsley@csd.harris.com       USMail: Tom Horsley
  uucp: ...!uunet!hcx1!tahorsley               511 Kingbird Circle
                                               Delray Beach, FL  33444
+==== Censorship is the only form of Obscenity ======================+
|     (Wait, I forgot government tobacco subsidies...)               |
+====================================================================+

exit 0 # Just in case...
-- 
Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
Sterling Software, IMD           UUCP:     uunet!sparky!kent
Phone:    (402) 291-8300         FAX:      (402) 291-4362
Please send comp.sources.misc-related mail to kent@uunet.uu.net.