Logo Search packages:      
Sourcecode: aime version File versions  Download package

editor.cpp

/**********************************************************************
 ** Editor class: The editor class consists of objects designed to
 **               provide a feature-rich editing environment for
 **               editing multiple line fields
 **
 **
 **
 ** Last reviewed: version 0.14
 **
 **
 ** Copyright (C) 2000 George Noel (Slate)
 **
 **   This program is free software; you can redistribute it and/or modify
 **   it under the terms of the GNU General Public License as
 **   published by the Free Software Foundation; either version 2 of the 
 **   License, or any later version. 
 **
 **   This program is distributed in the hope that it will be useful, but 
 **   WITHOUT ANY WARRANTY; without even the implied warranty of 
 **   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
 **   General Public License for more details. 
 ** 
 **   You should have received a copy of the GNU General Public License 
 **   along with this program (in the docs dir); if not, write to the Free
 **   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
 **    
 **********************************************************************/


#ifndef NEWEDITOR_CC
#define NEWEDITOR_CC

#include "config.h"
#include "sysdep.h"
#include "editor.h"
#include "inp_handler.h"
#include "inp_funct.h"
#include "mud.h"
#include "builder.h"
#include "player.h"
#include "objtype.h"
#include "newfuncts.h"
#include "memchk.h"
#include "global.h"

Editor::Editor()
{   
    targetfile = NULL;
    targetstr  = NULL;
    eolmarkers = false;
    cur_line   = edit_buffer = NULL;
    linemarker = false;
    remove_newline = false;
    simple_mode = false;

}

Editor::Editor(char *thestring)
{    
    targetfile = NULL;
    targetstr  = NULL;
    eolmarkers = false;
    cur_line   = edit_buffer = NULL;
    linemarker = false;
    remove_newline = false;
    if (thestring != NULL)
       load_string(thestring);
    simple_mode = false;

}


Editor::Editor(FILE *thefile)
{  
    targetfile = NULL;
    targetstr  = NULL;
    eolmarkers = false;
    cur_line   = edit_buffer = NULL;
    linemarker = false;
    remove_newline = false;
    load_file(thefile);
    simple_mode = false;

}

Editor::~Editor()
{   reset_editor();
}

/*****************************************************************************
 * reset_editor - Resets the editor by removing the content and clearing
 *                the input buffer.
 *
 * Parameters - None
 * Returns      always 0
 **************************************************************************/
int Editor::reset_editor()
{  Edit_Line  *tmp_line;
 
   while (edit_buffer != NULL)
   {   tmp_line    = edit_buffer;
       edit_buffer = edit_buffer->next_line;
       delete_Edit_Line(tmp_line);
   } 
   cur_line = edit_buffer = NULL;

   //   if (targetstr != NULL)
   //       targetstr->truncate(0);

   if (targetfile != NULL)
       rewind(targetfile);

   last_command.truncate(0);
   return 0;   
}

/*****************************************************************************
 * stop_editor - Writes the data to the specified output source, but only
 *               if the player didnt abort.
 *
 * Parameters: - Abort = true if the player does not want to save thier data
 *                       false if the player wishes to safe the data.
 * Return value:
 *       0 
 ****************************************************************************/
int Editor::stop_editor(bool    abort)
{ 
     if (!abort)
     {  
          write_context();
     }     return reset_editor();
}

int Editor::start_editor(MudObject *the_User, Strings *tostr)
{    targetstr = tostr;

     return start_editor(the_User);
} 

int Editor::start_editor(MudObject *the_User, Strings *tostr, int rem_newline)
{    targetstr = tostr;
     if (rem_newline)
        remove_newline = true;
 
     return start_editor(the_User);
} 


void Editor::set_simple_mode()
{
   simple_mode = true;
} 


