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

vdkb_text.cc

/*
 * ===========================
 * VDK Builder
 * Version 0.1
 * Revision 0.0
 * December 1998
 * ===========================
 *
 * Copyright (C) 1998,1999 Mario Motta
 * Developed by Mario Motta <mmotta@guest.net>
 *
 * Based on VDK Library
 * Copyright (C) 1998, Mario Motta
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA.
 *
 */

#if HAVE_CONFIG_H
#include <config.h>
#endif

#if !HAVE_GNOME
  #if ENABLE_NLS
    #include <libintl.h>
//#define _(str) gettext(str)
#define _(str) \
    ( g_utf8_validate(gettext(str),-1,NULL) ? \
    gettext(str) : \
    g_locale_to_utf8(gettext(str),-1,NULL,NULL,NULL) )
#define N_(str) str
  #else
    #define _(str) str
    #define N_(str) str 
  #endif
#else
 #include <gnome.h>
#endif

#include <vdkb2/vdkb_text.h>
#include <gdk/gdkkeysyms.h>
#include <vdkb2/vdkb_utils.h>
#include <stdio.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <vdkb2/vdkb.h>
#include <vdkb2/vdkb_utils.h>

#define vdkeCourier "-*-courier-medium-r-*-*-12-*-*-*-*-*-*-*"
#define vdkeCourierBold "-*-courier-bold-r-*-*-12-*-*-*-*-*-*-*"
#define vdkeCourierSlant "-*-courier-medium-o-*-*-12-*-*-*-*-*-*-*"

DEFINE_SIGNAL_LIST(VDKBText,VDKEditor);
DEFINE_EVENT_LIST(VDKBText, VDKEditor);

static const char * mark_xpm[] = {
"16 16 67 1",
"     c None",
".    c #FEFEFE",
"+    c #FEFEFD",
"@    c #FCFCFC",
"#    c #C3C3C3",
"$    c #ABAAA8",
"%    c #BABAB9",
"&    c #F6F6F6",
"*    c #F7F7F7",
"=    c #989488",
"-    c #E3D395",
";    c #F7E8AA",
">    c #EAD992",
",    c #B1A578",
"'    c #D1D1D1",
")    c #B5B4B3",
"!    c #EDDB98",
"~    c #F8F2DB",
"{    c #FAF6E8",
"]    c #F8EDB9",
"^    c #F0DE8D",
"/    c #99906F",
"(    c #FAFAFA",
"_    c #B5B2A8",
":    c #F4E29B",
"<    c #FAF5E7",
"[    c #F9F4E2",
"}    c #F5EAB9",
"|    c #F5E494",
"1    c #B4A66D",
"2    c #D9D9D9",
"3    c #B7B6B6",
"4    c #E9D895",
"5    c #F9F4E3",
"6    c #F9EFCD",
"7    c #F3E6AC",
"8    c #F1DF8E",
"9    c #978B5A",
"0    c #EFEFEF",
"a    c #B5AA7A",
"b    c #F7F0D6",
"c    c #F2E4A9",
"d    c #E8D88F",
"e    c #CFBD76",
"f    c #979383",
"g    c #D0D0CD",
"h    c #918C79",
"i    c #AEA684",
"j    c #D2C07B",
"k    c #94895A",
"l    c #918F87",
"m    c #898987",
"n    c #9A9A96",
"o    c #949490",
"p    c #55544E",
"q    c #B2B2B0",
"r    c #FDFDFC",
"s    c #555554",
"t    c #959591",
"u    c #888885",
"v    c #5C5C5B",
"w    c #222220",
"x    c #494946",
"y    c #727271",
"z    c #828281",
"A    c #0C0C0B",
"B    c #60605D",
"                ",
"                ",
"         .+     ",
"       @#$%&.   ",
"      *=-;>,'.  ",
"     +)!~{]^/(  ",
"     ._:<[}|12  ",
"      34567890  ",
"      &abcdef.  ",
"      ghijkl0   ",
"      mnopqr    ",
"      stuv      ",
"      wxyz      ",
"       AB       ",
"                ",
"                "};

//===================================
const unsigned int guessOffset = 1000;
static char buff[1024];
extern VDKBuilder* TheApp;
extern char *source_prompts[];
extern HintBTree* hint_tree;
/*
*/
bool
VDKBText::KeyEventAfter(VDKObject *sender,GdkEvent *event)
{
  GdkEventKey *ev = (GdkEventKey*) event;
  // dispatch directly to text parent (VDKBnotebook)
  if(Changed)
      Parent()->SignalEmit("text_changed");
  // others keys:
  switch(ev->keyval)
    {
    case GDK_Up:
    case GDK_Down:
    case GDK_Page_Up:
    case GDK_Page_Down:
      CurrentLine((int) Line+1);
      Parent()->SignalEmit("line_changed");
      break;
    case GDK_F3:
    case GDK_F20:
      Parent()->SignalEmit("repeat_search_text");
      break;
    }
  return false; //true;
}

