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

vdkb_prjman.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 USE_XDB
#include <vdkxdb2/vdkxdb.h>
#include <vdkxdb2/vdkxtable.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
#undef __REGEXP_LIBRARY_H__
#define __REGEXP_LIBRARY_H__ 1 // do not include builtin regex.h
// STUB #include <vdkb2/vdkb_ccpane.h>
#include <vdkb2/vdkb_prjman.h>
#include <vdkb2/vdkb_locale.h>
#include <vdkb2/vdkb_types.h>
#include <vdk/FileDialog.h>
#include <vdk/FileSaveAsDialog.h>
#include <vdkb2/vdkb.h>
#include <vdk/evlisthandle.h>
#include <vdkb2/vdkb_unit.h>
#include <vdkb2/vdkb_utils.h>

extern char *c_xpm[];
extern char *h_xpm[];
extern char *prj_node_xpm[];
extern char *unit_node_xpm[];
extern char *gear_xpm[];
static char buff[512];
extern char *ext_types[];
extern char *mininewform_xpm[];
extern VDKBuilder* TheApp;
// emacs support
extern bool EmacsServerStarted();
extern int StartEmacs(char ** args);
extern int EmacsPid();
// into vdkb.cc
extern char mime_file[];
////////////// SIGNAL STUFF ////////////////
DEFINE_SIGNAL_MAP(VDKBProjectManager,VDKForm)
  ON_SIGNAL(tree,select_node_signal,OnSelectRow)
  // ON_SIGNAL(toolbar,clicked_signal,HandleToolbar)
END_SIGNAL_MAP

DEFINE_EVENT_LIST(VDKBProjectManager,VDKForm);
DEFINE_SIGNAL_LIST(VDKBProjectManager,VDKForm);

bool
VDKBProjectManager::HandleToolbar(VDKObject* )
{
int button = toolbar->ButtonPressed;
switch(button)
  {
  case NEW_PROJECT_BUTTON:
    ((VDKBMainForm*) Owner())->NewProject(NULL);
    break;

  case ADD_UNIT_BUTTON:
    AddUnit();
    break;

  case REMOVE_UNIT_BUTTON:
    RemoveUnit();
    break;

  case ACTIVATE_EDITOR_BUTTON:
    OnSelectRow(tree);
    break;

  case FORM_PROPS_BUTTON:
    // select root (thus form)
    if(objInspector && ActiveChild.child)
        objInspector->SelectWidgetByTree(NULL);
    break;
  }
return true;
}
/*
activate editor
on a selected tree
node
 */
void
VDKBProjectManager::ActivateEditor(VDKTreeNode node,
                           bool editable,
                           bool hilite)
{
  if(! node)
    return;
  VDKBMainForm* mainform = (VDKBMainForm*) Owner();
  VDKBEditor* editor =   mainform->MakeEditor();
  //look for the file pointed by node
  int t = 0;
  bool found = false;
  TextListIterator li(editor->textlist);
  for(;li;li++,t++)
    {
      if(! strcmp(li.current()->Filename(),tree->Key(node)))
      {
        found = true;
        break;
      }
    }
  // does not exist in editor, make it
  if(!found)
    editor->AddText(tree->Key(node),editable,hilite);
  // call emacs client even if found
  else if(EmacsServerStarted())
    {
      char* args[3];
      args[0] = "emacsclient";
      args[1] = tree->Key(node);
      args[2] = NULL;
      StartEmacs(args);
    }
  // activate page containing file
  editor->nbook->ActivePage = t;
  // set toggle form/unit
  char* cc_ext = (char*) VDKBuilder::ideDefaults.unit.cc_ext;
  char* p = get_extension(tree->Key(node));
  if(p)
    {
      p++;
      if(!strcmp(p,cc_ext))
      {
        char local[256];
        strcpy(local,tree->Key(node));
        char* q = get_extension(local);
        if(q)
          {
            *q = '\0';
            sprintf(buff,"%s.frm",local);
            mainform->EnableToggleFormUnit(true,buff);
          }
        else
          mainform->EnableToggleFormUnit(false,buff);
      }
      else
      mainform->EnableToggleFormUnit(false,buff);
    }
}

/*
activate editor
on a generic file
pointed by <text>
 */
void
VDKBProjectManager::ActivateEditor(char* text,
                           bool editable,
                           bool hilite)
{
  if(! text)
    return;
  VDKBMainForm* mainform = (VDKBMainForm*) Owner();
  VDKBEditor* editor =  mainform->MakeEditor();
  //look for the file int text list
  int t = 0;
  bool found = false;
  TextListIterator li(editor->textlist);
  for(;li;li++,t++)
    {
      if(! strcmp(li.current()->Filename(),text))
      {
        found = true;
        break;
      }
    }
  // does not exist in editor, make it
  if(! found)
    editor->AddText(text,editable,hilite);
  // activate page containing file
  editor->nbook->ActivePage = t;
  // set toggle form/unit
  char* cc_ext = (char*) VDKBuilder::ideDefaults.unit.cc_ext;
  char* p = get_extension(text);
    if(p)
    {
      p++;
      if(!strcmp(p,cc_ext))
      {
        char local[256];
        strcpy(local,text);
        char* q = get_extension(local);
        if(q)
          {
            *q = '\0';
            sprintf(buff,"%s.frm",local);
            mainform->EnableToggleFormUnit(true,buff);
          }
        else
          mainform->EnableToggleFormUnit(false,buff);
      }
      else
      mainform->EnableToggleFormUnit(false,buff);
    }
}

/*
 */
