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

vdkb_editor.cc

/*
 * ===========================
 * VDK Builder
 * Version 0.1
 * Revision 0.0
 * November 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.
 *
 */

#ifdef 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
#endif

#include <vdkb2/vdkb_editor.h>
#include <vdkb2/vdkb.h>
#include <vdkb2/vdkb_locale.h>
#include <vdkb2/vdkb_utils.h>
#include <vdk/FileDialog.h>
#include <vdk/FileSaveAsDialog.h>
#include <vdkb2/vdkb_search.h>
#include <vdkb2/vdkb_replace.h>
#include <vdkb2/vdkb_prjman.h>
#include <vdkb2/vdkb_timebar.h>
#include <vdkb2/vdkb_edhelp.h>
#include "pixmaps/undo.xpm"
#include "pixmaps/redo.xpm"
#include "pixmaps/togglech.xpm"
#include "pixmaps/fileclose.xpm"
#include "pixmaps/savefile.xpm"
#include "pixmaps/filesaveas.xpm"
#include "pixmaps/search.xpm"
#include "pixmaps/repeatsearch.xpm"
#include "pixmaps/togglesyntax.xpm"
#include "pixmaps/showln.xpm"
#include "pixmaps/showmsg.xpm"
#include "pixmaps/dock.xpm"
#include "pixmaps/jumpto.xpm"
extern char *gear_xpm[];
extern char *run_xpm[];
#define TOOLB_TOGGLE_SRC_HDR 0
#define TOOLB_CLOSE_PAGE 1
#define TOOLB_SAVE_FILE 2
#define TOOLB_SAVE_FILE_AS 3
#define TOOLB_SEARCH 4
#define TOOLB_REP_SEARCH 5
#define TOOLB_UNDO 6
#define TOOLB_REDO 7
#define TOOLB_TOGGLE_SYNTAX 8
#define TOOLB_MAKE 9
#define TOOLB_RUN 10
#define TOOLB_SHOWLN 11
#define TOOLB_SHOWMSG 12
// a static dialog address
static Vdkb_edhelpForm* edhelp = NULL;
static char buff[512];
extern char* main_menu_prompts[];
extern char *main_toolbar1_tips[];
extern char* search_dialog_prompts[];
extern TokenList* tokenlist;
/*
search stuff
*/
static int last_pos = 0;
static char* match = NULL;

/*
 */
///////////////// signal stuff //////////
DEFINE_SIGNAL_LIST(VDKBEditor,VDKForm);
DEFINE_SIGNAL_MAP(VDKBEditor,VDKForm)
  ON_SIGNAL(nbook,switch_page_signal,OnPageChanged),
  ON_SIGNAL(messages,select_row_signal,JumpToError),
  ON_SIGNAL(closePage,activate_signal,OnClosePage),
  ON_SIGNAL(toggleHeader,activate_signal,OnToggleHeader),
  ON_SIGNAL(fileSave,activate_signal,FileSave),
  ON_SIGNAL(fileSaveAs,activate_signal,FileSaveAs),
  ON_SIGNAL(search,activate_signal,Search),
  ON_SIGNAL(repeatsearch,activate_signal,RepeatSearch),
  ON_SIGNAL(hilite,activate_signal,Hilite),
  ON_SIGNAL(undo,activate_signal,Undo),
  //   ON_SIGNAL(toolbar,clicked_signal,HandleToolbar),
  ON_SIGNAL(handle,child_attached_signal,OnHandleAttach),
  ON_SIGNAL(handle,child_detached_signal,OnHandleDetach),
  ON_SIGNAL(shortcut,activate_signal,ShortCut)
END_SIGNAL_MAP
/*
 */
VDKBEditor::VDKBEditor(VDKForm* owner):
  VDKForm(owner)
{
  //  struct stat info;
  ForceToClose = false;
}
/*
 */
VDKBEditor::~VDKBEditor()
{
}


/*
 */
bool
VDKBEditor::ShortCut(VDKObject* sender)
{
  if(!edhelp)
    {
      edhelp = new Vdkb_edhelpForm(this,NULL);
      edhelp->Setup();
      edhelp->Show(GTK_WIN_POS_MOUSE);
    }
  else if(edhelp->Iconized)
    edhelp->Iconized = false;
  else if(edhelp->Visible)
    edhelp->Raise();
  else // should never the case
    edhelp->Show(GTK_WIN_POS_MOUSE);
  return true;
}
/*
 */
void 
VDKBEditor::OnChildClosing(VDKForm* child)
{
  if(child == edhelp)
    edhelp = NULL;
}
/*
 */
bool
VDKBEditor::OnHandleAttach(VDKObject* sender)
{
  VDKHandleBox* handle = dynamic_cast<VDKHandleBox*>(sender);
  if(handle)
    {
      VDKObject* obj = handle->Child;
      VDKToolbar* tbar = dynamic_cast<VDKToolbar*>(obj);
      if(tbar)
      tbar->Orientation = GTK_ORIENTATION_HORIZONTAL;
    }
  return true;
}
/*
 */
