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

vdkb_customtree.cc

/*
 * ===========================
 * VDK Builder
 * Version 0.1.1
 * Revision 0.0
 * March 1999
 * ===========================
 *
 * Copyright (C) 1998, Mario Motta
 * Developed by Mario Motta <mmotta@guest.net>
 *
 * 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-130
 */ 
#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_utils.h>
#include <vdkb2/vdkb_form.h>
#include <vdkb2/vdkb_parser.h>
#include <vdkb2/vdkb_objinspect.h>
#include <stdlib.h>
#include <vdkb2/vdkb_customtree.h>
#include <vdkb2/vdkb_clistdlg.h>
#include <vdkb2/vdkb_prjman.h>
#include <vdkb2/vdkb_fixed.h>
/*
================================
symbolic constants to templatize
a bit 
================================
*/
// for methods and other stuff
#define CLASS VDKBGuiCustomTree
// put here vdk class name string
#define VDK_CLASS "VDKCustomTree"
// put here vdk class name 
#define VDK_ANCESTOR  VDKCustomTree
// put here here the widget will be named
// (name+counter)
#define VDK_WIDGET "customtree"

static char buff[128];
extern char* wi_widget_prompts[];
// used to autogenerate default
// labelbutton  names and captions

int CLASS::Counter = 0;
/* 
 label properties names
 */
char* vdkctree_props[] =
{ 
VPOLICY,HPOLICY,
BORDERSHADOW,ROWHEIGHT,
AUTORESIZE,SELECTIONMODE,0
};
static char *shadows[] = 
{ 
"shadow_none","shadow_in","shadow_out","shadow_etched_in",
"shadow_etched_out",0 
};
char* vdkctree_signals[] =
{
SIGNAL_SELECT_NODE,SIGNAL_UNSELECT_NODE,
SIGNAL_CLICK_COLUMN,0
};
char* vdkctree_nicknames[] =
{
NICK_SELECT_NODE,NICK_UNSELECT_NODE,
NICK_CLICK_COLUMN,0
};
//////////////////////////////////////////////////
// dynamic tables
DEFINE_SIGNAL_LIST(CLASS,VDK_ANCESTOR);
DEFINE_EVENT_LIST(CLASS,VDK_ANCESTOR);
///////////////////////////////////////////////////
/*
 */
bool
CLASS::OnColumnClicked(VDKObject*)
{
  if(ColumnClicked() < 0)
    return true;
  else if(inspector)
    {
      inspector->SetActive(this);
      columnTitle->Text = column_titles[ColumnClicked()];
      columnTitle->Enabled = true;
    }
  return true;
}
/*
 */
int OnCtreeButtonEvent(GtkWidget *w, GdkEvent* event, void* o)
{
  g_return_val_if_fail(o != NULL, FALSE);
  g_return_val_if_fail(w != NULL, FALSE);
  CLASS* obj = reinterpret_cast<CLASS*>(o);
  obj->ButtonPressed(obj->ObjectFromVDK(), event);
  return FALSE;
}
//////////////////////////////////////////////////////////////
/*
  - constructor
 */
// default pixmap
// defined in vdkb_local.cc 
extern char** default_pixmap;

CLASS::CLASS(char* name, VDKForm* owner,
                         int cols, 
                         char** titles,
                         GtkSelectionMode mode,
                         int tree_column):
  VDK_ANCESTOR(owner,cols,titles,mode,tree_column),VDKBObject(name)
{
  int t;
  // newly constructed widget counter is incremented
  // each time 
  Counter++;
  // assign this to VDKBObject <object> member.
  object = this;
  // add to VDKBObject properties 
  for(t=0; vdkctree_props[t]; t++)
    proplist.add(VDKBProperty(vdkctree_props[t]));
    // add to VDKBObject signal list  signals
  for(t=0; vdkctree_signals[t]; t++)
    siglist.add(VDKBSignal(vdkctree_signals[t],
                     this,
                     vdkctree_nicknames[t]));
  // make and load colums title array
  column_titles = TitlesArray(cols);
  for(t = 0 ; t < cols; t++)
    column_titles[t] = VDKString(titles[t]);
  // connects events.
  CONNECT_COMMON_EVENTS;
  gtk_widget_add_events(CustomWidget(),GDK_POINTER_MOTION_MASK);
  EventConnect("motion_notify_event",&VDKBObject::OnMouseMove);
  SignalConnect("click_column",&CLASS::OnColumnClicked,false);
  gtk_signal_connect(GTK_OBJECT(CustomWidget()),"button_press_event",
               GTK_SIGNAL_FUNC(::OnCtreeButtonEvent),
               reinterpret_cast<gpointer>(this));
  // makes a pop menu common to all widgets (in vdkb_widpopmenu.cc/h)
  // this pop menu will be popped at righ button press event.
  popmenu = new VDKBWidgetPopMenu(this);
  // FIX ME: to be rewied on all widgets !
  SetSize(100,100);
  SetPropValue(USIZE,"100,100");
  SignalConnect("click_column",&CLASS::OnColumnClicked,false);
  inspector = NULL;
}