bool
VDKBProjectManager::OnSelectRow(VDKObject* obj)
{
  VDKCustomTree* tree = dynamic_cast<VDKCustomTree*>(obj);
  if(!tree ) return true;
  VDKTreeNode node = tree->SelectedNode;
  if(! node) return true;
  // get stored info
  gpointer p = gtk_ctree_node_get_row_data(GTK_CTREE(tree->CustomWidget()),
                                 node);
  VDKBUnit*  unit = (VDKBUnit*) p;

  // is a leaf without other info, edit it
  if(! p && tree->IsLeaf(node))
        ActivateEditor(node);
  // is a form unit
  // create or show form
  else if(p && (p == (gpointer) form_unit))
    {
      char* t = new char[strlen(tree->Key(node))+1];
      strcpy(t,tree->Key(node));
      char* p = get_extension(t);
      if(p) *p = '\0';
      VDKString text = t;
      text += ".";
      text += FORM_EXT;
      // create a form parsing .frm file (or raise)
      VDKBGuiForm* form = CreateForm(tree->Key(node));
      // make inspector
      if(form)
      {
        if( !objInspector)
          {
            objInspector = new VDKBObjectInspector(this,NULL);
            objInspector->Setup();
            objInspector->Show();
          }
        else if(objInspector->Iconized)
          objInspector->Iconized = false;
        else
          objInspector->Raise();
        objInspector->LoadTree(form);
        form->Raise();
      }
      // set automa
      VDKBMainForm* mainform = (VDKBMainForm*) Owner();
      mainform->Automa(automa_edit_form_on);
      delete[] t;
    }
  // isn't a leaf and is editable, edit it
  else if(p && (unit->Type() == c_source_unit))
      ActivateEditor(node);

  return true;
}
/*
 */
bool VDKBProjectManager::OnReleaseButton(VDKObject* obj, GdkEvent*)
{
  /*
  VDKCustomTree* tree = dynamic_cast<VDKCustomTree*>(obj);
// run time type checking
  if(!tree)
    return true;
  printf("\nVDKBProjectManager::OnReleaseButton()");
  fflush(stdout);
  VDKTreeNode node = tree->SelectedNode;
// no node selected so get away
if(! node)
  return true;
// refuses multiple selections
// deselecting all nodes
if(tree->Selections().size() > 1)
  {
    gtk_ctree_unselect_recursive (GTK_CTREE(tree->CustomWidget()), NULL);
    (*toolbar)[ADD_UNIT_BUTTON]->Enabled = true;
    (*toolbar)[REMOVE_UNIT_BUTTON]->Enabled = false;
    (*toolbar)[ACTIVATE_EDITOR_BUTTON]->Enabled = false;
    (*toolbar)[FORM_PROPS_BUTTON]->Enabled = false;
    return true;
  }
// now can proceed
// is root ?
if(node == root)
  {
    (*toolbar)[ADD_UNIT_BUTTON]->Enabled = true;
    (*toolbar)[REMOVE_UNIT_BUTTON]->Enabled = false;
    (*toolbar)[ACTIVATE_EDITOR_BUTTON]->Enabled = false;
    (*toolbar)[FORM_PROPS_BUTTON]->Enabled = false;
    // prompts name & status
    VDKString name = project->Name;
    sprintf(buff,"%s - %s",
          (char*) name,
          _(prj_status[project->Status]));
    bar->Panels()[0]->Caption = buff;
  }
// is a node ?
else if(! tree->IsLeaf(node))
    {
      // prompts name & status
      VDKBUnit*  unit = (VDKBUnit*)
      gtk_ctree_node_get_row_data(GTK_CTREE(tree->CustomWidget()),node);
      // not a .frm
      if( ((gpointer) unit) != ((gpointer) form_unit))
      {
        (*toolbar)[ADD_UNIT_BUTTON]->Enabled = false;
        (*toolbar)[REMOVE_UNIT_BUTTON]->Enabled = true;
        (*toolbar)[ACTIVATE_EDITOR_BUTTON]->Enabled =
          unit->Type() == c_source_unit ? true : false;
        (*toolbar)[FORM_PROPS_BUTTON]->Enabled = false;
        sprintf(buff,"%s.%s - %s",
              (char*) VDKString(unit->Name()),
              ext_types[unit->Type()],
              _(prj_status[unit->Status]));
        bar->Panels()[0]->Caption = buff;
      }
      else
      {
        (*toolbar)[ADD_UNIT_BUTTON]->Enabled = false;
        (*toolbar)[REMOVE_UNIT_BUTTON]->Enabled = false;
        (*toolbar)[ACTIVATE_EDITOR_BUTTON]->Enabled = true;
        (*toolbar)[FORM_PROPS_BUTTON]->Enabled = (ActiveChild.child) ? true : false;
        bar->Panels()[0]->Caption = "";
      }
    }
// is a leaf
else
    {
      gpointer p =
      gtk_ctree_node_get_row_data(GTK_CTREE(tree->CustomWidget()),node);
      (*toolbar)[ADD_UNIT_BUTTON]->Enabled = false;
      (*toolbar)[REMOVE_UNIT_BUTTON]->Enabled = false;
      (*toolbar)[ACTIVATE_EDITOR_BUTTON]->Enabled = true;
      (*toolbar)[FORM_PROPS_BUTTON]->Enabled =
      ((p == (gpointer) form_unit) && (ActiveChild.child)) ?
      true : false;
      bar->Panels()[0]->Caption = "";
    }
  */
  return false;
}

void VDKBProjectManager::OnTreeSelection(GtkWidget* wid,
                               GtkCTreeNode* node,
                               int column,
                               gpointer gp)

