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

vdkb_xentry.cc

/*
 * ===========================
 * VDK Builder
 * Version 1.2
 * Revision 0.1
 * May 2000
 * ===========================
 *
 * 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 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 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 USE_XDB

#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.h>
#include <vdkb2/vdkb_xentry.h>
#include <vdkb2/vdkb_evbox.h>
#include <vdkb2/vdkb_utils.h>
#include <vdkb2/vdkb_form.h>
#include <vdkb2/vdkb_parser.h>
#include <vdkb2/vdkb_objinspect.h>
#include <vdkb2/vdkb_prjman.h>
#include <stdlib.h>
#include <vdkb2/vdkb_fixed.h>
#include <ctype.h>
/*
================================
symbolic constants to templatize
a bit
================================
*/


// for methods and other stuff
#define CLASS VDKBXEntry
// put here vdk class name string
#define VDK_CLASS "VDKXEntry"
// put here vdk class name
#define VDK_ANCESTOR  VDKXEntry
// put here here the widget will be named
// (name+counter)
#define VDK_WIDGET "xentry"

static char buff[128];
extern char* wi_widget_prompts[];
extern VDKBuilder* TheApp;
void LoadTableList(VDKCustomList* tlist,
               VDKXDatabase* xdb, char* tablename);
void LoadFieldList(VDKCustomList *fieldlist,
               char* tablename, VDKXDatabase* xdb,
               char* fieldname);
// used to autogenerate default
// labelbutton  names and captions

int CLASS::Counter = 0;
/*
 properties names
 */
char* vdkxentry_props[] =
{
TEXT,EDITABLE,HIDDEN,MAXCHARS,ASSIGNTABLE,ASSIGNFIELD,0
};
/*
entry widget signal names && nicknames
Default response method name will be made by:
On<object name><nickname>.
For instance if object name = <Abutton> and nickname = <Click>
default response method name will be: <OnAbuttonClick>
*/
char* vdkxentry_signals[] =
{
SIGNAL_ACTIVATE,SIGNAL_CHANGED,
SIGNAL_FOCUS_IN,SIGNAL_FOCUS_OUT,0
};
char* vdkxentry_nicknames[] =
{
NICK_ACTIVATE,NICK_CHANGED ,
NICK_FOCUS_IN,NICK_FOCUS_OUT,0
};
//////////////////////////////////////////////////
// dynamic tables
DEFINE_SIGNAL_LIST(CLASS,VDK_ANCESTOR);
DEFINE_EVENT_LIST(CLASS,VDK_ANCESTOR);
//////////////////////////////////////////////////
/*
overridden ButtonPressed
used in substitution of
VDKBObject::ButtonPress
*/
bool
VDKBXEntry::OverriddenButtonPressed(VDKObject* sender, GdkEvent* ev)
{
  VDKBEventContainer* container;
  gtk_signal_emit_stop_by_name(GTK_OBJECT(sender->WrappedWidget()),
                   "button_press_event");
  container = dynamic_cast<VDKBEventContainer*>(sender->Parent());
  if(container)
    // we pass <this> instead <sender>
    // otherwise entry widget selection
    // is lost (don'y ask me why !)
    container->OnButtonPressed(this,ev);
  return true;
}

//////////////////////////////////////////////////////////////
/*
  - constructor
 */