bool
VDKBEditor::OnHandleDetach(VDKObject* sender)
{
  VDKHandleBox* handle = dynamic_cast<VDKHandleBox*>(sender);
  if(handle)
    {
      VDKObject* obj = handle->Child;
      VDKToolbar* tbar = dynamic_cast<VDKToolbar*>(obj);
      if(tbar)
      tbar->Orientation = GTK_ORIENTATION_VERTICAL;
    }
  return true;
}
/*
 */
bool
VDKBEditor::HandleToolbar(VDKObject* sender)
{
  int button = toolbar->ButtonPressed;
  VDKBMainForm* owner = dynamic_cast<VDKBMainForm*>(Owner());
  switch (button)
    {
    case TOOLB_TOGGLE_SRC_HDR:
      OnToggleHeader(NULL);
      break;

    case TOOLB_CLOSE_PAGE:
      OnClosePage(NULL);
      break;

    case TOOLB_SAVE_FILE:
      FileSave(NULL);
      break;

    case TOOLB_SAVE_FILE_AS:
      FileSaveAs(NULL);
      break;

    case TOOLB_SEARCH:
      Search(NULL);
      break;

    case TOOLB_REP_SEARCH:
      RepeatSearch(NULL);
      break;

    case TOOLB_UNDO:
      Undo(NULL);
      break;

    case TOOLB_REDO:
      // not yet implemented
      break;

    case TOOLB_TOGGLE_SYNTAX:
      Hilite(NULL);
      break;

    case TOOLB_MAKE:
      if(owner)
      owner->Make(NULL);
      break;

    case TOOLB_RUN:
      if(owner)
      owner->RunExecutable();
      break;

    case TOOLB_SHOWLN:
      {
      int activePage = nbook->ActivePage;
      if(activePage < 0 || activePage >= textlist.size())
        ;
      else
        {
          bool flag = textlist[activePage]->ShowLineNumbers;
          textlist[activePage]->ShowLineNumbers = !flag;
          // a dirty trick to force expose
          VDKPoint size = Usize;
          size.x+=1;
          SetFormSize(size);
          size.x-=1;
          SetFormSize(size);
        }
      }
      break;
    case TOOLB_SHOWMSG:
      {
      bool flag = message_docker->Visible;
      message_docker->Visible = ! flag;
      }
      break;
    }
  return true;
}

/*
 */
bool
VDKBEditor::HandleDockbar(VDKObject* sender)
{
  int button = dockbar->ButtonPressed;
  bool flag;
  switch (button)
    {
    case 0: // docks/undocks
      message_docker->Docked = message_docker->Docked ? false : true;
      break;
    case 1: // hides/show message docker
      flag = message_docker->Visible;
      message_docker->Visible = ! flag;
      break;
    case 2: // saves messages into a log file
      LogMessages();
      break;
    case 3: // jumps to error
      JumpToError(messages);
      break;
    }
  return true;
}
/*
 */
void
VDKBEditor::LogMessages()
{
  FILE* fp;
  FileStringArray selections;
  VDKFileSaveAsDialog *child =
    new VDKFileSaveAsDialog(this,&selections,_("saving message log"));
  child->Filter = "*.log";
  child->ShowModal();
  if(selections.size() <= 0)
    return;
  fp = fopen((char*) selections[0],"w+");
  if(!fp)
    return;
  TupleListIterator li(messages->Tuples);
  for(;li;li++)
    {
      Tuple tuple = li.current();
      char* p = (char*) tuple[0];
      fprintf(fp,"%s\n",p);
    }
  fclose(fp);
  return;
}
/*
 */
bool
VDKBEditor::MessageDocked(VDKObject* sender)
{
  if(message_docker->Docked)
    {
      message_docker->DockForm()->SetSize(450,350);
      message_docker->DockForm()->SetTitle(_("Message list"));
    }
  (*dockbar)[1]->Enabled = !(message_docker->Docked);
  (*toolbar)[TOOLB_SHOWMSG]->Enabled = !(message_docker->Docked);
  return true;
}

/*
 */