{
  VDKBProjectManager* prjman = reinterpret_cast<VDKBProjectManager*>(gp);
  VDKCustomTree* tree = prjman->tree;
// run time type checking
  if(!tree)
    return ;

  //  VDKTreeNode node = tree->SelectedNode;
  // no node selected so get away
  if(! node)
    return ;
  // refuses multiple selections
  // deselecting all nodes
  if(tree->Selections().size() > 1)
    {
      gtk_ctree_unselect_recursive (GTK_CTREE(tree->CustomWidget()), NULL);
      (*prjman->toolbar)[ADD_UNIT_BUTTON]->Enabled = true;
      (*prjman->toolbar)[REMOVE_UNIT_BUTTON]->Enabled = false;
      (*prjman->toolbar)[ACTIVATE_EDITOR_BUTTON]->Enabled = false;
      (*prjman->toolbar)[FORM_PROPS_BUTTON]->Enabled = false;
      return ;
    }
  // now can proceed
  // is root ?
  if(node == prjman->root)
    {
      (*prjman->toolbar)[ADD_UNIT_BUTTON]->Enabled = true;
      (*prjman->toolbar)[REMOVE_UNIT_BUTTON]->Enabled = false;
      (*prjman->toolbar)[ACTIVATE_EDITOR_BUTTON]->Enabled = false;
      (*prjman->toolbar)[FORM_PROPS_BUTTON]->Enabled = false;
      // prompts name & status
      VDKString name = prjman->project->Name;
      sprintf(buff,"%s - %s",
            (char*) name,
            _(prj_status[prjman->project->Status]));
      prjman->bar->Panels()[0]->Caption = buff;
    }
  // is a node ?
  else if(! tree->IsLeaf(node))
    {
      // prompts name & status
      VDKBUnit*  unit = (VDKBUnit*)
      gtk_ctree_node_get_row_data(GTK_CTREE(tree->CustomWidget()),node);
      // not a .frm
      if( ((gpointer) unit) != ((gpointer) form_unit))
      {
        (*prjman->toolbar)[ADD_UNIT_BUTTON]->Enabled = false;
        (*prjman->toolbar)[REMOVE_UNIT_BUTTON]->Enabled = true;
        (*prjman->toolbar)[ACTIVATE_EDITOR_BUTTON]->Enabled =
          unit->Type() == c_source_unit ? true : false;
        (*prjman->toolbar)[FORM_PROPS_BUTTON]->Enabled = false;
        sprintf(buff,"%s.%s - %s",
              (char*) VDKString(unit->Name()),
              ext_types[unit->Type()],
              _(prj_status[unit->Status]));
        prjman->bar->Panels()[0]->Caption = buff;
      }
      else
      {
        (*prjman->toolbar)[ADD_UNIT_BUTTON]->Enabled = false;
        (*prjman->toolbar)[REMOVE_UNIT_BUTTON]->Enabled = false;
        (*prjman->toolbar)[ACTIVATE_EDITOR_BUTTON]->Enabled = true;
        (*prjman->toolbar)[FORM_PROPS_BUTTON]->Enabled = (prjman->ActiveChild.child) ? true : false;
        prjman->bar->Panels()[0]->Caption = "";
      }
    }
  // is a leaf
  else
    {
      gpointer p =
      gtk_ctree_node_get_row_data(GTK_CTREE(tree->CustomWidget()),node);
      (*prjman->toolbar)[ADD_UNIT_BUTTON]->Enabled = false;
      (*prjman->toolbar)[REMOVE_UNIT_BUTTON]->Enabled = false;
      (*prjman->toolbar)[ACTIVATE_EDITOR_BUTTON]->Enabled = true;
      (*prjman->toolbar)[FORM_PROPS_BUTTON]->Enabled =
      ((p == (gpointer) form_unit) && (prjman->ActiveChild.child)) ?
      true : false;
      prjman->bar->Panels()[0]->Caption = "";
    }
  return ;
}

/////////////////////////////////////////////
/*
 */
VDKBProjectManager::VDKBProjectManager(VDKForm* owner):
  VDKForm(owner)
{
project = NULL;
root = NULL;
ForceToClose = false;
Changed = false;
ActiveChild.child = NULL;
ActiveChild.name = "";
objInspector = NULL;
}
/*
 */
VDKBProjectManager::~VDKBProjectManager()
{
if(project)
  delete project;
}
/*
 */
/*
  NLS translation tables
 */
extern char * prjman_prompts[];
void
VDKBProjectManager::Setup()
{
  //
  Title = _(prjman_prompts[0]);
  // a notebook for units and classes lists
  panebar = new VDKNotebook(this);
  panebar->Scrollable = true;
  Add( panebar);
  // a vbox for units list page
  VDKBox *vbox = new VDKBox(this,v_box);
  const char* booktitle = _("Browse units");
  panebar->AddPage( vbox, booktitle/*,unit_node_xpm,unit_node_xpm*/);
  // add next parts of units list to vbox
  // a separator
  VDKSeparator *sep = new VDKSeparator(this,h_separator);
  vbox->Add(sep,l_justify,false,false,false);
  // the toolbar
  // toolbar = new VDKToolbar(this);
  toolbar = new VDKHLButtonBar(this,h_box,shadow_etched_in);
  // toolbar->Style = GTK_TOOLBAR_BOTH;
  // toolbar->Spacing = 5;
  /* 
  toolbar->AddButton(prjman_pixmaps[1],NULL,
                 _(prjman_prompts[1])
                 );
  toolbar->AddButton(prjman_pixmaps[2],NULL,
                 _(prjman_prompts[2])
                 );
  toolbar->AddButton(prjman_pixmaps[3],NULL,
                 _(prjman_prompts[3])
                 );
  toolbar->AddButton(prjman_pixmaps[4],NULL,
                 _(prjman_prompts[4])
                 );
  toolbar->AddButton(prjman_pixmaps[5],NULL,
                 _(prjman_prompts[5])
                 );
  */
  toolbar->AddButton((const char**)prjman_pixmaps[1],_(prjman_prompts[1]));
  toolbar->AddButton((const char**)prjman_pixmaps[2],_(prjman_prompts[2]));
  toolbar->AddButton((const char**)prjman_pixmaps[3],_(prjman_prompts[3]));
  toolbar->AddButton((const char**)prjman_pixmaps[4],_(prjman_prompts[4]));
  toolbar->AddButton((const char**)prjman_pixmaps[5],_(prjman_prompts[5]));

  (*toolbar)[ADD_UNIT_BUTTON]->Enabled = false;
  (*toolbar)[REMOVE_UNIT_BUTTON]->Enabled = false;
  (*toolbar)[ACTIVATE_EDITOR_BUTTON]->Enabled = false;
  (*toolbar)[FORM_PROPS_BUTTON]->Enabled = false;
  // toolbar->Borderless = true;
  vbox->Add(toolbar,l_justify,false,false,false);
  SignalConnect(toolbar,"clicked",&VDKBProjectManager::HandleToolbar,false);
  // another sep
  sep = new VDKSeparator(this,h_separator);
  vbox->Add(sep,l_justify,false,false,false);
  // the widgets tree
  vbox->Add(tree = new VDKBCustomTree(this,1,NULL, GTK_SELECTION_SINGLE));//GTK_SELECTION_EXTENDED
  // cast white background to override some gtk-themes defaults
  // tree->NormalBackground = clWhite;
  bar = new VDKPanelbar(this);
  vbox->Add(bar,l_justify,false,false,false);
  //  EventConnect(tree,"button_release_event", &VDKBProjectManager::OnReleaseButton);
  // SignalConnect(tree,"tree_select_row",&VDKBProjectManager::OnTreeSelection);
  gtk_signal_connect( GTK_OBJECT(tree->CustomWidget()),
                  "tree_select_row",
                  GTK_SIGNAL_FUNC(VDKBProjectManager::OnTreeSelection),  
                  (gpointer) this);

  // make and add classes pane as a new page in panebar
  // STUB   cpane = new VDKBCCPane(this);
  // cpane->Setup();
  // booktitle = _("Browse classes");
  // panebar->AddPage( cpane, booktitle/*,class_xpm,class_xpm*/);
  // all done
  SetSize(300,250);
  // allows to grow
  // denies to shrink and autoshrink
  gtk_window_set_policy(GTK_WINDOW(Window()),false,true,false);
}