////////////////////////////////////////////////////////////////
//
//               WRITER TO .FRM FILE
//
///////////////////////////////////////////////////////////////
/*
Writes a .frm format representation of label button widget
This virtual function is called by VDKBForm::WriteBoxesOnFrm()
a recursive algorithm that scans VDKBForm widget tree.
*/
void
CLASS::WriteOnFrm(FILE* fp, VDKBObject* parentobj)
{
  // first of all call ancestor to write common properties
    VDKBObject::WriteOnFrm(fp,parentobj);
    
    fprintf(fp,"\n\t%s%s;", 
          PROP_SELECTIONMODE,
          (char*) GetProp(SELECTIONMODE));
    fprintf(fp,"\n\t%s%s;", 
          PROP_AUTORESIZE,
          (char*) GetProp(AUTORESIZE));
    fprintf(fp,"\n\t%s%s;",
          PROP_BORDERSHADOW,
          (char*) GetProp(BORDERSHADOW));
    // writes columns titles:
    fprintf(fp,"\n\t%s%d;",PROP_COLUMNS_INTERNAL,column_titles.size());
    fprintf(fp,"\n\t%s\"",PROP_TITLES_INTERNAL);
    int t,last = column_titles.size();
    for(t = 0; t < last-1 ; t++)
      fprintf(fp,"%s,", (char*) column_titles[t].isNull() ? 
            NIHIL_PROP : (char*) column_titles[t]);
    fprintf(fp,"%s\";", (char*) column_titles[last-1].isNull() ? 
          NIHIL_PROP : (char*) column_titles[last-1]);
}
//////////////////////////////////////////////////////////////////
//
//               PREPARE GUI WIDGETS
//
//////////////////////////////////////////////////////////////////
/*
This method is called by global MakeWidget() in vdkb_design.cc
MakeWidget() scans a table that maps class id's with each
static MakeWidget() for each class. Class id's are generated
during clicks on widget palette.
On return:
0 - successfull
1 - unsupported widget
2 - target is not a container
 */
static void
AddSomeNodes(CLASS* ctree, int columns)
{
  int t,z;
  // add some nodes...just to see the tree
  VDKTreeNode node = NULL;
  for(z = 0; z < 9; z++)
    {
      char** cells = new char*[columns];
      for(t=0;t<columns;t++)
      {
        cells[t] = new char[32];
        sprintf(cells[t],"Sample %d.%d",z,t);
      }
      node = ctree->AddNode(cells, !(z%3) ? NULL : node,
                      true,
                      (z%3) < 2 ? false : true);
      // free them
      for(t=0; t < columns; t++)
      delete[] cells[t];
      delete[] cells;
    }
}
/*
 */
int
CLASS::MakeWidget(VDKBGuiForm* owner, GdkEvent* ev)
{
  CLASS* ctree;
  int columns = 0,t;
  // be sure target is a container (otherwise hangs -up )
  if(!dynamic_cast<VDKBEventContainer*>(owner->Active))
      return 2;
// autogenerate first suitable pixmap counter
  // to ensure unicity
  if(!owner->GenerateWidgetName(buff,VDK_WIDGET,&CLASS::Counter))
    // unauthorized operation
    return 2;
  // columns should be asked to user
  Vdkb_clistdlgForm* dlg = new Vdkb_clistdlgForm(owner,NULL,&columns);
  dlg->Setup();
  dlg->ShowModal();
  columns = columns ? columns : 1;
  // autogenerates titles
  char **titles = new char*[columns];
  for(t=0; t < columns;t++)
    {
      titles[t] = new char[32];
      sprintf(titles[t],"Title#%d",t);
    }
  ctree = new CLASS(buff, owner, columns, titles);
  // deletes titles
  for(t=0; t < columns; t++)
    delete[] titles[t];
  delete[] titles;
  return owner->AddToSelf(ctree,ev);
}
/*
This is called by a global CreateSource() in vdkb_parser.cc.
CreateSource() scans a table that maps class names with
each static CreateSource() in widget class.
 */