void
VDKBEditor::Setup()
{
  Title = _(editor_prompts[0]);
  handle = new VDKHandleBox(this);
  handle->SetSize(-1,40);
  /*
  toolbar = new VDKToolbar(this);
  toolbar->Style = GTK_TOOLBAR_ICONS;
  */
  toolbar = new VDKHLButtonBar(this);
  toolbar->AddButton((const char**)togglech_xpm,_(editor_prompts[3]));
  toolbar->AddButton((const char**)fileclose_xpm,_(editor_prompts[4]));
  toolbar->AddButton((const char**)savefile_xpm,_(editor_prompts[9]));
  toolbar->AddButton((const char**)filesaveas_xpm,_(editor_prompts[5]));
  toolbar->AddButton((const char**)search_xpm,_(main_menu_prompts[30]));

  sprintf(buff,"%s-(F3)", _(main_menu_prompts[31]) );
  toolbar->AddButton((const char**)repeatsearch_xpm,buff);
  sprintf(buff,"%s-(Alt-Backspace)", _(main_menu_prompts[33]) );
  toolbar->AddButton((const char**)undo_xpm,buff);
  sprintf(buff,"%s-(F5)", _(main_menu_prompts[34]) );
  toolbar->AddButton((const char**)redo_xpm,buff);
  (*toolbar)[7]->Enabled = false;
  toolbar->AddButton((const char**)togglesyntax_xpm,_(main_menu_prompts[35]));
  toolbar->AddButton((const char**)gear_xpm,_(main_menu_prompts[41]));
  toolbar->AddButton((const char**)run_xpm,_(main_toolbar1_tips[1]));
  toolbar->AddButton((const char**)showln_xpm,_(editor_prompts[10]));
  toolbar->AddButton((const char**)showmsg_xpm,_(editor_prompts[11]));
  (*toolbar)[TOOLB_MAKE]->Enabled = false;
  (*toolbar)[TOOLB_RUN]->Enabled = false;
  handle->Add(toolbar,l_justify,false,false,0);
  SignalConnect(toolbar,"clicked",&VDKBEditor::HandleToolbar);
  Add(handle,l_justify,false,false,0);

  VDKPaned* paned = new VDKPaned(this); // **STUB
  nbook = new VDKBNotebook(this);
  paned->Pack(nbook,1,true,false); // **STUB
  VDKPoint size = VDKBuilder::ideDefaults.editor.size;
  nbook->SetSize(size.X(),size.Y());
  // dockable message list
  message_docker = new VDKDockerBox(this);
  dockbar = new VDKHLButtonBar(this,h_box,shadow_etched_in);
  dockbar->AddButton((const char**)dock_xpm,_("docks/undocks messages list"));
  dockbar->AddButton((const char**)showmsg_xpm,_(editor_prompts[11]));
  dockbar->AddButton((const char**)savefile_xpm,_("Save messages into a log file"));
  dockbar->AddButton((const char**)jumpto_xpm,
                 _("Jumps to error into editor\ncan be done also double clicking\non selected line"));
  message_docker->Add(dockbar,l_justify,false,false,0);
  SignalConnect(dockbar,"clicked",&VDKBEditor::HandleDockbar);

  messages = new VDKCustomList(this,1,NULL,GTK_SELECTION_EXTENDED);
  // cast white background to override some gtk-themes defaults
  // messages->NormalBackground = clWhite;
  message_docker->Add(messages);
  paned->Add(message_docker,2,true,true); // **STUB
  SignalConnect(message_docker,"docked",&VDKBEditor::MessageDocked,false);
  SignalConnect(message_docker,"undocked",&VDKBEditor::MessageDocked,false);
  message_docker->Visible=false;
  Add(paned); // **STUB
  
  bar =  new VDKPanelbar(this,3);
  bar->Panels()[2]->Justify = GTK_JUSTIFY_RIGHT;
  Add(bar,r_justify,false,false,false);
  // makes a pop menu
  popmenu = new VDKMenu(this);
  toggleHeader = new VDKMenuItem(popmenu,_(editor_prompts[3]));
  closePage = new VDKMenuItem(popmenu,_(editor_prompts[4]));
  fileSave = new VDKMenuItem(popmenu,_(editor_prompts[9]));
  fileSaveAs = new VDKMenuItem(popmenu,_(editor_prompts[5]));
  popmenu->Separator();
  search = new VDKMenuItem(popmenu,
                     _(main_menu_prompts[30]));
  sprintf(buff,"%s-(F3)",
        _(main_menu_prompts[31])
        );
  repeatsearch = new VDKMenuItem(popmenu,buff);
  sprintf(buff,"%s-(Alt-Backspace)",
        _(main_menu_prompts[33])
        );
  undo = new VDKMenuItem(popmenu,buff);
  sprintf(buff,"%s-(F5)",
        _(main_menu_prompts[34])
        );
  redo = new VDKMenuItem(popmenu,buff);
  hilite = new VDKMenuItem(popmenu, _(main_menu_prompts[35]));
  shortcut = new VDKMenuItem(popmenu, _(main_menu_prompts[48]));
  // since redo capability isn't yet  implemented, set as disabled
  redo->Enabled = false;
  /*
     since popmenu could never be popped
     better add it to form items even if VDKMenu::Popup()
     does the job. VDKList::add() will ensure won't be added twice
     and GC will detect it even if never popped.
  */
  AddItem(popmenu);
  /*
    Signals will come up from one of VDKBText's
    contained into VDKBNotebook pages.
    Since these signals are not provided by gtk+
    put <gtk> arg as false, so will be dispatched by VDK
  */
  SignalConnect(nbook,"text_changed",&VDKBEditor::OnTextChanged,false);
  SignalConnect(nbook,"line_changed",&VDKBEditor::OnLineChanged,false);
  SignalConnect(nbook,"pop_menu",&VDKBEditor::OnPopMenu,false);
  SignalConnect(nbook,"repeat_search_text",&VDKBEditor::RepeatSearch,false);
  SignalConnect(nbook,"no_more_undo",&VDKBEditor::NoMoreUndo,false);
  SignalConnect(nbook,"hilite_text",&VDKBEditor::Hilite,false);
  SignalConnect(nbook,"user_prompt",&VDKBEditor::UserPrompt,false);
  SignalConnect(nbook,"editor_help",&VDKBEditor::ShortCut,false);
  /*
    makes a timer for timed auto save
  */
  unsigned int autosavetime =
    atoi((char*) VDKBuilder::ideDefaults.editor.timedsave);
  if(autosavetime > 0)
    {
      autosavetimer = new VDKTimer(this,5000);
      autosavetimer->Parent(this);
      SignalConnect(autosavetimer,"timer_tick_signal",
                &VDKBEditor::OnAutosaveTimer,false);
    }
  else
    autosavetimer = NULL;
}
/*
 */
