[comp.lang.c++] An InterViews example

bp@dolphin.cis.ufl.edu (Brian Pane) (08/10/90)

Well, nobody seems to know of an existing InterViews tutorial.  I've
managed to progress a bit by studying the man pages and sample programs,
though, and I've created a trivial but perhaps useful application that
uses several of the InterViews classes.  It's called ipipe and is invoked
with:
	ipipe command_line {more command lines}
It creates a window for each argument, displaying the output generated by
executing that argument from a shell.  Above the output is a button which
can be pressed to repeat the execution of the command.  I use it primarily
in the form: ipipe "ps -auxww"; this way, when I feel that the system
is running too slowly, I can simply click the button to see who's consuming
all of my CPU time with a game of xtank.

I know this newsgroup is not comp.sources.interviews, but I'm posting
my program because enough people sent mail in response to my previous
documentation query to indicate sufficient interest in small, clear
InterViews example programs.  While my code is rather primitive, I
offer it to the group in hope that somebody will find it somehow useful.

You'll probably have to edit the Makefile before compiling.  I apologize
for its nonportability and inelegance, but I haven't had time to study
make or imake in depth; schoolwork doesn't leave much time for education. :-)

If you have any comments (like "stop wasting net bandwidth, you idiot"),
suggestions, or code patches, please e-mail them; I'll be out of town for
a week, and news ages quickly.

-------------------------------------------------------------------------
Brian Pane	University of Florida Department of Computer Science
bp@beach.cis.ufl.edu		Class of 1991

"If you can keep your expectations       |#ifdef OFFENDED_ANYONE
 tiny, you'll go through life            |#  include "disclaimer.h"
 without being so whiny" - Matt Groening |#endif
-------------------------------------------------------------------------

#!/bin/sh
# This is a shell archive (shar 3.32)
# made 08/10/1990 14:32 UTC by bp@dolphin
# Source directory /net/manatee/1/bp/studies
#
# existing files WILL be overwritten
#
# This shar contains:
# length  mode       name
# ------ ---------- ------------------------------------------
#   1112 -rw-r--r-- ipipe.h
#   2222 -rw-r--r-- ipipe.cc
#   1145 -rw-r--r-- main.cc
#    335 -rw-r--r-- Makefile
#
if touch 2>&1 | fgrep 'amc' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
# ============= ipipe.h ==============
echo "x - extracting ipipe.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > ipipe.h &&
X// ipipe class declaration
X//
X// (c) 1990 by Brian F. Pane
X// May be freely distributed and modified, but not sold.
X
X#ifndef IPIPE_H
X#define IPIPE_H
X#include <InterViews/box.h>
X#include <InterViews/button.h>
X#include <InterViews/frame.h>
X#include <InterViews/textbuffer.h>
X#include <InterViews/texteditor.h>
X#include <InterViews/scroller.h>
X
X
Xclass Ipipe: public MonoScene;
X
Xclass ClickButton: public PushButton {
Xprivate:
X  Ipipe* parent;
X
Xpublic:
X  ClickButton(char* str, ButtonState* button_state, int value,
X	      Ipipe* parent_ptr)
X    :PushButton(str, button_state, value)
X  {
X    parent = parent_ptr;
X  }
X  void Press();
X};
X
X
Xclass Ipipe: public MonoScene {
Xfriend class ClickButton;
Xprivate:
X  const int BUFFER_SIZE = 10000;
X  char pipe_text[BUFFER_SIZE];
X  TextBuffer*   pipe_text_buffer;
X  TextEditor*   pipe_text_editor;
X  VScroller*    pipe_text_vscroller;
X  HScroller*    pipe_text_hscroller;
X  ButtonState*  go_button_state;
X  ClickButton*  go_button;
X  Frame*   outer_level;
X  VBox*    v_box;
X  HBox*    h_box;
X
X  void go();
X
Xpublic:
X  Ipipe(char*);
X  ~Ipipe();
X
X  char* command_line;
X};
X
X#endif
SHAR_EOF
$TOUCH -am 0810101390 ipipe.h &&
chmod 0644 ipipe.h ||
echo "restore of ipipe.h failed"
set `wc -c ipipe.h`;Wc_c=$1
if test "$Wc_c" != "1112"; then
	echo original size 1112, current size $Wc_c