CLASS::CLASS(char* name, VDKForm* owner, char* def):
  VDK_ANCESTOR(owner, 0, def),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 list label button properties
  // names. (Others props are prepended  by VDKBObject constructor)
  for(t=0; vdkxentry_props[t]; t++)
    proplist.add(VDKBProperty(vdkxentry_props[t]));
  // add to VDKBObject signal list  signals
  for(t=0; vdkxentry_signals[t]; t++)
    siglist.add(VDKBSignal(vdkxentry_signals[t],
                     this,
                     vdkxentry_nicknames[t]));
  //SetPropValue(TEXT,name);
  SetPropValue(MAXCHARS,"0");
  SetPropValue(EDITABLE,"true");
  // connects events.
  // an exception here
  EventConnect("button_press_event",&VDKBXEntry::OverriddenButtonPressed);
  // others kept from ancestor
  EventConnect("button_release_event",&VDKBObject::ButtonReleased);
  EventConnect("enter_notify_event",&VDKBObject::OnEnter);
  EventConnect("leave_notify_event",&VDKBObject::OnLeave);
  // 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);
}
////////////////////////////////////////////////////////////////
//
//               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)
{
    char* text = (char*) GetProp(TEXT);
  // first of all call ancestor to write common properties
  VDKBObject::WriteOnFrm(fp,parentobj);
  fprintf(fp,"\n\t%s%s;",
        PROP_EDITABLE,
        (char*) GetProp(EDITABLE));
  fprintf(fp,"\n\t%s%s;",
        PROP_HIDDEN,
        (char*) GetProp(HIDDEN));
  if(strcmp(text,NIHIL_PROP))
      fprintf(fp,"\n\t%s\"%s\";", PROP_TEXT, text);
  else
      fprintf(fp,"\n\t%s%s;", PROP_TEXT, text); 
  fprintf(fp,"\n\t%s%s;",
        PROP_MAXCHARS,
        (char*) GetProp(MAXCHARS));
  fprintf(fp,"\n\t%s%s;",
        PROP_ASSIGNTABLE,
        (char*) GetProp(ASSIGNTABLE));
  fprintf(fp,"\n\t%s%s;",
        PROP_ASSIGNFIELD,
        (char*) GetProp(ASSIGNFIELD));

}
//////////////////////////////////////////////////////////////////
//
//               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
 */