/*
 */
void
VDKBProjectManager::OnShow(VDKForm*)
{
  int w,h;
  VDKPoint ownerPos = Owner()->Position;
  gdk_window_get_size(GTK_WIDGET(Owner()->Window())->window, &w, &h);
  VDKPoint ownerSize = VDKPoint(w,h);
  VDKPoint p(ownerPos.X(),ownerPos.Y()+ownerSize.Y()+30);
  Position = p;
  // check mime type
  if(*mime_file)
      OpenProject(mime_file);
   
  else
    {   
      // load last session
      char* save = (char*) VDKBuilder::ideDefaults.project.save_session;
      if(!strcmp(save,CHECK_YES))
      LoadLastSession();
    }
}
/*
 */
static char *avoid = "\"\r\n\t";
#define LAST_SESSION_PRJMAN_DO "project_manager_do"
#define LAST_SESSION_MAINFORM_POS "mainform_pos:"
#define LAST_SESSION_PRJMAN_ALLOCATION "prjman_alloc:"
#define LAST_SESSION_EDITOR_ALLOCATION "editor_alloc:"
#define LAST_SESSION_WI_ALLOCATION "wi_alloc:"
#define LAST_SESSION_OPEN_FILE "open_file:"
#define LAST_SESSION_OPEN_FORM "open_form:"
#define LAST_SESSION_POS_FORM "pos_form:"
#define LAST_SESSION_OPEN_TEXT "open_text:"
#define LAST_SESSION_ACTIVE_TEXT "active_text:"
#define LAST_SESSION_ACTIVE_TEXT_POS "active_text_pos:"
#define LAST_SESSION_END_KEY ";"
#define RIGHT_BRACE "}"
static 
VDKPoint getpos(char* s)
{
  VDKPoint point(0,0);
  char* p = strchr(s,',');
  if(p)
    {
      *p = '\0';
      p++;
      point.x = atoi(s);
      point.y = atoi(p);
    }
  return point;
}