/*
 */
char *
VDKBText::MakeTip(char* word)
{
  VDKHint hint(word,(char*) ""),*found;
  if( (found = hint_tree->find(hint)))
    sprintf(buff,found->hint);
  else
    sprintf(buff,_("%s: no tip available"),word);
  return buff;
}

/*
 */
bool
VDKBText::KeyEventBefore(VDKObject *sender,GdkEvent *event)
{
    GdkEventKey *ev = (GdkEventKey*) event;
    bool isAlt = false;
    bool isCtrl = false; 
    char* word = NULL;
    //    Action* action = NULL;
    if(! Editable)
      return false;//true;
    switch(ev->keyval)
      {
      case GDK_F16:
      case GDK_F4:
        if (! Undo())
          Parent()->SignalEmit("no_more_undo");
        break;

      case GDK_BackSpace:
          isAlt = ev->state & GDK_MOD1_MASK;
          if(isAlt && ! Undo())
              Parent()->SignalEmit("no_more_undo");
          break;
      
      case GDK_F5:
        ShowTipWindow(_("sorry, redo not yet implemented")); 
        break;
        
      case GDK_F6:
        if(Hilite)
          Parent()->SignalEmit("hilite_text");
        break;

      case GDK_F1:
        Parent()->SignalEmit("editor_help");
        break;

        // hints
      case GDK_q:
        isCtrl = ev->state & GDK_CONTROL_MASK;
        if(isCtrl)
          {
            word = GetWord();
            if(word)
            ShowTipWindow(MakeTip(word));
          }
        break;
      default:    
          break;
      }
    return false;//true;
}
/*
*/
bool
VDKBText::ButtonPressEvent(VDKObject* obj, GdkEvent* ev)
{
  char* p = Filename();
  GdkEventButton* event = (GdkEventButton*) ev;
  if(event->button != 1)
    return false;
  if(p)
    {
     struct stat finfo;
     if(!stat(p,&finfo))
       {
       if( (Mtime() != 0) &&
        (finfo.st_mtime !=  Mtime()) )
         {
           sprintf(buff,"%s\n%s",p,_("Changed from disk, reload ?"));
           if(Owner()->Application()
            ->VDKMessageBox(APPNAME,
                       buff,
                       VDK_ICONQUESTION|VDK_YESNO,
                       _(user_messages[user_ok]),
                       _(user_messages[user_no]))     == VDK_IDYES)
             Load(p);
         }
       else
       {
         CurrentLine(Line+1);
         Parent()->SignalEmit("line_changed");
       }
       }
    }
  return false;//true;
}
/*
pop menu
*/
bool
VDKBText::ButtonReleaseEvent(VDKObject* sender, GdkEvent *event)
{
  // casts to button event
  GdkEventButton *ev = (GdkEventButton*) event;
  // pops menu on right button pressed
  if(ev->button == 2)
    {
      Parent()->SignalEmit("pop_menu");
      return true;
    }
  return false;
}

/*
*/
bool
VDKBText::Realized(VDKObject* sender)
{
  char* cc_ext   = (char*) VDKBuilder::ideDefaults.unit.cc_ext;
  char* h_ext    = (char*) VDKBuilder::ideDefaults.unit.h_ext;
  // this flag is set to false by constructor
  // so only one realized signal is catched
  if(!realized)
    {
      SetStyle();
      // load from file if found
      // and hilites it
      if(!access(Filename(),F_OK) && Load(Filename()) && Hilite)
      Syntax = true;
      // create a new unit file if not empty filename
      else if(*Filename())
      {
        // is a new unit file ?
        Changed = true;
        char *local = new char[strlen(Filename())+1];
        strcpy(local,Filename());
        char* ext = get_extension(local);
        // advance to jump '.'
        if(ext)
          {
            *ext = '\0';
            ext++;
            // is a .cc file ?
            if(!strcmp(ext,cc_ext))
            {
              sprintf(buff,"#include <%s.h>\n",local);
              TextInsert(buff);
              sprintf(buff,source_prompts[1], SOURCE_END_MARK, local, cc_ext);
              TextInsert(buff);
            }
            // is .h file ?
            else if(!strcmp(ext,h_ext))
            {
              TextInsert("//\n");
              sprintf(buff,"#ifndef _%s_h\n",local);
              TextInsert(buff);
              sprintf(buff,"#define _%s_h\n",local);
              TextInsert("// put your code below here\n");
              TextInsert(buff);
              TextInsert("\n\n");
              TextInsert("//\n");
              TextInsert("#endif\n");
              sprintf(buff,source_prompts[1], SOURCE_END_MARK, local, h_ext);
              TextInsert(buff);
            }
          }
        delete[] local;
      }
      realized = true;
      Pointer = 0;
    }
 return true;
}