void
VDKBEditor::EnableMaker(bool flag)
{
  (*toolbar)[TOOLB_MAKE]->Enabled = flag;
  (*toolbar)[TOOLB_RUN]->Enabled = flag;
}
/*
 */
void
VDKBEditor::OnShow(VDKForm*)
{
  VDKBMainForm* owner = dynamic_cast<VDKBMainForm*>(Owner());
  if(owner)
    {
      int w,h;
      VDKPoint ownerPos = owner->Position;
      VDKBProjectManager* prjman = owner->PrjManager();
      VDKPoint prjmanPos = prjman->Position;
      gdk_window_get_size(GTK_WIDGET(prjman->Window())->window, &w, &h);
      VDKPoint prjmanSize(w,h);
      gdk_window_get_size(GTK_WIDGET(owner->Window())->window, &w, &h);
      VDKPoint ownerSize(w,h);
      VDKPoint p(ownerPos.X()+prjmanSize.X()+5 ,ownerPos.Y()+ownerSize.Y()+30);
      Position = p;
    }
 }
/*
 */
bool
VDKBEditor::NewForm(char* name)
{
  char* cc_ext = (char*) VDKBuilder::ideDefaults.unit.cc_ext;
  char* h_ext  = (char*) VDKBuilder::ideDefaults.unit.h_ext;
  // gets name without extension
  char* p = get_extension(name);
  int result = false;
  if(p)
    *p = '\0';

  // write .cc
  sprintf(buff,"%s.%s",name,cc_ext);
  FILE* fp = fopen(buff,"w+");
  if(!fp)
    return false;
  else
    result = WriteFormCC(name,fp);
  if(result)
    AddText(buff,true,true);
  else
    return result;

  // write .h
  sprintf(buff,"%s.%s",name,h_ext);
  fp = fopen(buff,"w+");
  if(!fp)
    return false;
  else
    result = WriteFormH(name,fp);
  if(result)
    AddText(buff,true,true);
  // write .frm
  sprintf(buff,"%s.%s",name,FORM_EXT);
  fp = fopen(buff,"w+");
  if(!fp)
    return false;
  else
    result = WriteFrm(name,fp);

  VDKBMainForm* owner = dynamic_cast<VDKBMainForm*> (Owner());
  VDKBProjectManager* prjman = NULL;
  if(owner)
    prjman = owner->PrjManager();
  if(prjman)
    {
      char local[256];
      sprintf(local,"%s_gui.%s",name,h_ext);
      fp = fopen(local,"w+");
      if(fp)
      prjman->Project()->WriteGuiHeaderParsingFrm(fp,buff);
      sprintf(local,"%s_gui.%s",name,cc_ext);
      fp = fopen(local,"w+");
      if(fp)
      prjman->Project()->WriteGUISetupParsingFrm(fp,buff);  
    }
  return result;
 }
/*
 */
void VDKBEditor::AddNewUnit()
{
  // read defaults
  char* cc_ext   = (char*) VDKBuilder::ideDefaults.unit.cc_ext;
  char* h_ext    = (char*) VDKBuilder::ideDefaults.unit.h_ext;
  char* unit     = (char*) VDKBuilder::ideDefaults.unit.def_name;
  int   count    = VDKBuilder::ideDefaults.unit.count;
  //VDKBText *text;
  // add .cc
  sprintf(buff,"%s%d.%s",unit,count,cc_ext);
  AddText(buff,true,true);
    // add .h
  sprintf(buff,"%s%d.%s",unit,count,h_ext);
  AddText(buff,true,true);
  // finished, update unit count
  VDKBuilder::ideDefaults.unit.count += 1;
}


/*
 */
extern "C" { int GetEditorTab(); };
extern bool EmacsServerStarted();
extern int StartEmacs(char ** args);
extern int EmacsPid();