static void
CreateTitles(char* source,char* obj_name,int obj_cols, 
           char* obj_titles, bool nls_support)
{
  char* p;
  char tmp[128];
  int t = 0;
  sprintf(tmp,"\nchar* %sTitles[] = { ",obj_name);
  strcpy(source,tmp);
  p = strtok(obj_titles,",");
  while(p)
    {
      if(nls_support)
      sprintf(tmp,"\n_(\"%s\"),",strcmp(p,NIHIL_PROP) ? p : " ");
      else
      sprintf(tmp,"\n\"%s\",",strcmp(p,NIHIL_PROP) ? p : " ");
      t++;
      p = strtok(NULL,",");
      if(!p)
      // cut comma
      tmp[strlen(tmp)-1] = '\0';
      strcat(source,tmp);
    }
  sprintf(tmp," };");
  strcat(source,tmp);
 if( t!= obj_cols)
   ; // FIX ME: error to be noticed to user
 return;
}
char*
CLASS::CreateSource(char* buffer,VDKBParser& parser)
{
  char* source;
  char obj_name[128];
  char obj_parent[128];
  char arg[64];
  char tmp[256];
  char obj_titles[1024];
  char obj_cols[32];
  char selmode[16];
  int  smode =  0;
  // gets widget name, parent name, columns and titles
  if(
     (!parser.GetNameAndParent(buffer, obj_name, obj_parent)) ||
     (!parser.GetParam(obj_cols,buffer,PROP_COLUMNS_INTERNAL)) ||
     (!parser.GetParam(obj_titles,buffer,PROP_TITLES_INTERNAL)) 
     )
    return NULL;
  source = new char[4096];
  if(parser.GetParam(selmode,buffer,PROP_SELECTIONMODE) &&
     strcmp(arg,NIHIL_PROP))
    {
      smode = atoi(selmode);
    }
  // create code for titles
  bool nls_support = parser.CheckNLSSupport();
  CreateTitles(source,obj_name,atoi(obj_cols),obj_titles,nls_support);
  sprintf(tmp,
        "\n%s = new %s(this,%s,%sTitles,(GtkSelectionMode) %d);",
        obj_name,VDK_CLASS,obj_cols,obj_name,smode);
  strcat(source,tmp);
  ///////////////////////////////////////
  // call ancestor to set common properties
  char* props = VDKBObject::CreateSource(buffer,parser,obj_name);
  if(props)
    {
      strcat(source,props);
      delete[] props;
    }
  /*
    this code is widget specific
  */
  if(parser.GetParam(arg,buffer, PROP_AUTORESIZE) && 
     strcmp(arg,NIHIL_PROP))
   {
     sprintf(tmp,"\n%s->%s = %s;",obj_name,AUTORESIZE,arg);
     strcat(source,tmp);
   }
  // get shadow
  if(parser.GetParam(arg,buffer,PROP_BORDERSHADOW ) && 
     strcmp(arg,NIHIL_PROP))
    {
      int ndx = atoi(arg);
      ndx = (ndx >= 0) && (ndx <= 4) ? ndx : 0;
      sprintf(tmp,"\n%s->%s = (GtkShadowType) %s;", 
            obj_name,BORDERSHADOW,shadows[ndx]);
      strcat(source,tmp);
    }
  // get code that adds widget to container
  parser.WriteCodeToPack(obj_parent,obj_name,source,buffer,tmp);
  /*
    visible property must be wrote after adding it to a parent
    container. That's the reason why is written here and not
    in vdkb_object class as should be. Written only if == false
  */
  parser.WriteVisible( obj_name, arg, source,buffer,  tmp);
  return source;
}
/*
Invoked by VDKBGuiForm::MakeGuiObjects() during gui creation
reading .frm file.
MakeGuiObjects() scans .frm file and call a global CreateWidget()
that scans a table that maps class names with
each static CreateWidget() in widget class.
*/
static char **
GenerateTitles(int obj_cols, char* obj_titles)
{
  char* p, **titles;
  int t = 0;
  // generates titles
  if(obj_cols <= 0)
    return (char**) NULL;
  titles = new char*[obj_cols];
  p = strtok(obj_titles,",");
  while(p)
    {
      titles[t] = new char[strlen(p)+1];
      if(strcmp(p,NIHIL_PROP))
      strcpy(titles[t],p);
      else
      strcpy(titles[t]," ");
      t++;
      p = strtok(NULL,",");
    }
  return t == obj_cols ? titles : (char**) NULL;
}
/*
 */