/*
  set style
*/
void
VDKBText::SetStyle()
{
  VDKString Yes = CHECK_YES;
  char* font = (char*) VDKBuilder::ideDefaults.editor.font;
  char* bg_color = (char*) VDKBuilder::ideDefaults.editor.bg;
  char* fg_color = (char*) VDKBuilder::ideDefaults.editor.fg;
  char* color = NULL;
  VDKColor *key_color = NULL;
  VDKFont  *key_font = NULL;
  VDKColor *gtk_color = NULL;
  VDKFont  *gtk_font = NULL;
  VDKColor *macro_color = NULL;
  VDKFont  *macro_font = NULL;
  VDKColor *preprocessor_color = NULL;
  VDKFont  *preprocessor_font = NULL;
  VDKColor *const_color = NULL;
  VDKFont  *const_font = NULL;
  VDKColor *comment_color = NULL;
  VDKFont  *comment_font = NULL;

  //  bool autoindent = VDKBuilder::ideDefaults.project.code_autoindent == Yes;
  // gtk_source_view_set_auto_indent(GTK_SOURCE_VIEW(WrappedWidget()),autoindent);
  int tabs = atoi(VDKBuilder::ideDefaults.editor.tab);
  TabStop = tabs;
  bool showline = VDKBuilder::ideDefaults.project.showln == Yes;
  ShowLineNumbers = showline;

  // defaults
  if(font)
    Font = new VDKFont(this,font);
  if(bg_color)
    NormalBackground = VDKRgb(bg_color);
  if(fg_color)
    Foreground = VDKRgb(fg_color);
  // keys attributes
  font = (char*) VDKBuilder::ideDefaults.editor.key_font;
  color = (char*) VDKBuilder::ideDefaults.editor.key_color;
  if(font)
    key_font = new VDKFont(this,font);
  if(color)
    key_color = new VDKColor(this,color);
  // gtk/vdk attributes
  font = (char*) VDKBuilder::ideDefaults.editor.gtk_font;
  color = (char*) VDKBuilder::ideDefaults.editor.gtk_color;
  if(font)
    gtk_font = new VDKFont(this,font);
  if(color)
    gtk_color = new VDKColor(this,color);
  // macro attributes
  font = (char*) VDKBuilder::ideDefaults.editor.macro_font;
  color = (char*) VDKBuilder::ideDefaults.editor.macro_color;
  if(font)
    macro_font = new VDKFont(this,font);
  if(color)
    macro_color = new VDKColor(this,color);
  // preprocessor attributes
  font = (char*) VDKBuilder::ideDefaults.editor.preprocess_font;
  color = (char*) VDKBuilder::ideDefaults.editor.preprocess_color;
  if(font)
    preprocessor_font = new VDKFont(this,font);
  if(color)
    preprocessor_color = new VDKColor(this,color);
  // const attributes
  font = (char*) VDKBuilder::ideDefaults.editor.const_font;
  color = (char*) VDKBuilder::ideDefaults.editor.const_color;
  if(font)
    const_font = new VDKFont(this,font);
  if(color)
    const_color = new VDKColor(this,color);
  // comment attributes
  font = (char*) VDKBuilder::ideDefaults.editor.comment_font;
  color = (char*) VDKBuilder::ideDefaults.editor.comment_color;
  if(font)
    comment_font = new VDKFont(this,font);
  if(color)
    comment_color = new VDKColor(this,color);
  // install syntax and patterns table
  InstallSyntaxTable (
                      key_color,key_font, // keywords 
                      gtk_color,gtk_font, // gtk+ names
                      macro_color,macro_font, // macros
                      preprocessor_color,preprocessor_font, // preprocessor directives
                      const_color,const_font, // constants
                      comment_color,comment_font); // remarks
    // install marker pixmaps
  AddMarkIcon(new  VDKPixbuf(owner, mark_xpm),"mark",true);
}

//////////////////////////////////////
/*
 */