void
VDKBProjectManager::LoadLastSession()
{
  // load last session file
  char *key = NULL;
  char* buffer = NULL,*p,*section;
  struct stat info;
  char* file;
  FILE* fp;
  // look at user home
  sprintf(buff,"%s/.vdkb2/res/last.session",(char*) TheApp->user_home);
  file = buff;
  // no last session here
  if(stat(file,&info) == -1)
    return;
  else
    fp = fopen(file,"r");
  // filters file cutting unnecessary chars.
  if(fp)
    {
      int c;
      buffer = p = new char[info.st_size+1];
      while( (c = fgetc(fp)) != EOF)
      {
        if (!strchr (avoid, c))
          *p++ = (char) c;
      }
      *p = '\0';
      fclose(fp);
    }
  else 
    return;
  // read project to open
  key = new char[1024*10];
  if((section = ExtractSection(buffer,
                         LAST_SESSION_PRJMAN_DO,
                         RIGHT_BRACE)))
    {
      VDKBMainForm* mainform = (VDKBMainForm*) Owner();
      // extracts project file name to open 
      if((ExtractWord(section,key,
                      LAST_SESSION_OPEN_FILE,
                      LAST_SESSION_END_KEY)))
      {
        if(access(key,F_OK))
          {
            sprintf(buff,_("Could not open last session %s"),key);
            Application()->VDKMessageBox(APPNAME,
                              buff,
                              VDK_OK| VDK_ICONINFORMATION,
                              _(user_messages[user_cancel]),
                              NULL,5000);
            return;
          }
       else
         OpenProject(key,false);
      }
      else
      goto  DEAD_END;
      // extract main form position
      if((ExtractWord(section,key,
                      LAST_SESSION_MAINFORM_POS,
                      LAST_SESSION_END_KEY)))
      {
        VDKPoint pos = getpos(key);
        if(mainform)
          mainform->Position = pos;
      }
      // extracts forms names to open
      if((ExtractWord(section,key,
                      LAST_SESSION_OPEN_FORM,
                      LAST_SESSION_END_KEY)))
      {
        VDKBStringList flist;
        char* token;
        VDKBGuiForm* form = NULL;
        if( (token = strtok(key,",")) )
        {
          if(!objInspector)
            {
            objInspector = new VDKBObjectInspector(this,NULL);
            objInspector->Setup();
            objInspector->Show();
            }
          // set automa
          mainform->Automa(automa_edit_form_on);
          // load list with all form names
          do
            {
            flist.add(VDKString(token));
            } while( (token = strtok(NULL,",")) );
          // iterates on string list
          for(VDKBStringListIterator li(flist);li;li++)
            {
            // create a form parsing .frm file
            form = CreateForm((char*) li.current());
            if(form)
              form->Show();
            }
          if(form)
            objInspector->LoadTree(form);
          // reset changes on forms
          objInspector->FormNeedToBeChanged(false);
        }
      }
      // extracts forms position
      if((ExtractWord(section,key,
                      LAST_SESSION_POS_FORM,
                      LAST_SESSION_END_KEY)))
      {
        char* p = strtok(key,"-");
        if(p)
          {
            int t = 0;
            do
            {
              VDKPoint point = getpos(p);
              if(t < formlist.size())
                formlist[t]->Position = point;
              t++;
            } while( ( p = strtok(NULL,"-")) );
          }
                   
      }
      // extracts text names to open on editor
      if((ExtractWord(section,key,
                      LAST_SESSION_OPEN_TEXT,
                      LAST_SESSION_END_KEY)))
      {
        VDKBStringList flist;
        char* token;
        int t = 0;
        if( (token = strtok(key,",")) )
          {
            VDKBMainForm* mainform = (VDKBMainForm*) Owner();
            VDKBEditor* editor =  mainform->MakeEditor();
            // load list with all text names
            do
            {
              flist.add(VDKString(token));
            } while( (token = strtok(NULL,",")) );
            // iterates on string list
            for(VDKBStringListIterator li(flist);li;li++,t++)
            {
              bool found = false;
              TextListIterator lt(editor->textlist);
              for(;lt;lt++)
                {
                  if(! strcmp(lt.current()->Filename(),
                          (char*) li.current()))
                  {
                    found = true;
                    break;
                  }
                }
              // does not exist in editor, make it
              if(!found)
                editor->AddText((char*) li.current(),true,true);
            }
          }
      }
      // extract project manager allocation
      if((ExtractWord(section,key,
                      LAST_SESSION_PRJMAN_ALLOCATION,
                      LAST_SESSION_END_KEY)))
      {
        char* p = strchr(key,'-');
        if(p)
          {
            *p = '\0';
            p++;
            VDKPoint pos = getpos(key);
            VDKPoint size = getpos(p);
            Position = pos;
            SetFormSize(size);
            }
      }
      // extract editor allocation
      if((ExtractWord(section,key,
                      LAST_SESSION_EDITOR_ALLOCATION,
                      LAST_SESSION_END_KEY)))
      {
        VDKBEditor* editor =  mainform->MakeEditor();
        if(editor)
          {
            char* p = strchr(key,'-');
            if(p)
            {
              *p = '\0';
              p++;
              VDKPoint pos = getpos(key);
              VDKPoint size = getpos(p);
              editor->Position = pos;
              editor->SetFormSize(size);
            }
          }
      }
      // extract wi allocation
      if((ExtractWord(section,key,
                      LAST_SESSION_WI_ALLOCATION,
                      LAST_SESSION_END_KEY)))
      {
        char* p = strchr(key,'-');
        if(p)
          {
            *p = '\0';
            p++;
            VDKPoint pos = getpos(key);
            VDKPoint size = getpos(p);
            if(objInspector)
            {
              objInspector->Position = pos;
              // objInspector->SetFormSize(size);
            }
          }
      }
      // extract active text and last text cursor position
      if((ExtractWord(section,key,
                      LAST_SESSION_ACTIVE_TEXT,
                      LAST_SESSION_END_KEY)))
      {
        bool found = false;
        int t = 0;
        VDKBEditor* editor =  mainform->MakeEditor();
        if(editor)
          {
            TextListIterator lt(editor->textlist);
            for(;lt;lt++,t++)
            {
              if(! strcmp(lt.current()->Filename(), key))
                {
                  found = true;
                  break;
                }
            }
            // 
            if(found)
            {
              editor->nbook->ActivePage = t;
              (editor->textlist)[t]->GrabFocus();
              if((ExtractWord(section,key,
                          LAST_SESSION_ACTIVE_TEXT_POS,
                          LAST_SESSION_END_KEY)))
                {
                  int pos = atoi(key); 
                  (editor->textlist)[t]->ScrollToPos(pos);
                  /*                 
                  GtkWidget *wid = 
                  (editor->textlist)[t]->WrappedWidget();
                  GtkAdjustment *adj = 
                  GTK_ADJUSTMENT(GTK_TEXT_VIEW(wid)->vadjustment);
                  gtk_adjustment_value_changed(adj);
                  */
                }
            }
          }
      }
      delete[] section;
    }
  else
    goto  DEAD_END;
  
  // opens all text editors
  // opens all child forms
 DEAD_END:
  if(buffer)
    delete[] buffer;
  if(key)
    delete[] key;
}
/*
 */