void 
VDKBEditor::AddText(char* text_name, bool editable,bool hilite)
{

  ((VDKBMainForm*)Owner())->MakeEditor();
  VDKBText *text = new VDKBText(this,editable,text_name);
  text->SetTokens(tokenlist);
  VDKString Yes = CHECK_YES;
  // add a text to textlist
  textlist.add(text);
  nbook->AddText(text,text->ShortName(),hilite);
  nbook->ActivePage = textlist.size()-1;
  // forward text request to emacs server if any
  if(EmacsServerStarted())
    {
      char* args[3];
      args[0] = "emacsclient";
      args[1] = text_name;
      args[2] = NULL;
      StartEmacs(args);
    }
  (*toolbar)[8]->Enabled = hilite;
}

//////////////////////// signal process ////////////////////
bool
VDKBEditor::OnAutosaveTimer(VDKObject* sender)
{
  static unsigned int elapsedSecs = 0;
  elapsedSecs += 5;
  unsigned int savetime =
    atoi((char*) VDKBuilder::ideDefaults.editor.timedsave);
  savetime *= 60;
  if(! (elapsedSecs%savetime))
    FileSave(sender);
  else
    {
      char local[64];
      sprintf(local,"%02u:%02u:%02u",
            elapsedSecs/3600,
            (elapsedSecs%3600)/60,
            elapsedSecs%60);
      bar->Panels()[1]->Caption = local;
    }
  return true;
}
/*
 */
bool
VDKBEditor::JumpToError(VDKObject* )
{
  char *tokens = "$%";
  int t,z;
  int row = messages->Selected.Row();
  if(row < 0 || row >= messages->Tuples.size())
    return true;
  VDKString errmess = messages->Tuples[row][0]; 
  VDKString file;
  int line = 0;
  char* err = new char[strlen((char*) errmess)+1];
  strcpy(err,(char*) errmess);
  // change first two ":" with tokens
  for(t = 0,z=0; err[t]; t++)
    {
      if( err[t] == ':')
      {
        err[t] = tokens[z++];
        if(!tokens[z])
          break;
      }
    }
  char * p;
  if( (p = ExtractWord(err,buff,"","$")) )
    file = buff;
  if ( (p = ExtractWord(err,buff,"$","%")) )
    line = atoi(buff);
  if((line == 0) || access((char*) file ,F_OK) || 
     ( ! GoToLine(file,line,false,true)) ) // no enlight, shows bug
    {
      gdk_beep();
      bar->Panels()[0]->Caption = _("no error to go");
    }

  delete[] err;
  return true;
}
/*
 */

bool
VDKBEditor::GoToLine(VDKString& file, int line, bool enlight, bool with_icon)
{
  int t = 0;
  TextListIterator li(textlist);
  // activate or load a new text
  for(t = 0; li; li++,t++)
    {
      VDKString temp = li.current()->Filename();
      if( temp == file)
        break;
    }
  // not found, so load a new text
  if(t >= textlist.size())
      AddText((char*) file, true,true);
  nbook->ActivePage = t;
  // finally goes to line
  textlist[t]->GoToLine(line);
  // enlights putting an icon on the line
 if(with_icon)
   {
     textlist[t]->AddLineMark(line, "mark");
     /*
     GtkTextIter iter;
     int startpos = textlist[t]->Pointer; 

     gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER(textlist[t]->Buffer()),
                                              &iter,
                                              startpos);
     int icon = gtk_text_iter_get_char (&iter);
     if(icon != 0xFFFC)
     {
       VDKPixbuf *mark = new  VDKPixbuf(Owner(), mark_xpm);
       gtk_text_buffer_insert_pixbuf (GTK_TEXT_BUFFER(textlist[t]->Buffer()),
                              &iter,
                              mark->AsGdkPixbuf());
     }
     */
   }
 else if(enlight)
   {
     int startpos = textlist[t]->Pointer; 
     textlist[t]->SelectText(startpos,startpos+1);
   }
 return true;
}
/*
 */
bool
VDKBEditor::OnTextChanged(VDKObject* )
{
  // editor says that some text was changed
  // so let's user to know
  int activePage = nbook->ActivePage;
  char* p = textlist[activePage]->ShortName();
  if(textlist[activePage]->Changed)
    {
      sprintf(buff,"%s%s",_(editor_prompts[1]),p);
      bar->Panels()[0]->Caption = buff;
    }
  int line = textlist[activePage]->CurrentLine;
  sprintf(buff,"%s%d",editor_prompts[2],line);
  bar->Panels()[2]->Caption = buff;
  return true;
}
/*
 */