int Editor::start_editor(MudObject *the_User)
{  Inp_Handler *tmp_handler;
   Player      *plr_ptr = NULL;
   Builder     *bldr_ptr = NULL;
   Strings     *cur_prompt;
   
   cur_line = edit_buffer;
   cur_cmdmode = Command;
   cur_editmode = Append;

   switch (the_User->get_type()) {
   case OBJ_TYPE_BUILDER:
            bldr_ptr = (Builder *) the_User;
      tmp_handler = bldr_ptr->get_input_handler();
      /*cur_prompt  = bldr_ptr->get_prompt();*/
      cur_prompt = new Strings(EDITOR_PROMPT);
      bldr_ptr->send_bldr(EDITOR_HEADER);
            break;
   case OBJ_TYPE_PLAYER:
      plr_ptr = (Player *) the_User;
      tmp_handler = plr_ptr->get_input_handler();
      /*cur_prompt  = plr_ptr->get_prompt();*/
      cur_prompt = new Strings(EDITOR_PROMPT);
      plr_ptr->send_plr(EDITOR_HEADER);
            break;
   default:
      printf("blah1 in editor!\n");
      return -1;
   }
  
   if (bldr_ptr != NULL)
       bldr_ptr->send_bldr("Loading handler...\n"); 

   if (simple_mode)
   {
      tmp_handler->push_input_handler(editor_input_handler,NULL,0,
                                                HANDLER_DATA_EDITOR, 1);
      tmp_handler->set_data(this);
      set_cmdmode(Edit);
      set_editmode(Overwrite);
      if (bldr_ptr != NULL)
      {
         bldr_ptr->send_bldr("&+b[&+WOverwrite mode started&+b]&*\n");
         bldr_ptr->send_bldr(
                        "&+b[&+wType '.' on a new line to exit&+b]&*\n");
         print_linemarker(bldr_ptr->get_connection());
 
      }
      else
      {
         plr_ptr->send_plr("&+b[&+WOverwrite mode started&+b]&*\n");
         plr_ptr->send_plr(
                        "&+b[&+wType '.' on a new line to exit&+b]&*\n");
         print_linemarker(plr_ptr->get_connection());

      }

   }
   else
   {
      if (bldr_ptr != NULL)
      {
         bldr_ptr->send_bldr("Type '?' for help.\n");
      }
      else
      {
         plr_ptr->send_plr("Type '?' for help.\n");
      }
      tmp_handler->push_input_handler(editor_command_handler,cur_prompt,
                                                1,HANDLER_DATA_EDITOR, 1);
      tmp_handler->set_data((void *)this);
   }

   if (bldr_ptr != NULL)
       bldr_ptr->send_bldr("Input over to editor...\n"); 
   
   return 1;
}

/**************************************************************************
 * load_string - Loads a string into the editor.
 *
 * Parameters: a_str - The string to be loaded into the editor
 *
 * Returns : >= 0 If conversion was succesful. (return value will show how
 *                many lines have been read).
 *           -1   If failed (Allocation of lines)
 *
 * Loads the string into the editor by breaking the string up into seperate
 * lines and inserting each line after the other.
 *************************************************************************/
int Editor::load_string(char *a_str)
{   Edit_Line    *tmp_line;
    char    *p,*base;
    Strings tmp_str(a_str);
    int     num_lines = 0;

    if (a_str == NULL)
       return 0;

    edit_buffer = NULL;
    p = base = tmp_str.str_show();

    /* p will point to the end of the line, and base will point to the start
     * of the line.
     */
    while (p != NULL && *p != '\0')
    {   if (*p == '\r')
        {  
        }
        else if (*p == '\n')
        {  *p = '\0';           // Remove newline and mark it as end of line
           tmp_line = new_Edit_Line();

           if (tmp_line == NULL)
           {   /* Log error */
               return -1;
           }

           tmp_line->the_line.str_copy(base); // Copy from the base onward
           base = p + 1;                      // Move Base to next line
           add_line(EDITOR_ADD_LAST,tmp_line);
           num_lines++;
        }
        p++;                                  // Move to the next line;
    }

    /* Check to see if there is some text reamining in the string that
     * hasnt been put in a line yet.
     */
    if (base < p && p != NULL)
    {   tmp_line = new_Edit_Line();

        tmp_line->the_line.str_copy(base); 
        if (tmp_line->the_line.str_len() == 0)
            delete_Edit_Line(tmp_line);
        else
        {
            add_line(EDITOR_ADD_LAST,tmp_line);
            num_lines++;
        }
    }
    return num_lines;
}

/**************************************************************************
 * load_file - Loads a file into the editor.
 *
 * Parameters: fp - a pointer to the FILE that is to be loaded into the
 *                  editor
 *
 * Reads the contents of a file into the editor, by reading it in one line
 * at a time and adding these lines into the editor buffer.
 *
 * NOTE: At the moment the editor will always load the COMPLETE file, if
 *       this is not needed, we need to remove the rewind() call.
 *************************************************************************/
int Editor::load_file(FILE *fp)
{   char    a_line[512];
    Edit_Line    *tmp_line;
    Strings tmp_str;
    int     num_lines = 0;

    edit_buffer = NULL;

    rewind(fp);

    while (!feof(fp))
    {   fgets(a_line,512,fp);

        if (strlen(a_line) >= 511)
        {   tmp_str.str_cat(a_line);
            tmp_str.remove_returns();  
        }
        else  
        {   tmp_str.str_copy(a_line);
            tmp_str.remove_newline();
            tmp_line = new_Edit_Line();
            if (tmp_line == NULL)
            {   return -1;
            }

            tmp_line->the_line.str_copy(tmp_str.str_show());
            add_line(EDITOR_ADD_LAST,tmp_line);
            tmp_str.truncate(0);
            num_lines++;
        }
    }
    return num_lines; 
}