bool
CLASS::CreateWidget(VDKBGuiForm* owner, 
                        char* buffer,VDKBParser& parser)
{
  VDKString True = CHECK_TRUE;
  char obj_name[128];
  char obj_parent[128];
  char arg[64];
  char obj_titles[1024];
  char obj_cols[32];
  char selmode[16];
  int  smode =  0;
  //char arg[64];
  CLASS* ctree;
  // get name, and parent
  if(
     (!parser.GetNameAndParent(buffer, obj_name, obj_parent)) ||
     (!parser.GetParam(obj_cols,buffer,PROP_COLUMNS_INTERNAL)) ||
     (!parser.GetParam(obj_titles,buffer,PROP_TITLES_INTERNAL)) 
     )
    return false;

  if(parser.GetParam(selmode,buffer,"SelectionMode:") &&
     strcmp(arg,NIHIL_PROP))
    smode = atoi(selmode);

  VDKObject* p = owner->ChildWithName(obj_parent);
  VDKBEventContainer* container = p ? 
    dynamic_cast<VDKBEventContainer*>(p) : (VDKBEventContainer*) NULL;
  if(container)
    {
      char** tit = GenerateTitles(atoi(obj_cols),obj_titles);
      ctree = new CLASS(obj_name,owner,
                         atoi(obj_cols),
                         tit, (GtkSelectionMode) smode);
      if(tit)
      {
        int t = 0;
        int z = atoi(obj_cols);
        for( ; t < z; t++)
          delete[] tit[t];
        delete[] tit;
      }

      if(parser.GetParam(selmode,buffer, PROP_SELECTIONMODE) &&
       strcmp(arg,NIHIL_PROP))
      ctree->SetPropValue(SELECTIONMODE,selmode);
      // shadow
      if(parser.GetParam(arg,buffer,PROP_AUTORESIZE) &&
       strcmp(arg,NIHIL_PROP))
      {
        ctree->SetPropValue(AUTORESIZE,arg);
        ctree->AutoResize = !strcmp(arg,CHECK_TRUE);
      }
      if(parser.GetParam(arg,buffer,PROP_BORDERSHADOW) &&
       strcmp(arg,NIHIL_PROP))
      {
        ctree->SetPropValue(BORDERSHADOW,arg);
        int sh = atoi(arg);
        ctree->BorderShadow = (GtkShadowType) sh;
      }
      bool result =  owner->PackToSelf(ctree, container, buffer, parser);
      if(! dynamic_cast<VDKBFixed*>(container))
      AddSomeNodes(ctree,atoi(obj_cols));
      return result;
    }
  else
    return false;
}
/////////////////////////////////////////////////////
//           OBJECT INSPECTOR MANAGEMENT
////////////////////////////////////////////////////
/*
GTK_SELECTION_SINGLE,  GTK_SELECTION_BROWSE,  GTK_SELECTION_MULTIPLE,
  GTK_SELECTION_EXTENDED
*/
static
char *selectionmodes[] = { "single","browse","multiple","extended",0 };
/*
 */