bool
VDKBEditor::OnPageChanged(VDKObject* sender)
{
  char local[256];
  int activePage;
  activePage = nbook->ActivePage;
  if(activePage < 0 || 
     activePage >= textlist.size()
     )
    return true;
  char* p = textlist[activePage]->ShortName();
  if(textlist[activePage]->Changed)
    {
      sprintf(buff,"%s%s",_(editor_prompts[1]),p);
      bar->Panels()[0]->Caption = buff;
    }
  else
    bar->Panels()[0]->Caption = " ";
  int line = textlist[activePage]->CurrentLine;
  sprintf(buff,"%s%d",_(editor_prompts[2]),line);
  bar->Panels()[2]->Caption = buff;
  // set to 0 last pos in search.
  last_pos = 0;
  // enable/disable form/unit toggle
  strcpy(local,textlist[activePage]->Filename());
  char* e = get_extension(local);
  if(e)
    {
      VDKBMainForm* owner = dynamic_cast<VDKBMainForm*>(Owner());
      *e = '\0';
      sprintf(buff,"%s.frm",local);
      if(owner)
      owner->EnableToggleFormUnit(!access(buff,F_OK),buff);
    }
  // enable syntax button
  (*toolbar)[8]->Enabled = textlist[activePage]->Hilite;
  // FIXME: set focus to text widget
  // Owner()->FocusWidget = textlist[activePage];
  return true;
}
/*
 */
bool
VDKBEditor::OnLineChanged(VDKObject* )
{
  int activePage = nbook->ActivePage;
  if(activePage < 0 || activePage >= textlist.size())
    return true;
  int line = textlist[activePage]->CurrentLine;
  sprintf(buff,"%s%d",_(editor_prompts[2]),line);
  bar->Panels()[2]->Caption = buff;
  return true;
}
/*
 */
bool
VDKBEditor::CanClose()
{
 UpdateFiles();
 // can be closed via mainform only.
 if(ForceToClose)
   {
     if(autosavetimer)
       autosavetimer->Stop();
     return true;
   }
 else
   {
     Visible = false;
     return false;
   }
}
/*
 */
extern int  AskUserToSaveFile(char* name);
void
VDKBEditor::UpdateFiles()
{
TextListIterator li(textlist);
for(;li;li++)
  {
    // has to be saved ?
    if(li.current()->Changed)
      {
      sprintf(buff,"%s",(char*) li.current()->Filename());
      if(AskUserToSaveFile(buff) == VDK_IDYES)
        {
          // never saved
          // it's a new unit, changes sentinel in .h
          if(access(li.current()->Filename(),F_OK))
            {
            // ask to user
            FileStringArray selections;
            VDKFileSaveAsDialog *child =
              new VDKFileSaveAsDialog(this,&selections,
                                _(file_dialog_prompts[3]));
            child->ShowModal();
            if(selections.size() > 0)
              {
                UpdateUnit(li.current(),selections[0]);
                li.current()->Save(selections[0]);
              }
            }
      
          // or unsaved ?
          else
            li.current()->Save((char*) li.current()->Filename());
          li.current()->Changed = false;
        }
      else
        // user forced to be considered saved
        li.current()->Changed = false;
      }
  }
}


/*
 toggle between hide/show as necessary
 */
void
VDKBEditor::ToggleMessages()
{
  bool f = message_docker->Visible;
  message_docker->Visible = f ? false : true;
}
/*
 */
void
VDKBEditor::FillMessages(VDKBStringList* list)
{
  message_docker->Visible = true;
  messages->Clear();
  messages->Freeze();
  VDKBStringListIterator li(*list);
  for(;li;li++)
    {
      char* p = (char*) li.current();
      messages->AddRow(&p);
    }
  messages->Thaw();
  if(list->size() > 0)
    messages->SelectRow(0,0);
}
/*
 */
void 
VDKBEditor::ClearMessages()
{
  // removes bug pixbuf from texts (if any)
  TextListIterator li(textlist);
  for(;li;li++)
    {
      li.current()->RemoveAllLineMarks();
      li.current()->Changed = false;
      /*
      GtkTextIter iter;
      VDKBText* text = li.current();
      gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER(text->Buffer()),&iter,0);
      while(gtk_text_iter_forward_char(&iter))
      {
        int bug = gtk_text_iter_get_char (&iter);
        if(bug == 0xFFFC)
          {
            GtkTextIter end;
            int pos =  gtk_text_iter_get_offset(&iter);
            gtk_text_buffer_get_iter_at_offset  (GTK_TEXT_BUFFER(text->Buffer()),
                                       &end,
                                       pos+1);
            gtk_text_buffer_delete (GTK_TEXT_BUFFER(text->Buffer()),
                              &iter,
                              &end);
            text->Changed = false;
          }
      }
      */

    }

  messages->Clear();
}
/*
 */
bool
VDKBEditor::OnPopMenu(VDKObject* )
{
  VDKBText* text;
  int activePage = nbook->ActivePage;
  if(activePage < 0 || activePage >= textlist.size())
    return true;
  else
    text = textlist[activePage];
  toggleHeader->Enabled = true;
  fileSave->Enabled = true;
  undo->Enabled = true;
  repeatsearch->Enabled = match != NULL;
  hilite->Enabled = text->Hilite;
  // pops menu
  popmenu->Popup();
  return TRUE;
}
/*
 */