/***************************************************************************
 * add_line() - Adds a line to the editor buffer.
 *
 * Parameters: where - Describes how the line should be added, this can have
 *                     4 different values, being:
 *                     EDITOR_ADD_LAST  - Appends the line at the end of the
 *                                        buffer.
 *                     EDITOR_ADD_FIRST - Inserts the line at the front of
 *                                        the edit buffer.
 *                     EDITOR_ADD_APPEND- Appends the line after the current
 *                                        line, if the current line is NULL
 *                                        (End Of Buffer), then this mode
 *                                        will behave like EDITOR_ADD_LAST.
 *                     EDITOR_ADD_INSERT- Inserts the new line before the
 *                                        current line. If the current
 *                                        line is NULL (EOB), then this mode
 *                                        will behave like EDITOR_ADD_LAST.
 *             the_line - Pointer to the Line structure that needs to be
 *                        added to the buffer.
 *
 * Add_line uses a simple linked list of Line structures to build up the
 * editor buffer. 
 ***************************************************************************/
int Editor::add_line(int where, Edit_Line *the_line)
{  Edit_Line *tmp_ptr;

   tmp_ptr = edit_buffer;

   if (where == EDITOR_ADD_INSERT)
   {   if (cur_line == NULL)
          return add_line(EDITOR_ADD_LAST,the_line);
       else if (cur_line == edit_buffer)
       {   the_line->next_line = edit_buffer;
           edit_buffer = the_line;
       }
       else
       {   while (tmp_ptr != NULL && tmp_ptr->next_line != cur_line)
               tmp_ptr = tmp_ptr->next_line;

           if (tmp_ptr == NULL)
              return add_line(EDITOR_ADD_LAST,the_line);
           else
           {   the_line->next_line = tmp_ptr->next_line;
               tmp_ptr->next_line = the_line;
           }
       }
       return 1;
   }
   else if (where == EDITOR_ADD_APPEND)
   { 
       if (cur_line == NULL)
           return add_line(EDITOR_ADD_LAST,the_line);
       else
       {  
           the_line->next_line = cur_line->next_line; 
           cur_line->next_line = the_line;
       }
       return 1;
   }
   else if (where == EDITOR_ADD_FIRST)
   {   the_line->next_line = edit_buffer;
       edit_buffer = the_line;
       return 1;
   }

   /* Only thing that is left is the add last code, this is the default
    * really, so if none of the above failed .. then try this one.
    */
   if (tmp_ptr == NULL)
   {   edit_buffer = the_line;
       the_line->next_line = NULL;
       return 1;
   }

   /* Seek the last line in the edit buffer, or the line denoted by
    * where (Append After line xx)
    */
   if (where == EDITOR_ADD_LAST)
   {   while (tmp_ptr->next_line != NULL)
           tmp_ptr = tmp_ptr->next_line;
   }
   else while (where != 0 && tmp_ptr->next_line != NULL)
   {    tmp_ptr = tmp_ptr->next_line;
        where--;
   }

   /* Add the line here */
   the_line->next_line = tmp_ptr->next_line;
   tmp_ptr->next_line = the_line;
   return 1;
}

/*****************************************************************************
 * Write_context - method that will call the two other write methods who
 *                 actually store the content. This function is here so
 *                 you donthave to worry about what the target was.
 *
 * Parameters   - None
 * Return Value - 0 if the write failed for some reason
 *                <> 0 if the write succeeded 
 ***************************************************************************/
int Editor::write_context()
{    int retf, rets;

     retf = rets = 0;
     if (targetfile != NULL)
     {
        retf = write_context(targetfile);
     }
     if (targetstr != NULL)
     { 
        rets = write_context(targetstr);
     }
     return (rets < 0 || retf < 0);
}


/***************************************************************************
 * write_context - Writes the edit buffer into a file.
 *
 * Parameters: tostr : the string to which the text should be written.
 *
 **************************************************************************/
int Editor::write_context(Strings *tostr)
{  Strings *tmpptr;

   if (tostr == NULL)
      return EDITOR_NO_TARGET;

   tmpptr = get_context();
   if (tmpptr == NULL)
      return 0;

   tostr->str_copy(tmpptr->str_show());
   if (remove_newline == true)
      tostr->remove_newline();
   delete tmpptr;
   return 1;
}