extern VDKPoint mainformLastPosition;
bool
VDKBProjectManager::SaveLastSession()
{
  FILE* fp;
  // look at user home
  if(project)
    {
      VDKPoint p,s;
      VDKBMainForm* mainform = (VDKBMainForm*) Owner();
      VDKBEditor* editor =  mainform->MakeEditor();
      sprintf(buff,"%s/.vdkb2/res/last.session",(char*) TheApp->user_home);
      fp = fopen(buff,"w+");
      if(!fp)
      return false;
      // saves project name
      fprintf(fp,"%s {\n %s\n\t%s.prj;",
            LAST_SESSION_PRJMAN_DO,
            LAST_SESSION_OPEN_FILE,
            (char *) project->PathName);
      // saves main form last position
      // global mainformLastPosition is set by
      // main form CanClose(). 
      // At this points underlying mainform gtk+
      // widget is already destroyed and isn't
      // possible access to his position.
      p = mainformLastPosition;
      fprintf(fp,"\n\t%s%d,%d;",
            LAST_SESSION_MAINFORM_POS,
            p.x,p.y);
     // saves prjmanager allocation
      p = Position;
      s = VDKPoint(Window()->allocation.width,Window()->allocation.height);
      fprintf(fp,"\n\t%s%d,%d-%d,%d;",
            LAST_SESSION_PRJMAN_ALLOCATION,
            p.x,p.y,s.x,s.y);
      // saves editor allocation
      if(editor && editor->Visible)
      {
        p = editor->Position;
        s = VDKPoint(editor->Window()->allocation.width,
                   editor->Window()->allocation.height);
        fprintf(fp,"\n\t%s%d,%d-%d,%d;",
              LAST_SESSION_EDITOR_ALLOCATION,
              p.x,p.y,s.x,s.y);
      }
      // saves WI allocation
      if(objInspector)
      {
        p = objInspector->Position;
        s = VDKPoint(objInspector->Window()->allocation.width,
                   objInspector->Window()->allocation.height);
        fprintf(fp,"\n\t%s%d,%d-%d,%d;",
              LAST_SESSION_WI_ALLOCATION,
              p.x,p.y,s.x,s.y);
      }
      // saves forms name
      int t = 0, j = 0;
      if(formlist.size() > 0)
      {
        fprintf(fp,"\n %s",LAST_SESSION_OPEN_FORM);
        j = formlist.size();
        GuiFormListIterator li(formlist);
        for (;li;li++,t++)
          {
            // save only if visible
            if(li.current()->Visible)
            {
              fprintf(fp,"\n\t%s",(char*) li.current()->FileName());
              if(t < j-1)
                fprintf(fp,",");
            }
          }
        fprintf(fp,";");
        // saves forms positions
        fprintf(fp,"\n %s",LAST_SESSION_POS_FORM);
        li.restart();
        t = 0;
        for (;li;li++,t++)
          {
            // save only if visible
            if(li.current()->Visible)
            {
              VDKPoint p = li.current()->Position;
              fprintf(fp,"\n\t%d,%d",p.x,p.y);
              if(t < j-1)
                fprintf(fp,"-");
            }
          }
        fprintf(fp,";");
      }
      // text editor section
      // saves texts name
      t = 0;
      j = editor->textlist.size();
      if(j > 0)
      {
        fprintf(fp,"\n %s",LAST_SESSION_OPEN_TEXT);
        for(TextListIterator li(editor->textlist);li;li++,t++)
          {
            fprintf(fp,"\n\t%s",(char*) li.current()->Filename());
            if(t < j-1)
            fprintf(fp,",");
          }
        fprintf(fp,";");
        // saves active text
        int a = editor->nbook->ActivePage;
        if(a >= 0 && a < j)
          {
            fprintf(fp,"\n %s",LAST_SESSION_ACTIVE_TEXT);
            fprintf(fp,"\n\t%s",(char*) editor->textlist[a]->Filename());
            fprintf(fp,";");
            // saves active text cursor position
            fprintf(fp,"\n %s",LAST_SESSION_ACTIVE_TEXT_POS);
            fprintf(fp,"\n\t%d",(int) editor->textlist[a]->Pointer);
            fprintf(fp,";");
          }
      }
      // end of section
      fprintf(fp,"\n}");
      fclose(fp);
      return true;
    }
  else
    return false;
}
/*
 */
void
VDKBProjectManager::AddNewProject(char* name, int type, char* author, char* email, bool gpld, bool updatelru)
{
  if(type < 0)
    return;

  if(project)
  {
    // this should manage project closing
    // (saving all prj stuff)
    CanClose();
    //
    // force to close all child form (if any)
    formlist.Destroy();
    if(objInspector)
      {
      objInspector->ForceToClose = true;
      objInspector->Close();
      objInspector = NULL;
      }
    ActiveChild.child = NULL;
    // removes all editor page
    VDKBMainForm* mainform = (VDKBMainForm*) Owner();
    VDKBEditor* editor = mainform->Editor();
    if( editor)
      {
      int t = 0;
      while( (t = editor->nbook->Pages.size()) > 0)
          editor->nbook->RemovePage(t-1);
      editor->textlist.flush();
      }
    delete project;
    project = NULL;

    //STUB    cpane->Clean(); // clear old classes
  }

  if(type >= 0)
    project = new VDKBProject(this, name, type, author, email, gpld, true);

 // makes template files
 bool result = false;

 switch(type)
   {
   case vdk_project:
     result = project->CreateTemplatesFilesForVDK(type);
     break;
   case console_project:
     result = project->CreateTemplatesFilesForConsole();
     break;
   case vdk_gnome_project:
     result = project->CreateTemplatesFilesForVDK(type);
     break;
   default:
     break;
   }

 if(result)
   {
     LoadTree();
     ((VDKBMainForm*) Owner())->Automa(automa_prjman_on);
     // change to project dir
     VDKString dir = project->Path;
     chdir((char*) dir);
     // activate editor on project_name.cc
     char* cc_ext = (char*) VDKBuilder::ideDefaults.unit.cc_ext;
     VDKString mainsource = project->PathName;
     mainsource += ".";
     mainsource += cc_ext;
     ActivateEditor((char*) mainsource,true,true);
     VDKBMainForm* mainform = (VDKBMainForm*) Owner();
#if HAVE_GNOME
     // enable gnome widget toolbar pending on project typedef
     if(project->Type == vdk_gnome_project)
       mainform->EnableGnomeWidgets(true);
     else
       mainform->EnableGnomeWidgets(false);
#endif
     // update lru manager
     if(mainform->LruManager() && updatelru)
       {
       mainform->LruManager()->Update(name);
       mainform->UpdateLRU();
       }

     // STUB update class viewer for project
     // cpane->reset_pane();
     // cpane->LoadClassTree((char*) project->Path);
   }

}
/*
 */