bool
VDKBEditor::OnClosePage(VDKObject* )
{
int activePage = nbook->ActivePage;
VDKBText* text;
if(activePage < 0 || activePage >= textlist.size())
  return true;
else
  text = textlist[activePage];
//
if(text->Changed)
  {
    sprintf(buff,"%s", (char*) text->Filename());
    if(AskUserToSaveFile(buff) == VDK_IDYES)
      {
      // never saved
      if(access(text->Filename(),F_OK))
        {
          // ask to user
          FileStringArray selections;
          VDKFileSaveAsDialog *child =
            new VDKFileSaveAsDialog(this,&selections,
                              _(file_dialog_prompts[3]));
          child->ShowModal();
          if(selections.size() > 0)
            {
            UpdateUnit(text,selections[0]);
            text->Save(selections[0]);
            }
        }
      
      // or unsaved ?
      else
          text->SaveToFile((char*) text->Filename());
      text->Changed = false;
      }
  }
if(textlist.unlink(activePage))
  nbook->RemovePage(activePage);
// hide editor if no more pages
if(textlist.size() > 0)
  OnPageChanged(NULL);
else
  Hide();
return true;
}

/*
 */
void
VDKBEditor::UpdateUnit(VDKBText* text, VDKString& rep_s)
{
  /*
    ========================
    suspended since is buggy
    ========================
  //  char* cc_ext   = (char*) VDKBuilder::ideDefaults.unit.cc_ext;
  char* h_ext    = (char*) VDKBuilder::ideDefaults.unit.h_ext;
  VDKString ext;
  VDKString name = text->ShortName();
  VDKString replace;
  char *z = get_shortfilename(rep_s);
  if(z)   replace = z;
  else  return;
  if(!name.isNull())
    {
      // extract name and extension
      char *p = get_extension((char*) name);
      if(p)  { *p = '\0'; p++; ext = p; }
      else  return;
      p = get_extension(replace);
      if(p) *p = '\0';
      else return;
    }
  else
    return;
  // change sentinel
  if(!strcmp(ext,h_ext))
    {

      sprintf(buff,"_%s_h",(char*) name);
      VDKString match = buff;
      sprintf(buff,"_%s_h",(char*) replace);
      replace = buff;
      int pos = text->Search(match, 0, true);
      if(pos>=0)
      {
        pos = Replace(text,pos,match,replace);
        pos = text->Search(match, pos, true);
      }
      if(pos>=0)
      pos = Replace(text,pos,match,replace);
    }
  */
}
int
VDKBEditor::Replace(VDKBText* text, int pos, char* match, char* replace)
{
  text->Pointer = pos;
  text->ForwardDelete(strlen(match));
  text->Pointer = pos;
  text->TextInsert(replace);
  return pos+strlen(replace);
}
/*
 */
bool
VDKBEditor::OnToggleHeader(VDKObject* )
{
char* cc_ext   = (char*) VDKBuilder::ideDefaults.unit.cc_ext;
char* h_ext   = (char*) VDKBuilder::ideDefaults.unit.h_ext;
int activePage = nbook->ActivePage;
VDKBText* text;
if(activePage < 0 || activePage >= textlist.size())
  return true;
else
  text = textlist[activePage];
// look for that
VDKString name = text->Filename();
VDKString ext;
char* p = get_extension((char*) name);
if(p)
  {
    *p++ = '\0';
    ext = p;
    sprintf(buff,"%s.%s",(char*) name,
          (!strcmp(ext,cc_ext)) || (!strcmp(ext,"c")) ?
          h_ext :
          cc_ext);
    name = buff;
  }
else
  return true;

// search in list
int t = 0;
bool found = false;
bool exists =  !access(name,F_OK);

TextListIterator li(textlist);
for(;li;li++,t++)
{
  if(! strcmp(li.current()->Filename(),name))
    {
      found = true;
      break;
    }
}

if(found && exists)
{
  nbook->ActivePage = t;
  return true;
}
else if(! found && exists)
{
  AddText(name,true,true);
  nbook->ActivePage = textlist.size()-1;
}
else if(! exists)
{
  FileStringArray selections;
  VDKFileDialog *child = new VDKFileDialog(this,&selections,
                                 _(file_dialog_prompts[0]));
  sprintf(buff,"*.%s",
        (!strcmp(ext,cc_ext)) || (!strcmp(ext,"c")) ?
        h_ext :
        cc_ext);
  child->Filter = buff;
  child->ShowModal();
  if(selections.size() > 0)
    AddText(selections[0],true,true);
}
return true;
}
 /*
  * Simple save the file and set it as unchanged
  */