fi
# ============= ipipe.cc ==============
echo "x - extracting ipipe.cc (Text)"
sed 's/^X//' << 'SHAR_EOF' > ipipe.cc &&
X// ipipe class implementation
X//
X// (c) 1990 by Brian F. Pane
X// May be freely distributed and modified, but not sold.
X
X
X#include "ipipe.h"
X#include <InterViews/Std/string.h>
X#include <InterViews/Std/stdio.h>
X
X
X// Called when you click the button containing the ipipe's command line:
X//
Xvoid ClickButton::Press()
X{
X  parent->go();
X}
X
X
X// Constructor for class Ipipe:
X//   Creates interactors for button, text buffer/editor pair, scrollbars,
X//   and enclosing boxes and frame
X//
XIpipe::Ipipe(char* prog_name) : MonoScene()
X{
X  command_line = new char[strlen(prog_name) + 1];
X  strcpy(command_line, prog_name);
X  pipe_text_buffer = new TextBuffer(pipe_text, 0, BUFFER_SIZE);
X  pipe_text_editor = new TextEditor(10, 80, 8, 0);
X  pipe_text_editor->Edit(pipe_text_buffer);
X  pipe_text_vscroller = new VScroller(pipe_text_editor);
X  pipe_text_hscroller = new HScroller(pipe_text_editor);
X  go_button_state = new ButtonState(false);
X  go_button = new ClickButton(command_line, go_button_state, true, this);
X  h_box = new HBox(pipe_text_vscroller, pipe_text_editor);
X  v_box = new VBox(go_button,
X		   h_box,
X		   pipe_text_hscroller
X		  );
X  outer_level = new Frame(v_box);
X  Insert(outer_level);
X  go();
X}
X
X
X// The destructor simply deallocates all the space allocated by the
X// constructor:
X//
XIpipe::~Ipipe()
X{
X  delete go_button;
X  delete go_button_state;
X  delete pipe_text_editor;
X  delete pipe_text_buffer;
X  delete pipe_text_vscroller;
X  delete pipe_text_hscroller;
X  delete v_box;
X  delete h_box;
X  delete outer_level;
X}
X
X
X
X// The go() member function executes the ipipe's command_line and inserts
X// the output into the text editor.
X//
Xvoid Ipipe::go()
X{
X  char input_buffer[81];
X  pipe_text_editor->BeginningOfText();
X  pipe_text_editor->DeleteText(pipe_text_buffer->Length());
X  pipe_text_buffer->Delete(0,BUFFER_SIZE);
X  FILE* pipe = popen(command_line, "r");
X  if (pipe == NULL)
X  {
X    pipe_text_editor->InsertText(command_line, strlen(command_line));
X    pipe_text_editor->InsertText(": cannot execute", 16);
X  }
X  else
X  {
X    while (fgets(input_buffer, 80, pipe) != NULL)
X      pipe_text_editor->InsertText(input_buffer, strlen(input_buffer));
X    (void)pclose(pipe);
X  }
X  go_button_state->SetValue(false);
X}
SHAR_EOF
$TOUCH -am 0810102790 ipipe.cc &&
chmod 0644 ipipe.cc ||
echo "restore of ipipe.cc failed"
set `wc -c ipipe.cc`;Wc_c=$1
if test "$Wc_c" != "2222"; then
	echo original size 2222, current size $Wc_c
fi
# ============= main.cc ==============
echo "x - extracting main.cc (Text)"
sed 's/^X//' << 'SHAR_EOF' > main.cc &&
X// A sample program using the ipipe class
X//
X// (c) 1990 by Brian F. Pane
X// May be freely distributed and modified, but not sold.
X
X
X
X#include <InterViews/Std/stream.h>
X#include <InterViews/interactor.h>
X#include <InterViews/world.h>
X#include <InterViews/message.h>
X#include "ipipe.h"
X
Xextern "C" {
Xvoid exit(int);
X}
X
X// void usage(char *program_name):
X//   Print a nasty error message if the user failed to specify a command
X//   to be piped
X//
Xvoid usage(char* program_name)
X{
X  cout << "Usage: " << program_name << " command_line {command_line}\n";
X}
X
X
X
Xint main(int argc, char* argv[])
X{
X  // Check that the user has actually specified one or more programs
X  // to be piped:
X  //
X  if (argc < 2)
X  {
X    usage(argv[0]);
X    exit(1);
X  }
X
X  // Create a world in which all of the InterViews display components will
X  // be built:
X  //
X  World* cruel_world = new World("Ipipe", argc, argv);
X
X  // Create an ipipe window to display the output of each command in the
X  // argument list:
X  //
X  for (int count = 1; count < argc; count++)
X    cruel_world->InsertApplication(new Ipipe(argv[count]));
X
X  // Accept user input:
X  cruel_world->Run();
X}
SHAR_EOF
$TOUCH -am 0810102990 main.cc &&
chmod 0644 main.cc ||
echo "restore of main.cc failed"
set `wc -c main.cc`;Wc_c=$1
if test "$Wc_c" != "1145"; then
	echo original size 1145, current size $Wc_c
fi
# ============= Makefile ==============
echo "x - extracting Makefile (Text)"
sed 's/^X//' << 'SHAR_EOF' > Makefile &&
X		CC = g++
X		LD = g++
X      IV_LIBRARIES = -lInterViewsX11 -lX11 -lm
X	   LDFLAGS = -L$(HOME)/lib $(IV_LIBRARIES)
X	    CFLAGS = -c -I$(HOME)/include
X
Xall:		ipipe
X
Xipipe:		ipipe.o main.o
X		$(LD) -o ipipe main.o ipipe.o  $(LDFLAGS)
X
Xipipe.o:	ipipe.cc ipipe.h
X		$(CC) $(CFLAGS) ipipe.cc
X
Xmain.o:		main.cc ipipe.h
X		$(CC) $(CFLAGS) main.cc
SHAR_EOF
$TOUCH -am 0810090790 Makefile &&
chmod 0644 Makefile ||
echo "restore of Makefile failed"
set `wc -c Makefile`;Wc_c=$1
if test "$Wc_c" != "335"; then
	echo original size 335, current size $Wc_c
fi
exit 0