VDKBText::VDKBText(VDKForm* owner, bool editable, char* filename ):
  VDKEditor(owner),filename(filename),
  CurrentLine("CurrentLine",this,1)
{
  mapped = false;
  lastGuessed = 0;
  realized = false;
  Hilite = false;
  // set max undo
  MaxUndo = 512;
  // setup event handler to intercept key press
  // intercepts undo/redo, stops signal in this case
  // and process undo/redo
  // "true" as last arg means connect after (default false)
  EventConnect("key_press_event",&VDKBText::KeyEventAfter);//,true);
  EventConnect("button_press_event",&VDKBText::ButtonPressEvent);//,true);
  EventConnect("button_release_event", &VDKBText::ButtonReleaseEvent);//,true);
  // EventConnect("map_event",&VDKBText::MappedEvent,true);
  SignalConnect("realize",&VDKBText::Realized,true,true);
  EventConnect("key_press_event",&VDKBText::KeyEventBefore);
  // load file last modification time
  if(filename)
    {
     struct stat finfo;
     if(!stat(filename,&finfo))
       mtime = finfo.st_mtime;
     else
       mtime = 0;
    }
  else
    mtime = 0;
}
/*
 */
int
VDKBText::Save(char* filename)
{

  int result = FALSE;
  if(filename)
    {
      result = VDKEditor::SaveToFile(filename);
      if(result)
      {
        struct stat finfo;
        if(!stat(filename,&finfo))
          mtime = finfo.st_mtime;
        else
          mtime = 0;
      }
      else
      mtime = 0;
    }
  else
    mtime = 0;
  return result;
}
/*
 */
int
VDKBText::Load(char* filename)
{
  int result = VDKEditor::LoadFromFile(filename);
  /*
    make a back-up file, using filename+~
  */
  VDKString Yes = CHECK_YES;
  if(result && filename &&
     (VDKBuilder::ideDefaults.editor.backup == Yes) )
    {
      char* ext = get_extension(filename);
      if(ext && (!strchr(ext,'~')))
      {
        int success = 0;
        VDKString backup = filename;
        backup += "~";
        success = VDKEditor::SaveToFile((char*) backup);
        if(! success)
          {
            sprintf(buff,_("Couldn't make %s backup file"),filename);
            TheApp->VDKMessageBox(
                         APPNAME,
                         buff,
                         VDK_ICONINFORMATION|VDK_OK,
                         _(user_messages[user_ok]),
                         NULL,
                         5000);
          }
      }
    }

  if(result && filename)
    {
      struct stat finfo;
      if(!stat(filename,&finfo))
      mtime = finfo.st_mtime;
      else
      mtime = 0;
    }
  else
    mtime = 0;
  return result;
}
///////////////////////////////////////
/*
 */
VDKBText::~VDKBText()
{
  //action_stack.flush();
}

/*
 */
char* VDKBText::ShortName()
{
  char* p = (char*) filename;
  char* s = get_shortfilename(p);
  return s ? s : p;
}
/*
 */
char* VDKBText::Extension()
{
char* p = (char*) filename;
return get_extension(p);
}
/*
 */
char* VDKBText::Filename(char* name)
{
if(name)
  filename = name;
return (char*) filename;
}

bool
VDKBText::GoToLine(int line)
{
  //Line = line;
  if(line > 0)
    ScrollToLine(line-1,0);
  return true;
}
/*
 */
void
VDKBText::ScrollTo(int pos)
{
  // Pointer = pos;
  ScrollToPos(pos);
}

int
VDKBText::Search(char* st,int from, bool select, bool bell)
{
  GtkTextIter iter,match_start,match_end;
  int m_start = -1;
  int m_end = -1;
  gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER(Buffer()),
                                      &iter,
                              from);

  if(gtk_text_iter_forward_search (&iter,
                        st,
                        GTK_TEXT_SEARCH_TEXT_ONLY,
                        &match_start,
                        &match_end,
                           NULL))
    {
      m_start = gtk_text_iter_get_offset (&match_start);
      m_end = gtk_text_iter_get_offset (&match_end);
      ScrollToPos(m_start);
      if(select)
      SelectText(m_start,m_end);
    }
  else if(bell)
    gdk_beep();
  return m_start;
  /*
  char* buf = GetChars(from,-1);
  int pos = -1;
  if(! buf)
    return 0;
  char* p = strstr(buf,st);
  if(p)
    {
      pos = from + (p-buf);
      ScrollToPos(pos);
      SelectText(pos,pos + strlen (st));
    }
  else if(bell)
    gdk_beep();
  g_free(buf);
  return pos;
  */
}



Generated by  Doxygen 1.6.0   Back to index