/**************************************************************************
 * format_context - Formats the context into a certain length of line and
 *                  two spaces after punctuation, etc
 *
 * Returns: 1 for success, -1 for failure
 *
 *************************************************************************/
int Editor::format_context(void)
{
   static char *tmp_line = new char[ the_config.max_line_len + 10 ];
   Strings *tostr;
   Strings newstr;
   char    *str_ptr;
   char    *last_space;
   int     counter = 0;
   char    punctuation;
   int     word_remaining = 0;
   int     result_length = 0;

   if ((tostr = get_context()) == NULL)
     return -1;

   str_ptr = tostr->str_show();

   BZERO(tmp_line, the_config.max_line_len + 10);
   strcpy(tmp_line, "   ");

   last_space = str_ptr;
   punctuation = '\0';
   /* beginning of paragraph */
   while ((str_ptr) && (*str_ptr))
   {
      counter = 0;
      if (word_remaining)
      {
         strcat(tmp_line, last_space);
         if (punctuation != '-')
       {
            tmp_line[strlen(tmp_line)] = punctuation;
            strcat(tmp_line, " ");
       }
         strcat(tmp_line, " ");
         word_remaining = 0;
      }

      /* first go to the first non space in the string to indent */
      while ((*str_ptr) && 
             ((*str_ptr == ' ') || (*str_ptr == '\n') || (*str_ptr == '\r')))
         str_ptr++;

      /* now copy until we are at the end of the line */ 
      while ((*str_ptr) && (counter < the_config.max_line_len))
      {
         /* go to the beginning of the next word */
         while ((*str_ptr) && ((*str_ptr == ' ') || (*str_ptr == '\n') ||
                                                    (*str_ptr == '\r')))
       {
            str_ptr++;  
       }
         last_space = str_ptr;

         /* go to the end of this word */
         while ((*str_ptr) && (*str_ptr != '.') && (*str_ptr != '!') && 
                (*str_ptr != '?') && (*str_ptr != ' ') && 
                (*str_ptr != '\n') && (*str_ptr != '\r'))
         {
            str_ptr++;   
         }

         /* get rid of newlines, we make our own! */
         if ((*str_ptr == '\n') || (*str_ptr == '\r'))
            *str_ptr = ' ';

         /* if this is not a space, it must be punctuation, save it */
         if (*str_ptr != ' ')
            punctuation = *str_ptr;
         else
            punctuation = '-';

         /* now terminate the end of the word */
         if (*str_ptr)
       {
            *str_ptr = '\0';
            str_ptr++;
       }

         /* calculate how long the new line will be with this word */
         result_length = counter + (strlen(last_space) + 1);

         /* add punctuation length if we will have that too */
         if (punctuation != '-')
            result_length += 2;

         /* if we have room, add the new word */
         if (result_length < the_config.max_line_len)
       {
            strcat(tmp_line, last_space);
            if (punctuation != '-')
          {
               tmp_line[strlen(tmp_line)] = punctuation;
               strcat(tmp_line, " ");
          }
            strcat(tmp_line, " ");
            counter = strlen(tmp_line);
       }
         else
       {
            counter = the_config.max_line_len + 1;
            word_remaining = 1;
       }
      }
      counter = 0; 
      newstr.str_cat(tmp_line);
      newstr.str_cat("\n");
      BZERO(tmp_line, the_config.max_line_len + 10);
   }
   reset_editor();
   load_string(newstr.str_show());
   delete tostr;
   return 1;   
}

/***************************************************************************
 * get_context - Request the contents of the edit buffer. The return value
 *               Will be ONE string with newlines inserted to break up the
 *               string into its seperate lines.
 *
 * Parameters: none
 *************************************************************************/
Strings *Editor::get_context(void)
{   Strings    *tmp_ptr = NULL;
    Edit_Line  *lin_ptr;

    lin_ptr = edit_buffer;
    
    while (lin_ptr != NULL)
    {   if (tmp_ptr == NULL)
        {   tmp_ptr = new Strings();
            if (tmp_ptr == NULL)
               return NULL;
        }
        tmp_ptr->str_cat(lin_ptr->the_line.str_show());
        tmp_ptr->str_cat("\n");
        lin_ptr = lin_ptr->next_line;
    }

    return tmp_ptr;
}

/***************************************************************************
 * write_context - Writes the edit buffer into a file.
 *
 * Parameters: fp : the file in which the text should be written.
 *
 * NOTE: The file will not be truncated, but the text will be appended at
 *       the current position!
 **************************************************************************/