VDKObjectContainer* 
CLASS::ExtraWidget(VDKBObjectInspector* isp) 
{ 
  VDKString True = CHECK_TRUE;
  inspector = isp;
  VDKFrame* bframe = new VDKFrame(inspector,NULL,v_box,shadow_etched_in);
  VDKTable *table = new VDKTable(inspector,4,2);
  table->SetSize(219,-1);

  VDKCustomButton *setmode = new VDKCustomButton(inspector,
                                     _(wi_widget_prompts[10]));
  table->AddToCell(setmode,0,0);
  setmode->Parent(this);
  SignalConnect(setmode,"clicked",&CLASS::OnSetSelectionMode);

  selmode = new VDKCombo(inspector,NULL);
  selmode->SetSize(100,-1);
  StringList sm;
  int t = 0;
  for(;selectionmodes[t];t++)
    sm.add(VDKString(selectionmodes[t]));
  selmode->PopdownStrings = sm;
  table->AddToCell(selmode,0,1);
  int r = atoi(GetProp("SelectionMode"));
  selmode->SelectItem(r);
 

  table->AddToCell(new VDKLabel(inspector,_(wi_widget_prompts[11])),1,0);
  columnTitle = new VDKEntry(inspector,64);
  columnTitle->SetSize(100,-1);
  table->AddToCell(columnTitle,1,1);
  columnTitle->Parent(this);
  SignalConnect(columnTitle,"activate",&CLASS::OnSetColumnTitle);
  columnTitle->Enabled = false;


  autoresize = new VDKCheckButton(inspector,_(wi_widget_prompts[12]));
  table->AddToCell(autoresize,2,1);
  autoresize->Checked = GetProp("AutoResize") == True;
  autoresize->Parent(this);
  SignalConnect(autoresize,"toggled",&CLASS::OnSetAutoResize);


  VDKCustomButton *set = new VDKCustomButton(inspector,_(wi_widget_prompts[13]));
  table->AddToCell(set,3,0);
  set->Parent(this);
  SignalConnect(set,"clicked",&CLASS::OnSetShadow);
  shadow = new VDKCombo(inspector,NULL);
  shadow->SetSize(100,-1);
  StringList sl;
  t = 0;
  for(;shadows[t];t++)
    sl.add(VDKString(shadows[t]));
  shadow->PopdownStrings = sl;
  table->AddToCell(shadow,3,1);
  r = atoi(GetProp(BORDERSHADOW));
  shadow->SelectItem(r);

  bframe->Add(table,l_justify,false,false,false);
  return bframe;
}
//////////////////////////////////////////////////////
// These response methods actually change both 
// properties on widget and gui widget properties
//////////////////////////////////////////////////////
/*
 */
bool
CLASS::OnSetColumnTitle(VDKObject*)
{
  if(ColumnClicked() < 0)
    return true;
  else if(strlen(columnTitle->Text) <= 0)
    sprintf(buff,NIHIL_PROP);
  else
    sprintf(buff,"%s",(char*) columnTitle->Text);
  gtk_clist_set_column_title (GTK_CLIST(CustomWidget()),
                        ColumnClicked(),
                        strcmp(buff,NIHIL_PROP) ? buff : " ");
  column_titles[ColumnClicked()] = buff;
  inspector->FormNeedToBeChanged();
  return true;
}
/*
 */
bool
CLASS::OnSetAutoResize(VDKObject*)
{
  SetPropValue(AUTORESIZE, autoresize->Checked ? CHECK_TRUE : CHECK_FALSE);
  AutoResize = autoresize->Checked ? true : false;
  inspector->FormNeedToBeChanged();
  return true;
}
/*
 */
bool
CLASS::OnSetShadow(VDKObject*)
{
  int sel = shadow->Selected;
  sprintf(buff,"%d", sel >= 0 ? sel : 0);
  SetPropValue(BORDERSHADOW,buff);
  int shd = atoi(buff);
  BorderShadow = (GtkShadowType) shd;
  inspector->FormNeedToBeChanged();
  return true;
}
bool
CLASS::OnSetSelectionMode(VDKObject*)
{
  int sel = selmode->Selected;
  sprintf(buff,"%d", sel >= 0 ? sel : 0);
  SetPropValue(SELECTIONMODE,buff);
  gtk_clist_set_selection_mode ( GTK_CLIST(CustomWidget()),
                        (GtkSelectionMode)  sel);
  inspector->FormNeedToBeChanged();
  return true;
}





Generated by  Doxygen 1.6.0   Back to index