#if USE_XDB
extern bool LoadXdbOptions(VDKXDatabase* db, char* filename);
#endif
void
VDKBProjectManager::OpenProject(char* filename, bool updatelru)
{
  FileStringArray selections;
  char* prj_ext   = (char*) VDKBuilder::ideDefaults.project.prj_ext;
  if(!filename)
    {
      VDKFileDialog *child = new VDKFileDialog(this,&selections,
                                 _(file_dialog_prompts[0]));
      sprintf(buff,"*.%s",prj_ext);
      child->Filter = buff;
      child->ShowModal();
      if(selections.size() <= 0)
      return;
    }
  else
    {
      selections.resize(1);
      selections[0] = filename;
    }
  // load project
  VDKBProject *temp =  new VDKBProject(this,(char*) selections[0]);
  if(temp->Valid)
    {
      if(project)
      {
        // this should manage project closing
        CanClose();
        // force to close all child form (if any)
        formlist.Destroy();
        ActiveChild.child = NULL;
        if(objInspector)
          {
            objInspector->ForceToClose = true;
            objInspector->Close();
            objInspector = NULL;
          }
        // removes all editor page
        VDKBMainForm* mainform = (VDKBMainForm*) Owner();
        VDKBEditor* editor = mainform->Editor();
        if( editor)
          {
            int t = 0;
            while( (t = editor->nbook->Pages.size()) > 0)
              editor->nbook->RemovePage(t-1);
            editor->textlist.flush();
          }
        // STUB cpane->Clean(); // clear old classes
      }
      delete project;
      project = temp;
      LoadTree();
      ((VDKBMainForm*) Owner())->Automa(automa_prjman_on);
      Changed = false;
      // change to project dir
      VDKString dir = project->Path;
      chdir((char*) dir);
      // make it if does not exists
      VDKBMainForm* mainform = (VDKBMainForm*) Owner();
      mainform->MakeEditor();
      // activate editor on project_name.cc
      char* cc_ext = (char*) VDKBuilder::ideDefaults.unit.cc_ext;
      VDKString mainsource = project->PathName;
      //char* p = get_extension((char*) mainsource);
      mainsource += ".";
      mainsource += cc_ext;
      ActivateEditor((char*) mainsource,true,true);
#if HAVE_GNOME
     // enable gnome widget toolbar pending on project typedef
     if(project->Type == vdk_gnome_project)
       mainform->EnableGnomeWidgets(true);
     else
       mainform->EnableGnomeWidgets(false);
#endif      
#if USE_XDB
     // clear previous database
     TheApp->theXdb->Clear();
     if(!LoadXdbOptions(TheApp->theXdb,(char*) project->PathName))     
       ; // warn user !!
#endif
     // update lru manager
     if(mainform->LruManager() && updatelru)
       {
       mainform->LruManager()->Update((char*) selections[0]);
       mainform->UpdateLRU();
       }
    }
  else
    delete temp;
  // STUB update class viewer for project
  // cpane->reset_pane();
  // if(VDKBuilder::ideDefaults.project.enable_class_browser == VDKString(CHECK_YES))
  //  cpane->LoadClassTree((char*) project->Path);
}
/*
 */
void
VDKBProjectManager::LoadTree()
{
  if(! project)
    return;
  // clears tree
  tree->Clear();
  tree->Freeze();
  // add project to tree
  VDKString name = project->Name;
  char* prj = (char*) name;
  // add root
  root = tree->AddNode(&prj,NULL,true,false,
                   prj_node_xpm,prj_node_xpm);
  // sets project as row data
  gtk_ctree_node_set_row_data(GTK_CTREE(tree->CustomWidget()), root,
                        (gpointer) project);

  // add units
  UnitListIterator li(project->Units());
  for(;li;li++)
      AddUnitNode(li.current());
  tree->Thaw();
  // select root node
  tree->SelectedNode = NULL;
  // enables
  (*toolbar)[ADD_UNIT_BUTTON]->Enabled = true;
  (*toolbar)[REMOVE_UNIT_BUTTON]->Enabled = false;

  (*toolbar)[ACTIVATE_EDITOR_BUTTON]->Enabled = false;
}
/*
 */
void
VDKBProjectManager::AddUnitNode(VDKBUnit* unit)
{
  char **xpm,*p;
  int type = unit->Type();
  switch(type)
    {
    case source_unit:
    case project_unit:
      xpm = unit_node_xpm;
      p = unit->ShortName();
      break;
    case c_source_unit:
      xpm = unit_node_xpm;
      sprintf(buff,"%s.c",unit->Name());
      p = buff;
      break;
    case object_unit:
    case staticlib_unit:
      xpm = gear_xpm;
      p = unit->ShortName();
      break;
    default:
      xpm = unit_node_xpm;
      p = unit->ShortName();
    }

  VDKTreeNode node = tree->AddNode(&p,root,
                           false,false,xpm,xpm);
  // sets unit as row data
  gtk_ctree_node_set_row_data(GTK_CTREE(tree->CustomWidget()), node,
                        (gpointer) unit);
  // if unit type == source_unit
  // add child source and header
  if(unit->Type() == source_unit
     ||  unit->Type() == project_unit
     )
    {
      char* source = unit->Source();
      // check for exist
      if(! access(source,F_OK))
      {
      VDKTreeNode n = tree->AddNode(&source,node,false,true,c_xpm,c_xpm);
      gtk_ctree_node_set_row_data(GTK_CTREE(tree->CustomWidget()), n,
                        (gpointer) NULL);
      }
      char* header = unit->Header();
      if(! access(header,F_OK))
      {
      VDKTreeNode n = tree->AddNode(&header,node,false,true,h_xpm,h_xpm);
      gtk_ctree_node_set_row_data(GTK_CTREE(tree->CustomWidget()), n,
                        (gpointer) NULL);
      }
      char* gui = unit->Gui();
      VDKTreeNode n = NULL;
      if(! access(gui,F_OK))
      {
      n = tree->AddNode(&gui,node,false,false,
                              mininewform_xpm,mininewform_xpm);
      if(n)
        gtk_ctree_node_set_row_data(GTK_CTREE(tree->CustomWidget()), n,
                        (gpointer) form_unit);
      //
      char* p = unit->GuiSource();
      if(n && p && ! access(p,F_OK))
         {
           VDKTreeNode n1 = tree->AddNode(&p,n,false,true,
                              c_xpm,c_xpm);
           if(n1)
             gtk_ctree_node_set_row_data(GTK_CTREE(tree->CustomWidget()), n1,
                               (gpointer) NULL);
         }
      //
       p = unit->DfmHeader();
       if( n && p && ! access(p,F_OK))
         {
           VDKTreeNode n2 = tree->AddNode(&p,n,false,true,
                              h_xpm,h_xpm);
           if(n2)
             gtk_ctree_node_set_row_data(GTK_CTREE(tree->CustomWidget()), n2,
                               (gpointer) NULL);
         }
      }
    }
}
/*
 */