int Editor::write_context(FILE *fp)
{   Edit_Line *tmp_lin = edit_buffer;

    if (fp == NULL)
       return EDITOR_NO_TARGET;

    while (tmp_lin != NULL)
    {   fputs(tmp_lin->the_line.str_show(),fp);
        fputc((int)"\n",fp);
        tmp_lin = tmp_lin->next_line;
    }
    return 1; 
}

/***************************************************************************
 * show_context - Dump the editor to the current connection.
 *
 * Parameters: the_conn - The connection where the data should be dumped to
 **************************************************************************/
void Editor::show_context(Connection *the_conn)
{  Edit_Line *tmp_ptr = edit_buffer;
   Strings a_line;
   int  linenr = 1;

   while (tmp_ptr != NULL)
   {   a_line.sprintf("&+W%.2d&+B]&* %s\n",linenr++,tmp_ptr->the_line.str_show());
       the_conn->send_to_socket(a_line.str_show());
       tmp_ptr = tmp_ptr->next_line;
   }
}


/************************************************************************
 * goto_line - sets the current line to the specified line number.
 *
 * Parameters: linenr - line to which cur_line should be set
 ***********************************************************************/
void Editor::goto_line(int linenr)
{  Edit_Line *tmp_ptr = edit_buffer;

   while (tmp_ptr != NULL && --linenr != 0)
       tmp_ptr = tmp_ptr->next_line;

   cur_line = tmp_ptr;      
}

/************************************************************************
 * show_help - shows a helpfile with all available commands.
 *
 * Parameters: the_conn : Connection to send the data to.
 ***********************************************************************/
void Editor::show_help(Connection *the_conn)
{   FILE *hfp = NULL;
    char linebuffer[512];
    Strings full_filename;

    full_filename.sprintf("%s/%s", the_config.basedir.str_show(), EDITOR_HELP); 
    if ((hfp = xfopen(full_filename.str_show(),"r", "editor_help_file")) == NULL)
    {   the_conn->send_to_socket("Help file not found.\n");
    }
    else
    {   fgets(linebuffer,512,hfp);
        while (!feof(hfp))
        {  the_conn->send_to_socket(linebuffer);
           fgets(linebuffer,512,hfp);
        }
        xfclose(hfp, "editor_help_file");
    }
}

/***************************************************************************
 * print_linemarker - show a marker at the end of a line (+/- 78th column)
 **************************************************************************/
void Editor::print_linemarker(Connection *the_connection)
{
    if (linemarker)
       the_connection->send_to_socket("\r                                                                            #\r");
}


/**************************************************************************
 * delete_from_line - deletes a specified number of lines starting at a
 *                    certain offset (usually this will be equal to cur_line)
 *
 * Parameters: startline - The first line that should be deleted.
 *             nroflines - Number of lines to be deleted.
 *************************************************************************/
int Editor::delete_from_line(Edit_Line *startline, int nroflines)
{   Edit_Line *tmp_ptr;
    Edit_Line *hlp_ptr;
    Edit_Line *off_ptr;
    int  delct;

    tmp_ptr = edit_buffer;

    if (tmp_ptr == startline)
    {   for (delct = 0; delct < nroflines && tmp_ptr != NULL; delct++)
        {  hlp_ptr = tmp_ptr->next_line;
           delete_Edit_Line(tmp_ptr);
           tmp_ptr = hlp_ptr;
        }
        cur_line = edit_buffer = tmp_ptr;
        return delct;
    }

    while ((tmp_ptr->next_line != startline) && (tmp_ptr->next_line != NULL))
        tmp_ptr = tmp_ptr->next_line;

    if (tmp_ptr->next_line == NULL)
       return 0;

    off_ptr = tmp_ptr;
    tmp_ptr = tmp_ptr->next_line;

    for (delct = 0; delct < nroflines && tmp_ptr != NULL; delct++)
    { 
        hlp_ptr = tmp_ptr->next_line;
        delete_Edit_Line(tmp_ptr);
        tmp_ptr = hlp_ptr;
    }
    off_ptr->next_line = tmp_ptr;
   
    if (off_ptr->next_line != NULL)
       cur_line = off_ptr->next_line;
    else
       cur_line = off_ptr;

    return delct;
}

/**************************************************************************
 * replace_with - replace all occurances of a certain string with a new
 *                one, either limited to the current line of the whole
 *                context.
 *
 * Parameters: thestr     = the string that needs to be replaced.
 *             withstring = the string it should be replaced with
 *             global     = should the replacement be global or local.
 ***********************************************************************/