bool
VDKBEditor::FileSave(VDKObject* obj)
{
  int activePage = nbook->ActivePage;  //identify the active page
  if(activePage < 0 || activePage >= textlist.size())
    // called with obj = NULL by main form main menu or toolbar
  return obj == NULL ? false : true;

  VDKBText* text = textlist[activePage];
  // check if never saved
  if(access(text->Filename(),F_OK))
    {
      // ask to user
      FileStringArray selections;
      VDKFileSaveAsDialog *child =
      new VDKFileSaveAsDialog(this,&selections,
                        _(file_dialog_prompts[4]));
      child->ShowModal();
      if(selections.size() > 0)
      {
        UpdateUnit(text,selections[0]);
        text->Filename(selections[0]);
        nbook->Pages[activePage]->TabLabel->Caption = text->ShortName();
      }
      else
      {
        return true;
      }
    }
  if(text->Changed)
    {
      text->Save((char*) text->Filename());      //save text to file
      text->Changed = false;                     //set it as unchanged
      sprintf(buff,"%s:%s",
            _(editor_prompts[8]),
            (char*) text->Filename());
      bar->Panels()[0]->Caption = buff;
    }
  return true;
}
/*
 */
bool
VDKBEditor::FileSaveAs(VDKObject* )
{
  int activePage = nbook->ActivePage;
  FileStringArray selections;

  if(activePage < 0 || activePage >= textlist.size())
    return true;

  VDKFileSaveAsDialog *child =
    new VDKFileSaveAsDialog(this,&selections,
                      file_dialog_prompts[4]);
  child->ShowModal();
  if(selections.size() <= 0)
    return true;
  VDKBText* text = textlist[activePage];
  text->Filename(selections[0]);
  text->Save((char*) text->Filename());
  text->Changed = false;

  sprintf(buff,"%s:%s",
        editor_prompts[8],
        (char*) text->Filename());
  bar->Panels()[0]->Caption = buff;
  nbook->Pages[activePage]->TabLabel->Caption = text->ShortName();
  return true;
}
/*
 */
bool
VDKBEditor::Search(VDKObject*)
{
  char* st = NULL;
  int activePage = nbook->ActivePage;
  if(activePage < 0 || activePage >= textlist.size())
    return true;
  VDKBSearchForm *dlg = new VDKBSearchForm(this,&st);
  dlg->Setup();
  dlg->ShowModal();
  // dlg return st to search newly allocated (or NULL)
  if(st)
    {
      last_pos = 0;
      if(match)
      delete[] match;
      match = new char[strlen(st)+1];
      strcpy(match,st);
      delete[] st;
      VDKBText* text;
      text = textlist[activePage];
      last_pos = text->Search(match, last_pos, true);
      last_pos = last_pos > 0 ? last_pos + strlen(match): last_pos;
    }
  return true;
}
/*
 */
bool
VDKBEditor::Undo(VDKObject*)
{
  int activePage = nbook->ActivePage;
  if(activePage < 0 || activePage >= textlist.size())
    return true;
  else if (!textlist[activePage]->Undo())
          NoMoreUndo(NULL);
  return true;
}
/*
 */
bool
VDKBEditor::UserPrompt(VDKObject*)
{
  VDKBText* text;
  int activePage = nbook->ActivePage;
  if(activePage < 0 || activePage >= textlist.size())
    return true;
  text = textlist[activePage];
  // bar->Panels()[0]->Caption = (char*) text->UserBuffer;
  gdk_beep();
  return true;
}

/*
 */
bool
VDKBEditor::RepeatSearch(VDKObject*)
{
  VDKBText* text;
  int activePage = nbook->ActivePage;
  if(! match || activePage < 0 || activePage >= textlist.size())
    return true;
  text = textlist[activePage];
  int pos = text->Search(match, last_pos, true);
  sprintf(buff,"%s\n%s",
        _(search_dialog_prompts[19]),
        _(search_dialog_prompts[20])
        );
  if(pos >= 0)
    last_pos = pos+strlen(match);
  else if(Application()->VDKMessageBox(APPNAME,
                         buff,
                         VDK_ICONQUESTION|VDK_YESNO,
                         _(user_messages[user_ok]),
                         _(user_messages[user_no])) == VDK_IDYES)
    {
      last_pos = 0;
      RepeatSearch(NULL);
    }
  return true;
}
/*
 */
bool
VDKBEditor::NoMoreUndo(VDKObject*)
{
  sprintf(buff,"%s",_(editor_prompts[6]));
  bar->Panels()[0]->Caption = buff;
  gdk_beep();
return true;
}
/*
 */
void
VDKBEditor::ReplaceText(void)
{
  VDKBText* text;
  int activePage = nbook->ActivePage;
  if(activePage < 0 || activePage >= textlist.size())
    return ;
  else
    text = textlist[activePage];
  VDKBReplaceForm *dlg = new VDKBReplaceForm(this,text);
  dlg->Setup();
  dlg->ShowModal();
}

bool
VDKBEditor::Hilite(VDKObject* )
{
  VDKBText* text;
  int activePage = nbook->ActivePage;
  if(activePage < 0 || activePage >= textlist.size())
    return true;
  else
    text = textlist[activePage];
  text->Syntax = text->Syntax ? false : true;
  return true;
}

Generated by  Doxygen 1.6.0   Back to index