void
VDKBProjectManager::RemoveUnit()
{
  VDKBUnit* unit;
  VDKTreeNode node = tree->SelectedNode;
  if(!node)
    return;
  else
    unit = (VDKBUnit*)  gtk_ctree_node_get_row_data(
       GTK_CTREE(tree->CustomWidget()), node);

  if(unit->Type() == project_unit)
    Application()->VDKMessageBox(APPNAME,
                        _(user_messages[user_cant_remove_unit]),
                        VDK_OK| VDK_ICONINFORMATION,
                        _(user_messages[user_cancel]));

  else if(project->Units().remove(unit))
    {
      tree->RemoveNode(node);
      delete unit;
      Changed = true;
    }
  return;
}

/*
 */
void VDKBProjectManager::AddUnit()
{
  FileStringArray selections;
  char* cc_ext   = (char*) VDKBuilder::ideDefaults.unit.cc_ext;
  VDKFileDialog *child = new VDKFileDialog(this,&selections,
                                 file_dialog_prompts[2]);
  sprintf(buff,"*.%s",cc_ext);
  child->Filter = buff;
  child->ShowModal();
  int t;
  if(selections.size() <= 0)
    return ;
  for(t=0; t < selections.size();t++)
    {
      char* selected = (char*) selections[t];
      VDKBUnit* unit = new VDKBUnit(selected,prj_unsaved);
      if(! Unique(unit))
      {
        // duplicate not allowed
        sprintf(buff,"%s\n%s",
              unit->Name(),
              _(user_messages[user_dup_unit])
              );
        Application()->VDKMessageBox(APPNAME,
                            buff,
                            VDK_OK| VDK_ICONINFORMATION,
                            _(user_messages[user_cancel]));

        delete unit;
      }
      else if(unit->Type() != unknow_type)
      {
        project->Units().add(unit);
        Changed = true;
        AddUnitNode(unit);
      }
      else
      {
        // unknown type can't be added
        sprintf(buff,"%s\n%s\n%s",
              unit->Name(),
              _(user_messages[user_unknown_unit]),
              _(user_messages[user_unknown_unit1])
              );
        Application()->VDKMessageBox(APPNAME,
                            buff,
                            VDK_OK| VDK_ICONINFORMATION,
                            _(user_messages[user_cancel])
                            );
        delete unit;
      }
    }
}


/*
  checks unique
 */
bool
VDKBProjectManager::Unique(VDKBUnit* unit)
{
UnitListIterator li(project->Units());
for(;li;li++)
   if (*unit == *(li.current()))
     return false;
return true;
}
/*
Save project
 */
#if USE_XDB
extern bool SaveXdbOptions(VDKXDatabase* db, char* filename);
#endif

bool
VDKBProjectManager::Save()
{
if(project)
  {
    if(project->Status == prj_never_saved)
      {
      char* prj_ext = (char*) VDKBuilder::ideDefaults.project.prj_ext;
      FileStringArray selections;
      VDKFileSaveAsDialog *child =
        new VDKFileSaveAsDialog(this,&selections,
                          _(file_dialog_prompts[3]));
      sprintf(buff,"*.%s",prj_ext);
      child->Filter = buff;
      child->ShowModal();
      if(selections.size() <= 0)
        return false;
      project->Save((char*) selections[0]);
#if USE_XDB
      SaveXdbOptions(TheApp->theXdb,(char*) selections[0]);
#endif
      Changed = false;
      // reload tree
      LoadTree();
      }
    else
      {
      // save editors
      VDKBMainForm* mainform = (VDKBMainForm*) Owner();
      VDKBEditor* editor =   mainform ? mainform->Editor() : NULL;
      if(editor && editor->Visible)
        editor->UpdateFiles();
      // save project
      project->Save();
#if USE_XDB
      SaveXdbOptions(TheApp->theXdb,(char*) project->PathName);
#endif
      // writes frm file (in vdkb_design.cc)
      WriteGuiFiles();
      Changed = false;
      // reload tree
      LoadTree();
      }
  }
 return true;
}

/*
Project manager can'te be closed
 */
bool
VDKBProjectManager::CanClose()
{
  if(project)
    {
      // save editors
      VDKBMainForm* mainform = (VDKBMainForm*) Owner();
      VDKBEditor* editor =   mainform ? mainform->Editor() : NULL;
      if(editor && editor->Visible)
      editor->UpdateFiles();
      // save project
      project->Save();
      // writes frm file (in vdkb_design.cc)
      WriteGuiFiles();
      Changed = false;
      // can be closed via mainform only.
      if(ForceToClose)
      {
        // save last session
        char* save = (char*) VDKBuilder::ideDefaults.project.save_session;
        if(!strcmp(save,CHECK_YES))
          SaveLastSession();
        // allows child list to be close
        // setting child ForceToClose = true
        formlist.Close();
        if(objInspector)
          objInspector->ForceToClose = true;
        return ForceToClose;
      }
    }
  return ForceToClose;
}

/////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////
typedef struct { VDKTreeNodeList* list; char* key; } SelectInfo;
/*
called by Select(char* key)->gtk_ctree_post_recursive(),
if node key matches with key
add that node to list
 */
static void
SelectOnTree(GtkCTree     *ctree,
            GtkCTreeNode *node,
            gpointer      i)
{
SelectInfo* info = (SelectInfo*) i;
char *text;
int res = gtk_ctree_get_node_info (ctree, node, &text,
                   NULL, NULL, NULL, NULL,NULL,NULL,NULL);
if(res && strstr(text,info->key))
   info->list->add(node);
}

/*
return a list of nodes that contain
<key>, user should delete list after use
 */
VDKTreeNodeList*
VDKBCustomTree::Select(char* key)
{

  VDKTreeNodeList* nodelist = new VDKTreeNodeList;
  SelectInfo info = { nodelist, key };
  gtk_ctree_post_recursive(GTK_CTREE(custom_widget),
                     NULL, SelectOnTree, (gpointer) &info);
  return nodelist;
}

Generated by  Doxygen 1.6.0   Back to index