int Editor::replace_with(char *thestr, char *withstring, bool    global)
{  Edit_Line    *tmp_ptr;
   Edit_Line    *end_ptr;
   char    *strptr;
   char    *offptr;
   Strings newstr;
   int     numoc = 0;

   if (global)
   {
      tmp_ptr = edit_buffer;
      end_ptr = NULL;
   }
   else
   {  tmp_ptr = cur_line;
     if (cur_line == NULL) 
        end_ptr = NULL;
     else
        end_ptr = cur_line->next_line;
   }

   while (tmp_ptr != NULL && tmp_ptr != end_ptr)
   {
       char *word_ptr;
       char *place_holder;
       char *last_stored_to;
       Strings holder;

       if (newstr.str_show() != NULL)
          newstr.truncate(0);
       holder = tmp_ptr->the_line.str_show();
       strptr = holder.str_show();
       last_stored_to = strptr;

       /* Find all the occurances one by one.. not efficient, but what the hell
        * CPU is not a problem these days *grindem*
        */
       offptr = NULL;
       while ((strptr) && (*strptr))
       {
          if (*strptr == ' ')
        {
             place_holder = strptr;
             strptr++;
             word_ptr = thestr;
             while ((*strptr) && (*word_ptr) && (*word_ptr == *strptr) && 
                    (*strptr != ' '))
           {
                strptr++;
                word_ptr++;
             }
 
             /* in this situation, we have a match! */
             if (!(*word_ptr) && ((*strptr == ' ') || (!(*strptr))))
           {
                *place_holder = '\0';
                newstr.str_cat(last_stored_to);
                newstr.str_cat(" ");
                newstr.str_cat(withstring);
                newstr.str_cat(" ");
                last_stored_to = strptr + 1;
                numoc++;
             }
          }
          strptr++;
       }
       if (strptr != last_stored_to)
          newstr.str_cat(last_stored_to);

       tmp_ptr->the_line = newstr.str_show();
       tmp_ptr = tmp_ptr->next_line;
   }
   return numoc;
}

/****************************************************************************
 * get_linemarker_flag - Gets the flag that determines if a linemarker should
 *                       be written (linemarker is a mark to denote where the
 *                       end of the line is)
 * Returns - true if linemarker is set
 *           false if linemarker is not set
 ***************************************************************************/
bool    Editor::get_linemarker_flag()
{  return linemarker;
}

/*****************************************************************************
 * set_linemarker_flag - sets the linemarker flag (see above)
 *
 * Parameters: flval, the value the flag should have (either true or false)
 ***************************************************************************/
void    Editor::set_linemarker_flag(bool    flval)
{  linemarker = flval;
}

void Editor::set_cmdmode(CmdMode newmode)
{  cur_cmdmode = newmode;
}

void Editor::set_editmode(EditMode newmode)
{  cur_editmode = newmode;
}

CmdMode Editor::get_cmdmode()
{  return cur_cmdmode;
}

EditMode Editor::get_editmode()
{  return cur_editmode;
}

Edit_Line *Editor::get_curline()
{  return cur_line;
}

void Editor::set_curline(Edit_Line *theline)
{   cur_line = theline;
}



/*****************************************************************************
 * editor_command_handler - Main input handler
 *
 * This input handler is the one the editor should start in.. It handles
 * the input of the editor when this is in command mode. In this mode
 * the editor will take simple commands which you can read about in 
 * ../data/editor.h.
 *
 * Input parameters - theobject : the user who owns the writer
 *                    the_input : the command
 * returns -1 on error
 *         1  if all went as it should.
 **************************************************************************/