int
CLASS::MakeWidget(VDKBGuiForm* owner, GdkEvent* ev)
{
  CLASS* text;
  // widget name generation failed
  if(!owner->GenerateWidgetName(buff,VDK_WIDGET,&CLASS::Counter))
    // unauthorized operation
    return 2;
  else
    // actually makes widget
    text = new CLASS(buff,owner);
  // add widget to form
  return owner->AddToSelf(text,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.
 */
extern VDKBuilder* TheApp;
char*
CLASS::CreateSource(char* buffer,VDKBParser& parser)
{
  char* source;
  char obj_name[128];
  char obj_parent[128];
  char obj_editable[16];
  char obj_text[256];
  char obj_maxchars[16];
  char arg[64];
  char tmp[256];
  char assigntable[256],assignfield[256];
  *assigntable = '\0';
  *assignfield = '\0';
// gets widget name and parent name
  if(! parser.GetNameAndParent(buffer, obj_name, obj_parent))
     return NULL;
  source = new char[4096];
  // widget specifics
  if(parser.GetParam(obj_maxchars,buffer,PROP_MAXCHARS) &&
     strcmp(obj_maxchars,NIHIL_PROP))
    ;
  else
    strcpy(obj_maxchars,"0");
    //
  if(parser.GetParam(obj_text,buffer,PROP_TEXT) &&
     strcmp(obj_text,NIHIL_PROP))
    ;
  else
    *obj_text = '\0';

  parser.CheckXDBSupport(0); // checks for contructing

  if(*obj_text)
    sprintf(tmp,"\n%s = new %s(this,%s,\"%s\");",
          obj_name,
          VDK_CLASS,
          obj_maxchars,
          obj_text);
  else
    sprintf(tmp,"\n%s = new %s(this,%s);",
          obj_name,
          VDK_CLASS,
          obj_maxchars);
  strcpy(source,tmp);
  // call ancestor to set common properties
  char* props = VDKBObject::CreateSource(buffer,parser,obj_name);
  if(props)
    {
      strcat(source,props);
      delete[] props;
    }
  //
  if(parser.GetParam(obj_editable,buffer,PROP_EDITABLE) &&
     strcmp(obj_editable,NIHIL_PROP))
    {
      sprintf(tmp,"\n%s->%s = %s;",
            obj_name,EDITABLE,obj_editable);
      strcat(source,tmp);
    }

  // get props
  if(parser.GetParam(arg,buffer,PROP_HIDDEN) &&
     strcmp(arg,NIHIL_PROP))
   {
     sprintf(tmp,"\n%s->%s = %s;",obj_name,HIDDEN,arg);
     strcat(source,tmp);
   }
  // get code that adds widget to container
  parser.WriteCodeToPack(obj_parent,obj_name,source,buffer,tmp);

  // get table and field to assign
  if(parser.GetParam(assigntable,buffer,PROP_ASSIGNTABLE) &&
     strcmp(assigntable,NIHIL_PROP) &&
     parser.GetParam(assignfield,buffer,PROP_ASSIGNFIELD) &&
     strcmp(assignfield,NIHIL_PROP))
    parser.WriteXDBAssignCode(obj_name, assigntable, assignfield,
                      source, 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.
*/
bool
CLASS::CreateWidget(VDKBGuiForm* owner,
                        char* buffer,VDKBParser& parser)
{
  char obj_name[128];
  char obj_parent[128];
  char arg[256];
  char obj_text[256];
  char assigntable[256],assignfield[256];
  *assigntable = '\0';
  *assignfield = '\0';
  CLASS* text;
  // get widget name and parent
  if(! parser.GetNameAndParent(buffer, obj_name, obj_parent))
     return false;
  if(parser.GetParam(obj_text,buffer,PROP_TEXT) &&
     strcmp(obj_text,NIHIL_PROP))
      ;
  else
      *obj_text = '\0';
  VDKObject* p = owner->ChildWithName(obj_parent);
  VDKBEventContainer* container = p ?
    dynamic_cast<VDKBEventContainer*>(p) : (VDKBEventContainer*) NULL;
  if(container)
    {
      text = new CLASS(obj_name,owner, *obj_text ? obj_text : NULL);
      if(parser.GetParam(arg,buffer,PROP_EDITABLE) && strcmp(arg,NIHIL_PROP))
      text->SetPropValue(EDITABLE,arg);
      if(parser.GetParam(arg,buffer,PROP_HIDDEN) && strcmp(arg,NIHIL_PROP))
      text->SetPropValue(HIDDEN,arg);
      if(parser.GetParam(arg,buffer,PROP_MAXCHARS) && strcmp(arg,NIHIL_PROP))
      text->SetPropValue(MAXCHARS,arg);
      if(parser.GetParam(arg,buffer,PROP_TEXT) && strcmp(arg,NIHIL_PROP))
      text->SetPropValue(TEXT,arg);
      if(parser.GetParam(assigntable,buffer,PROP_ASSIGNTABLE) &&
       strcmp(assigntable,NIHIL_PROP) &&
       parser.GetParam(assignfield,buffer,PROP_ASSIGNFIELD) &&
       strcmp(assignfield,NIHIL_PROP))
      {
        VDKXTable *table = NULL;
        text->SetPropValue(ASSIGNTABLE,assigntable);
        text->SetPropValue(ASSIGNFIELD,assignfield);
        // search for table on xdb
        TableList *tlist = TheApp->theXdb->TList();
        TableListIterator li(*tlist);
        for(;li;li++)
          {
            char* dbname = (char*) li.current()->Name();
            if(!strcmp(assigntable,get_shortfilename(dbname)))
            {
              table = li.current();
              break;
            }
          }
        if(table && text->AssignTableField(table,assignfield) &&
           table->Active && (table->First() == XB_NO_ERROR))
            text->Read();
      }
      // pack widget to container
      return owner->PackToSelf(text, container, buffer, parser);
    }
  else
    return false;
return true;
}
/////////////////////////////////////////////////////
//           OBJECT INSPECTOR MANAGEMENT
////////////////////////////////////////////////////
/*
 */
/*
 */


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,3,2);
  // table->SetSize(300,-1);

  hidden = new VDKCheckButton(inspector,_(wi_widget_prompts[16]));
  table->AddToCell(hidden,0,0);
  hidden->Checked = GetProp(HIDDEN) == True;
  // this after (so no signal hang)
  hidden->Parent(this);
  SignalConnect(hidden,"toggled",&CLASS::OnSetHidden);

  editable = new VDKCheckButton(inspector,_(wi_widget_prompts[2]));
  table->AddToCell(editable,0,1);
  editable->Checked = GetProp(EDITABLE) == True;
  // this after (so no signal hang)
  editable->Parent(this);
  SignalConnect(editable,"toggled",&CLASS::OnSetEditable);


  char* ttitle[2]  = { N_("Tables"), 0 };
  tablelist = new VDKCustomList(inspector,1,ttitle,GTK_SELECTION_SINGLE);
  // tablelist->SetSize(150,80);
  table->AddToCell(tablelist,1,0);
  tablelist->Parent(this);
  SignalConnect(tablelist,"select_row",&CLASS::OnTableListSelectRow,false);
  SignalConnect(tablelist,"unselect_row",&CLASS::OnTableListUnselectRow,false);
  char* ftitle[2] = { N_("Fields"), 0 };
  fieldlist = new VDKCustomList(inspector,1,ftitle,GTK_SELECTION_SINGLE);
  // fieldlist->SetSize(105,80);
  table->AddToCell(fieldlist,1,1);
  fieldlist->Parent(this);

  assignButton = new VDKCustomButton(inspector,_("Assign to table field"));
  table->AddToCell(assignButton,2,0);
  assignButton->Parent(this);
  assignButton->Enabled = false;
  assignButton->SetTip(_("Selecting \"nihil\" will reset field assignement"));
  SignalConnect(assignButton,"clicked",&CLASS::OnAssignButtonClicked);
  bframe->Add(table,l_justify,false,false,false);
  ::LoadTableList(tablelist,TheApp->theXdb,GetProp(ASSIGNTABLE));
  return bframe;
}

/*
  These global functions are used by all xdb vdkbobjects wrappers
 */
void 
LoadTableList(VDKCustomList* tablelist,VDKXDatabase* xdb, char* tablename)
{
  int t = 0, ndx = 0;
  TableList* tlist = xdb->TList();
  if(!tlist || (!tlist->size()) )
    return;
  TableListIterator li(*tlist);
  for(;li;li++,t++)
    {
      VDKXTable* table = li.current();
      char* dbName = table->Name();
      if(!strcmp(tablename,get_shortfilename(dbName)))
       ndx = t;
      tablelist->AddRow(&dbName);
    }
  tablelist->SelectRow(ndx,0);
  // should scroll into right position
  // but doesn't work well
  GtkCList* clist = GTK_CLIST(tablelist->CustomWidget());
  if(!gtk_clist_row_is_visible (clist,ndx))
    gtk_clist_moveto (clist,ndx,0,0.5,0.5);


}
void 
LoadFieldList(VDKCustomList *fieldlist,
            char* tablename, VDKXDatabase* xdb,
            char* fieldname)
{
  int t = 0, ndx = 0;
  char name[11];
  char* columns[1];
  VDKXTable* table = NULL;
  fieldlist->Clear();
  table = tablename ? (*xdb)[tablename] : NULL;
  if(!table)
    return ;
  columns[0] = NIHIL_PROP;
  fieldlist->AddRow(columns);
  int fn = table->FieldCount();
  for(t = 0; t < fn; t++)
    {
      sprintf(name,"%s",table->GetFieldName(t));
      if(!strcmp(name,fieldname))
       ndx = t+1;
      columns[0] = name;
      fieldlist->AddRow(columns);
    }
  fieldlist->SelectRow(ndx,0);
  // should scroll into right position
  // but doesn't work well
  GtkCList* clist = GTK_CLIST(fieldlist->CustomWidget());
  if(!gtk_clist_row_is_visible (clist,ndx))
    gtk_clist_moveto (clist,ndx,0,0.5,0.5);
  return ;
}
//////////////////////////////////////////////////////
// These response methods actually change both
// properties on widget and gui widget properties
//////////////////////////////////////////////////////
/*
 */
bool 
CLASS::OnTableListSelectRow(VDKObject*)
{
  int ndx = tablelist->Selected.Row();
  if(ndx < 0)
    {
      assignButton->Enabled = false;
      return true;
    }
  else
    {
      Tuple tuple = tablelist->Tuples[ndx];
      LoadFieldList(fieldlist,(char*) tuple[0],TheApp->theXdb,
                GetProp(ASSIGNFIELD));
      assignButton->Enabled = true;      
    }
  return true;
}
/*
 */
bool 
CLASS::OnTableListUnselectRow(VDKObject*)
{
  fieldlist->Clear();
  assignButton->Enabled = false;
  return true;
}
/*
 */
bool
CLASS::OnAssignButtonClicked(VDKObject*)
{
  VDKXTable* table = NULL;
  VDKXDatabase *xdb = TheApp->theXdb;
  int tndx = tablelist->Selected.Row();
  int fndx = fieldlist->Selected.Row();
  char* tname = NULL;
  char* fname = NULL;
  if( (tndx < 0) || (fndx < 0))
    return true;
  Tuple ttuple = tablelist->Tuples[tndx];
  Tuple ftuple = fieldlist->Tuples[fndx];
  tname = (char*) ttuple[0];
  fname = (char*) ftuple[0];
  // clears field
  Text = "";
  // reset the field
  if(!strcmp(fname,NIHIL_PROP))
    {
      SetPropValue(ASSIGNTABLE,NIHIL_PROP);
      SetPropValue(ASSIGNFIELD,NIHIL_PROP);
      return true;
    }
  table = (*xdb)[tname];
  if(!table)
    return true;
  if(AssignTableField(table,fname))
    {
      xbShort fno;
      if(table->Active && (table->First() == XB_NO_ERROR))
          Read();
      SetPropValue(ASSIGNTABLE,get_shortfilename(tname));
      SetPropValue(ASSIGNFIELD,fname);
      fno = table->GetFieldNo(fname);
      if(fno >= 0)
      {
        xbShort flen = table->GetFieldLen(fno);
        xbShort type = table->GetFieldType(fno);
        // two more bytes to dates for
        // mm-dd-yyyy format
        if(type == 'D')
          flen += 2;
        sprintf(buff,"%d",flen);
        SetPropValue(MAXCHARS,buff);        
      }
      inspector->FormNeedToBeChanged();
    }
  else
    {
      sprintf(buff,_("Couldn't assign to field \"%s\" on table %s"),
            fname,tname);
      Owner()->Application()->VDKMessageBox(
       APPNAME,
       buff,
       VDK_ICONINFORMATION|VDK_OK,
       _(user_messages[user_ok]),
       NULL,
       5000); // warns user
    }
  return true;
} 
/*
 */
bool
CLASS::OnSetHidden(VDKObject*)
{
  SetPropValue(HIDDEN, hidden->Checked ? CHECK_TRUE : CHECK_FALSE);
  Hidden = hidden->Checked ? true : false;
  inspector->FormNeedToBeChanged();
  return true;
}
/*
 */
bool
CLASS::OnSetEditable(VDKObject*)
{
  SetPropValue(EDITABLE, editable->Checked ? CHECK_TRUE : CHECK_FALSE);
  Editable = editable->Checked ? true : false;
  inspector->FormNeedToBeChanged();
  return true;
}

#endif









Generated by  Doxygen 1.6.0   Back to index