This class is a completely functional line oriented text editor. It can edit any file with lines less than 300 characters wide that use a linefeed, carriage return, or combination of those to mark the end of each line.
While you need to create your own class derived from vTextEditor, your class can be very minimal. You will need to provide some service methods for the parent vCmdWindow, such as methods to open, read, save, and close files. Other than actually working with the real text source and providing that source to vTextEditor, you can get a fully functional text editor with no additional work.
However, vTextEditor has been designed to allow you to extend and add functionality to the editor if you need to. The vTextEditor also sends messages that will allow you to place various status messages on a status bar if you wish. The hard stuff is done for you. You don't need to worry about mouse movements, scroll bars or scroll messages, updating the screen, handling keystrokes, or anything else associated with actual editing. The vTextEditor class takes care of all those details, and provides a standard editing interface.
The following steps are required to use vTextEditor. First, you create an instance of your derived class from your vCmdWindow class, something like this:
...
// The Text Editor Canvas
vedCanvas = new vedTextEditor(this);
AddPane(vedCanvas);
...
// Show Window
ShowWindow();
vedCanvas->ShowVScroll(1); // Show Vert Scroll for vTextEditor
...
Your derived vTextEditor class should provide the methods
needed for opening and reading the text file you want to edit.
(Actually, you can edit any text source you wish.) VTextEditor
doesn't actually read or write any text itself. It maintains an
internal line buffer. (The default version of the internal buffer
is essentially limited by the amount of memory your system can
provide. The buffer methods can be overridden to provide totally
unlimited file size, if you wish.) The idea is to have your
application control where the text comes from, and then
add it a line at a time to the vTextEditor buffer.
You retrieve the text a line at a time when you want to save
the edited text. Thus, your if your code is working with
disk files, it can read the text a line at a time, and let
vTextEditor worry about the buffering.
The following code shows how to add the contents of a text file to the vTextEditor buffer, and display it in the canvas for the first time. Calls to vTextEditor methods are marked with **.
//===================>>> vedTextEditor::ReadFile <<<====================
int vedTextEditor::ReadFile(char* name)
{
const int maxBuff = 300; // Line length
char buff[maxBuff];
if (!name || !*name)
return 0;
ifstream inFile(name); // Open the file
if (!inFile)
return 0; // file not there
resetBuff(); // ** Tell vTextEditor to init buffer
while (inFile.getline(buff,maxBuff)) // read file
{
if (!addLine(buff)) // ** Add the line to the buffer
{
ERROR_MESSAGE("File too big -- only partially read.");
break;
}
}
inFile.close(); // Close the file
displayBuff(); // ** Now, display the buffer
return 1;
}
To load text into the editor buffer,
you first call resetBuff to initialize the
buffer, then add a line at a time with calls to addLine,
and finally display the text by calling displayBuff.
When your are editing (e.g., the user enters a Close command), you retrieve the text from the vTextEditor buffer with calls to getLine.
Then, to use the editor, you pass keystrokes from the KeyIn method of your vCmdWindow to the EditKeyIn method of the vTextEditor. EditKeyIn interprets the conventional meanings of the arrow keys, etc., and lets you edit the text in the buffer. You will also probably implement other commands, such as Find, by using the EditCommand method.
VTextEditor also calls several methods to notify of text state changes, such as current line, insert or overtype, etc. You can receive these messages by overriding the default methods, and display appropriate information on a status bar.
While vTextEditor is very complete, there are some things missing. The major hole is cut and paste support. This will be added when cut and paste support is added to V. There is also no real undo support. Maybe someday.
Note that the entire text buffer package can be overridden if you need to provide unlimited file size handling. You should examine the source code for vTextEditor to determine the specifications of the methods you'd need to override.
Each function supported by vTextEditor has an associated id (symbolically defined in v/vtexted.h), each beginning with ed. Many of the functions also take an associated value. Many editors allow a repetition count to be specified with many commands. For example, it is sometimes useful to be able to specify a command to move right some specific number of characters. The val parameter can be used to specify a value as desired. The only function that really need a value other than 1 (or -1 in the case of directional movement commands) is edLineGoto.
EditCommand returns 1 if the command was executed successfully, 0 if the command was recognized, but not successful (the find fails, for example), and -1 if the command was not recognized as valid.
At the time this manual was written, the following commands are supported. Because vTextEditor is evolving, it is likely more commands will be added. Check the v/vtexted.h file for specification of new editor commands. In the following descriptions, the note ``no val'' means that the val parameter is not used. A notation of ``+/-'' means the sign of val indicates direction.
...
static vMenu EditMenu[] = {
...
{"Find", edFind, isSens,notChk,noKeyLbl,noKey,noSub},
{"Find Next", edFindNext, isSens,notChk,noKeyLbl,noKey,noSub},
{"Find Matching Paren", edBalMatch, isSens,notChk,
noKeyLbl,noKey,noSub},
...
};
...
//===========>>> vedCmdWindow::WindowCommand <<<====================
void vedCmdWindow::WindowCommand(ItemVal id, ItemVal val,
CmdType cType)
{
switch (id)
{
...
default: // route unhandled commands through editor
{
if (vedCanvas->EditCommand(id, 1) < 0)
vCmdWindow::WindowCommand(id, val, cType);
break;
}
}
...
}
//====================>>> vedCmdWindow::KeyIn <<<====================
void vedCmdWindow::KeyIn(vKey keysym, unsigned int shift)
{
if (vedCanvas->EditKeyIn(keysym, shift) < 0)
vCmdWindow::KeyIn(keysym, shift);
}
The default implementation of EditKeyIn handles most of the standard keys, such as the arrow keys, the page keys, backspace, home, delete, insert, and end keys. It will also insert regular character keys into the text. It ignores function keys and non-printing control key values except tab and newline.
You can override this method to provide your own look and feel to the editor.
typedef struct edState
{
long changes, // count of changes
cmdCount; // how many times to repeat command
int
findAtBeginning, // leave find at beginning of pattern
fixed_scroll, // flag if using fixed scroll
ins_mode, // true if insert mode
counter, // counter for + insert
echof, // whether or not to echo action
tabspc, // tab spacing
wraplm; // right limit
} edState;
You can query and set the state with GetEdState and
SetEdState.