int editor_command_handler(MudObject *theobject, char *the_input)
{  Player         *the_plr;
   Builder        *the_bldr;
   Inp_Handler *tmp_handler;
   Strings     the_inpstr;
   Strings     the_cmd;
   int         wc;
   Connection  *the_conn;
   Editor      *the_editor;
 
   switch (theobject->get_type()) {
   case OBJ_TYPE_BUILDER:
      the_bldr = (Builder *)theobject;
      the_conn = the_bldr->get_connection();
      tmp_handler = the_bldr->get_input_handler();
      
      break;
   case OBJ_TYPE_PLAYER:
      the_plr = (Player *)theobject;
      the_conn= the_plr->get_connection();
      tmp_handler = the_plr->get_input_handler();
      
      break;
   default:
      printf("Wrong type.\n");
      return -1;  /* GET LOST */         
   }

   the_editor = (Editor *)tmp_handler->get_data();
   if (the_editor == NULL)
      return -1;
     
   if (the_editor->get_cmdmode() != Command)
   {  return -1;
   }

   the_inpstr = the_input;
   
   the_inpstr.remove_newline();
   the_cmd.assign_word(the_inpstr.str_show(),1);

   //   the_conn->send_to_socket(the_inpstr.str_show());   
   wc = 0;
   
   while (isspace(the_cmd.get_letter(wc)) && the_cmd.get_letter(wc) != '\0')
         wc++;
      
   if (the_cmd.get_letter(wc) != '\0')
   {  
      switch(the_cmd.get_letter(wc)) {
      case 'q':
         the_conn->send_to_socket("&+B[&+WQuitting editor&+b]&*\n");
         the_editor->stop_editor(false);
         tmp_handler->pop_input_handler();
         break;
      case 'a':
         tmp_handler->push_input_handler(editor_input_handler,NULL,0,
                                                    HANDLER_DATA_EDITOR, 0);
         tmp_handler->set_data(the_editor);
         the_editor->set_cmdmode(Edit);
         the_editor->set_editmode(Append);
         the_conn->send_to_socket("&+b[&+WAppend mode started&+b]&*\n");
         the_conn->send_to_socket(
                        "&+b[&+wType '.' on a new line to exit&+b]&*\n");
         the_editor->print_linemarker(the_conn);
         break;
      case 'A':
         the_conn->send_to_socket("&+b[&+WAborting Editor&+b]&*\n");
         the_editor->stop_editor(true);
         tmp_handler->pop_input_handler();
         break;
      case 'i':
         tmp_handler->push_input_handler(editor_input_handler,NULL,0,
                                                   HANDLER_DATA_EDITOR, 0);
         tmp_handler->set_data(the_editor);
         the_editor->set_cmdmode(Edit);
         the_editor->set_editmode(Insert);
         the_conn->send_to_socket("&+b[&+WInsert mode started&+b]&*\n");
         the_conn->send_to_socket(
                        "&+b[&+wType '.' on a new line to exit&+b]&*\n");
         the_editor->print_linemarker(the_conn);
         break;
      case 'o':
         tmp_handler->push_input_handler(editor_input_handler,NULL,0,
                                                  HANDLER_DATA_EDITOR, 0);
         tmp_handler->set_data(the_editor);
         the_editor->set_cmdmode(Edit);
         the_editor->set_editmode(Overwrite);
         the_conn->send_to_socket("&+b[&+WOverwrite mode started&+b]&*\n");
         the_conn->send_to_socket(
                        "&+b[&+wType '.' on a new line to exit&+b]&*\n");
         the_editor->print_linemarker(the_conn);
         break;
      case 'l':
         the_editor->show_context(the_conn);
         break;
      case 'm':
         {  Strings tmpstr;
            
            the_editor->set_linemarker_flag(the_editor->get_linemarker_flag() ? false : true);
            tmpstr.sprintf("Line marker %s\n",
               the_editor->get_linemarker_flag() ? "Enabled" : "Disabled");
            the_conn->send_to_socket(tmpstr.str_show());
         }
         break;
      case 'd':
         if (the_editor->get_curline() != NULL)
         {  Edit_Line *theline = the_editor->get_curline();
            
            if (theline != NULL)
            {  the_conn->send_to_socket(theline->the_line.str_show());
               the_conn->send_to_socket("\n");
            }
            else
                the_conn->send_to_socket("Current line is at the end of the buffer.\n");
         }
         else
            the_conn->send_to_socket("End of buffer reached.\n");         
         break;
      case 'w':
         (void)the_editor->write_context();
         the_conn->send_to_socket("Context saved.\n");
         break;
      case 'c':
         the_editor->reset_editor();
         the_conn->send_to_socket("Context cleared.\n");
         break;
      case 'f':
         the_editor->format_context();
         the_conn->send_to_socket("Context Formatted.\n");
         break;
      case 'x':
         {  Strings lines;
            
            lines.assign_word(the_inpstr.str_show(),2);
            
            if (lines.str_show() == NULL)
            {   the_editor->delete_from_line(the_editor->get_curline(),1);
                the_conn->send_to_socket("Line deleted.\n");
            }
            else if (!isdigit(*(lines.str_show())))
               the_conn->send_to_socket("Usage: x <number of lines>\n");
            else
            {  Strings msgstr;
               int     d;

               d = the_editor->delete_from_line(the_editor->get_curline(),atoi(lines.str_show()));
               msgstr.sprintf("Deleted %d lines.\n",d);
               the_conn->send_to_socket(msgstr.str_show());
            }
         }
         break;

      case 'g':
         {  Strings linenr;
            
            linenr.assign_word(the_inpstr.str_show(),2);
            
            if (linenr.str_show() == NULL)
               the_conn->send_to_socket("Usage: goto <linenr>\n");
            else if (!isdigit(*(linenr.str_show())))
               the_conn->send_to_socket("Usage: goto <linenr>\n");
            else
            {  Strings msgstr;
               msgstr.sprintf("Setting current line to %s\n",linenr.str_show());
               the_conn->send_to_socket(msgstr.str_show());
               the_editor->goto_line(atoi(linenr.str_show())); 
            } 
         }
         break;
         
      case '/':
         {  Strings fromstr, tostr;
            int     i;
            
            fromstr.assign_word_sdl(the_inpstr.str_show(),2);
            tostr.assign_word_sdl(the_inpstr.str_show(),3);
            
            if (fromstr.str_show() == NULL || tostr.str_show() == NULL)
               the_conn->send_to_socket("Usage: replace <from> <to>\n");
            else
            {  i = the_editor->replace_with(fromstr.str_show(), 
                                                 tostr.str_show(),false);
               tostr.sprintf("Replaced %d occurances of %s.\n",i,
                                                        fromstr.str_show());
               the_conn->send_to_socket(tostr.str_show());
            }
         }
         break;
      case 'R':
         {  Strings fromstr, tostr;
            int     i;
            
            fromstr.assign_word_sdl(the_inpstr.str_show(),2);
            tostr.assign_word_sdl(the_inpstr.str_show(),3);
            
            if (fromstr.str_show() == NULL || tostr.str_show() == NULL)
               the_conn->send_to_socket("Usage: global replace <from> <to>\n");
            else
            {  i = the_editor->replace_with(fromstr.str_show(), tostr.str_show(),true);
               tostr.sprintf("Replaced %d occurances of %s.\n",i,fromstr.str_show());
               the_conn->send_to_socket(tostr.str_show());
            }
         }
         break;
      case '?':
         the_editor->show_help(the_conn);
         break;   
      default:
         the_conn->send_to_socket("Unknown command.\n");
         
      }         
   }
   return 1;
}

int editor_input_handler(MudObject *theobject, char *the_input)
{  Strings   the_inpstr = the_input;
   Edit_Line *newline;
   Edit_Line *cur_line;   
   Player    *the_plr;
   Builder   *the_bldr;
   Connection  *the_conn;
   Editor      *the_editor;
   Inp_Handler *tmp_handler;
   Strings     *tmp_prompt;
   
   switch (theobject->get_type()) {
   case OBJ_TYPE_BUILDER:
      the_bldr = (Builder *)theobject;
      the_conn = the_bldr->get_connection();
      tmp_handler = the_bldr->get_input_handler();
      
      break;
   case OBJ_TYPE_PLAYER:
      the_plr = (Player *)theobject;
      the_conn= the_plr->get_connection();
      tmp_handler = the_plr->get_input_handler();
      
      break;
   default:
      return -1;  /* GET LOST */         
   }

   the_editor = (Editor *)tmp_handler->get_data();
   if (the_editor == NULL)
      return -1;

   if (the_editor->get_cmdmode() != Edit)
   {  return -1;
   }
   
   if (the_inpstr.get_letter(0) == '.')
   {
      if (the_editor->is_simple_mode())
      {
         the_conn->send_to_socket("&+B[&+WQuitting editor&+b]&*\n");
         the_editor->stop_editor(false);
         tmp_handler->pop_input_handler();
         return 1;
      }
      else
      {
         the_editor->set_cmdmode(Command);

         tmp_handler->pop_input_handler();
         return 1;
      }       
   }
   
   newline = new_Edit_Line();
   newline->the_line = the_inpstr.str_show();
   newline->the_line.remove_newline();
   cur_line = the_editor->get_curline();
      
   switch (the_editor->get_editmode()) {
   case Insert:
      the_editor->add_line(EDITOR_ADD_INSERT,newline);
      the_editor->set_curline(newline);
      the_editor->set_editmode(Append);
      break;
   case Append:
      the_editor->add_line(EDITOR_ADD_APPEND,newline);
      the_editor->set_curline(newline);
      break;
   case Overwrite:
      if (cur_line == NULL)
      {
         the_editor->add_line(EDITOR_ADD_LAST,newline);
         the_editor->set_curline(newline);
         the_editor->set_editmode(Append);
      }
      else
      { 
          cur_line->the_line = newline->the_line.str_show();
          delete_Edit_Line(newline);
          the_editor->set_curline(cur_line->next_line);
      }
      break;
   default:
      the_conn->send_to_socket("Whoops, the editor is screwed up.. going to command mode.\n");
      the_editor->set_cmdmode(Command);
      tmp_prompt = new Strings(EDITOR_PROMPT);

      tmp_handler->pop_input_handler();
      return 1;
      break;
   }
   the_editor->print_linemarker(the_conn);
   return 1;
}

bool    Editor::is_simple_mode()
{
   return simple_mode;
}


#endif

Generated by  Doxygen 1.6.0   Back to index