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

vdkb_objinspect.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
 */
#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_objinspect.h>
#include <vdkb2/vdkb.h>
#include <vdkb2/vdkb_signal.h>
#include <vdkb2/vdkb_form.h>
#include <ctype.h>
#include <vdkb2/vdkb_evbox.h>
#include <vdkb2/vdkb_textlabel.h>
#include <vdkb2/vdkb_menuitem.h>
#include <vdkb2/vdkb_menubar.h>
#include <vdkb2/vdkb_paned.h>
#include <vdkb2/vdkb_notebook.h>
#include <vdkb2/vdkb_toolbar.h>
#include <vdkb2/vdkb_locale.h>
#include <vdkb2/vdkb_handlebox.h>
#include <vdkb2/vdkb_rbgroup.h>
#include <vdkb2/vdkb_guicanvas.h>
#include <vdkb2/vdkb_cbrowse.h>
// #include <vdkb2/vdkb_packer.h>
#include <vdkb2/vdkb_pholder.h>
#include <vdkb2/vdkb_fixed.h>
#include <vdkb2/vdkb_clipdlg.h>
#include <vdkb2/vdkb_widclip.h>
//
#include "./pixmaps/font16.xpm"
#include "./pixmaps/setcolor16.xpm"
#include "./pixmaps/widname.xpm"
#include "./pixmaps/undo.xpm"
#include "./pixmaps/repack.xpm"
#include "./pixmaps/calltip.xpm"
#include "./pixmaps/tag.xpm"
#include "./pixmaps/dock.xpm"
#define VERBOSE 1

void create_font_selection (void);
void font_selection_ok (GtkWidget *w, GtkFontSelectionDialog *fs);
void font_selection_cancel (GtkWidget *w, GtkFontSelectionDialog *fs);
char* selected_font = NULL;
extern VDKBWidgetClipboard* WidgetClipboard;
extern char* wi_prompts[];
extern char* popmenu_prompts[];
static char buff[256];
static VDKBGuiForm* activeOwner = NULL;
static char *color_states[] =
{
  "normal","prelight","insensitive","active","selected","foreground",0
};
/*
NORMALBACKGROUND,PRELIGHTBACKGROUND,
INSENSITIVEBACKGROUND,ACTIVEBACKGROUND,
SELECTEDBACKGROUND,FOREGROUND,0
};
*/

char *justifications[] =
{ "l_justify",
"c_justify",
"r_justify",
0
};
/*
static char* sides[] =
{
"top","bottom","left","right",0
};
static char*anchors[] =
{
"center","north","nort-west","north-east",
"south","south-west","south-east",
"west","east",0
};
*/
/*
 */
// in vdkb_design.cc
extern FormEventHandlers evTableItems [];

//////////////////////////////////////////////
DEFINE_SIGNAL_LIST(VDKBObjectInspector,VDKForm);

DEFINE_EVENT_LIST(VDKBObjectInspector,VDKForm);

DEFINE_SIGNAL_MAP(VDKBObjectInspector,VDKForm)
  ON_SIGNAL(nameButton,clicked_signal,SetWidgetName),
  ON_SIGNAL(name,activate_signal,SetWidgetName),
  ON_SIGNAL(nbook,switch_page_signal,OnPageSwitch),
  ON_SIGNAL(sigtable,select_row_signal,OnSelectTable),
  ON_SIGNAL(evtable,select_row_signal,OnSelectEventTable),
  ON_SIGNAL(evtable,click_column_signal,OnJumpToFormEventHandler),
  ON_SIGNAL(sigtable,click_column_signal,OnSelectTable),
  ON_SIGNAL(fontButton,clicked_signal,OnSelectFont),
  ON_SIGNAL(enabled,toggled_signal,OnSelectEnabled),
  ON_SIGNAL(visible,toggled_signal,OnSelectVisible),
  ON_SIGNAL(preview,toggled_signal,OnSelectPreview),
  ON_SIGNAL(repackButton,clicked_signal,RepackWidget),
  ON_SIGNAL(tipButton,clicked_signal,SetWidgetTip),
  ON_SIGNAL(tip,activate_signal,SetWidgetTip),
  ON_SIGNAL(colorButton,clicked_signal,OnChangeColor),
  ON_SIGNAL(restoreDefaultButton,clicked_signal,OnRestoreDefaultStyle),
  ON_SIGNAL(mul_connect,clicked_signal,OnMultipleConnect),
  ON_SIGNAL(WidgetsTree,select_node_signal,OnSelectWidgetsTree),
  ON_SIGNAL(WidgetsTree,click_column_signal,OnClickColumnWidgetsTree),
  ON_SIGNAL(add_remove_event,clicked_signal,ConnectToFormEvent),
  ON_SIGNAL(tagButton,clicked_signal,SetWidgetTag),
  ON_SIGNAL(tag,activate_signal,SetWidgetTag),
  ON_SIGNAL(declarePublic,toggled_signal,OnDeclarePublic)
  //   ON_SIGNAL(reconfigure,clicked_signal,ReconfigurePackerWidget),
  // ON_SIGNAL(treeToolbar,clicked_signal,OnToolbarClicked)
END_SIGNAL_MAP


/*
 */
bool
VDKBObjectInspector::OnClickColumnWidgetsTree(VDKObject*)
{
if(activeOwner)
  LoadTree(activeOwner);
return true;
}
/*
 */
void
VDKBObjectInspector::SelectWidgetByTree(VDKBObject* object)
{
VDKTreeNode node = NULL;
// calling with <object> == NULL
// selects root (form)
if(object)
    node = gtk_ctree_find_by_row_data (GTK_CTREE(WidgetsTree->CustomWidget()),
                               NULL,
                               (gpointer)  object);
 gtk_ctree_node_moveto (GTK_CTREE(WidgetsTree->CustomWidget()),
                     node,  0,  0.5, -1.0);
 WidgetsTree->SelectedNode = node;
}
/*
 */
bool
VDKBObjectInspector::OnSelectWidgetsTree(VDKObject*)
{
  VDKBObject* selected_object = NULL;
  VDKTreeNode node = WidgetsTree->SelectedNode;
  if(! node) return true;
  // retrieve widget address stored by LoadTree()
  gpointer gp =
    gtk_ctree_node_get_row_data(GTK_CTREE(WidgetsTree->CustomWidget()),
                        node);
  // cast it to a VDKBObject
  selected_object = reinterpret_cast<VDKBObject*> (gp);
  // unmark active widget if any
  if(active)
    active->ClearMark();
  // form inner box was selected
  // since LoadTree set NULL into row data at root level (form)
  if(! selected_object)
    {
      if(activeOwner && dynamic_cast<VDKBObject*>(activeOwner))
          selected_object = activeOwner;
      /*
        Raising form gui editor  disabled since 
        does not work well on some wm (such as icewm)
      */
      activeOwner->Raise();
    }
  // set owner active widget
  if(activeOwner && selected_object)
    {
      activeOwner->Active  = selected_object;
      // activates inspector on selected widget
      SetActive(selected_object,false);
      // mark it
      if(active)
      active->Mark();
      // 
      gtk_widget_queue_draw(GTK_WIDGET(Window()));
    }
  else
    DisableInspector();
  // enable/disable toolbar
  if( (!WidgetsTree->SelectedNode) ||
      (!activeOwner) ||
      (!selected_object) ||
      (selected_object == activeOwner)
      )
    {
      BList* widlist = treeToolbar->ButtonList();
      for(int t = 0; t < widlist->size()-1; t++)
      (*treeToolbar)[t]->Enabled = false;
    }
  else
    {
      // cut
      (*treeToolbar)[0]->Enabled = true;
      // copy
      (*treeToolbar)[1]->Enabled = selected_object &&
      !dynamic_cast<VDKBEventContainer*>(selected_object);
      // paste
      (*treeToolbar)[2]->Enabled = WidgetClipboard->size() > 0;
      // paste others
      (*treeToolbar)[3]->Enabled = WidgetClipboard->size() > 1;
    }
  return true;
}

/*
 */
bool
VDKBObjectInspector::SetWidgetTip(VDKObject*)
{
  if(!active)
    return true;
  active->SetPropValue("Tip", strlen(tip->Text) > 0 ? tip->Text : (char*) NIHIL_PROP);
  FormNeedToBeChanged();
  return true;
}
/*
 */
bool
VDKBObjectInspector::SetWidgetTag(VDKObject*)
{
  if(!active)
    return true;
  active->SetPropValue("Tag", strlen(tag->Text) > 0 ? tag->Text : NIHIL_PROP);
  FormNeedToBeChanged();
  return true;
}
/*
 */
void
VDKBObjectInspector::FormNeedToBeChanged(bool flag)
{
  VDKBGuiForm* owner_form = NULL;
  if(!active)
    return ;
  if( (owner_form = dynamic_cast<VDKBGuiForm*>(active)) )
    owner_form->Changed = flag;
  else
    {
      VDKObject* vdkobj = dynamic_cast<VDKObject*>(active);
      if(vdkobj)
      {
        owner_form = dynamic_cast<VDKBGuiForm*>(vdkobj->Owner());
        if(owner_form)
          owner_form->Changed = flag;
      }
    }
}

/*
 */
bool
VDKBObjectInspector::OnSelectPreview(VDKObject* )
{
  GtkPackType packtype =
    justification->Selected == 2  ? GTK_PACK_END : GTK_PACK_START;
  if(!active)
    return true;

  VDKBEventBox *box = dynamic_cast<VDKBEventBox*>(active);
  if(!box)
    return true;
  else
    box->PreviewFlag = (bool) preview->Checked;

  EventBoxListIterator li(box->boxlist);
  for(;li;li++)
    {
      VDKBObject* vdkbobj = dynamic_cast<VDKBObject*>(li.current());
      if(vdkbobj)
      {
        int propExpand = atoi(vdkbobj->GetProp( EXPAND_INTERNAL));
        int propFill = atoi(vdkbobj->GetProp("_Fill"));
        int propPadding = atoi(vdkbobj->GetProp("_Padding"));
        gtk_box_set_child_packing(GTK_BOX(box->Container()),
                            vdkbobj->ObjectFromVDK()->WrappedWidget(),
                            preview->Checked ? propExpand : 0,
                            preview->Checked ? propFill : 0,
                            propPadding,
                            packtype);
      }
    }
  return true;
}
/*
 */
bool
VDKBObjectInspector::RepackWidget(VDKObject* obj)
{
  if(!active)
     return true;
  GtkPackType packtype =
    justification->Selected == 2  ? GTK_PACK_END : GTK_PACK_START;
  sprintf(buff,"%d",(int) padding->ValueAsInt);
  active->SetPropValue("_Padding",buff);
  int paddingtype  =  atoi(buff);
  bool filltype =  fill->Checked;
  bool expandtype =  expand->Checked;
  active->SetPropValue(JUSTIFY_INTERNAL,
                   justification->Selected == 0 ? (char*) "0" :
                   justification->Selected == 1 ? (char*) "1" :
                   (char*) "2");
  active->SetPropValue("_Fill", filltype ? (char*) "1" : (char*) "0");
  active->SetPropValue( EXPAND_INTERNAL,expandtype ? (char*) "1" :
                  (char*) "0");
  FormNeedToBeChanged();
  /* there are some exceptions, ... not good OOP here  :-(
  */
  // menu item is an exception
  VDKBMenuItem* menuitem = dynamic_cast<VDKBMenuItem*>(active);
  if(menuitem)
    {
      if(packtype == GTK_PACK_END)
      gtk_menu_item_right_justify(
                (GTK_MENU_ITEM(active->ObjectFromVDK()->WrappedWidget())));
      else
        GTK_MENU_ITEM(menuitem->ObjectFromVDK()->
                  WrappedWidget())->right_justify = 0;
    }
  // VDKBEventBox and most of containers: normally packed
  VDKBEventBox* box = dynamic_cast<VDKBEventBox*>(active->ObjectFromVDK()->Parent());
  if(box)
    {
      gtk_box_set_child_packing(GTK_BOX(box->Container()),
                        active->ObjectFromVDK()->WrappedWidget(),
                        expandtype,filltype,paddingtype,packtype);
      return true;
    }
  // VDKBMenubar differently packed
  // since casting from menubar to box fails.
  VDKBMenubar* bar =  dynamic_cast<VDKBMenubar*>(active->ObjectFromVDK()->Parent());
  if(bar)
    {
      if (GTK_WIDGET_DRAWABLE (bar->WrappedWidget()))
        {
          gtk_widget_queue_clear (GTK_WIDGET (bar->WrappedWidget()));
        }
      gtk_widget_queue_resize (GTK_WIDGET (bar->WrappedWidget()));
      return true;
    }
  return true;
}
/*
 */
bool
VDKBObjectInspector::OnSelectVisible(VDKObject*)
{
if(!active)
  return true;
 bool flag =  visible->Checked;
 active->SetPropValue(VISIBLE,flag ? CHECK_TRUE : CHECK_FALSE);
 active->ObjectFromVDK()->Visible = flag;
 FormNeedToBeChanged();
 return true;
}
/*
 */
bool
VDKBObjectInspector::OnSelectEnabled(VDKObject*)
{
if(!active)
  return true;
 bool flag =  enabled->Checked;
 active->SetPropValue(ENABLED,flag ? CHECK_TRUE : CHECK_FALSE);
 FormNeedToBeChanged();
return true;
}
/*
 */
/*
 */
bool
VDKBObjectInspector::OnDeclarePublic(VDKObject*)
{
  if(!active)
    return true;
  bool flag =  declarePublic->Checked;
  active->SetPropValue(DECLARE_PUBLIC,flag ? CHECK_YES : CHECK_NO);
  FormNeedToBeChanged();
  return true;
}
/*
 */
bool
VDKBObjectInspector::OnSelectFont(VDKObject*)
{
create_font_selection ();
if(selected_font)
  {
    font->Text = selected_font;
    VDKObject* vdkobj = dynamic_cast<VDKObject*>(active);
    if(vdkobj)
      {
      VDKBGuiForm* owner_form = dynamic_cast<VDKBGuiForm*>(vdkobj->Owner());
      if(owner_form)
        {
          VDKFont* newfont = new VDKFont(owner_form,selected_font);
          if( (char*) *newfont) // valid font
            {
            active->ObjectFromVDK()->Font = newfont;
            active->SetPropValue( FONT,selected_font);
            }
          else
            newfont->Destroy();
        }
      }
    g_free(selected_font);
  }
FormNeedToBeChanged();
return true;
}
/*
 */
bool
VDKBObjectInspector::OnJumpToFormEventHandler(VDKObject*)
{
  int ndx = evtable->Selected.Row();
  if( (ndx < 0) || ( ndx >= (evtable->Tuples.size())) )
    return true;
  VDKString True = CHECK_TRUE;
  VDKBGuiForm* owner_form = dynamic_cast<VDKBGuiForm*>(active);
  if(owner_form)
    {
      VDKBProjectManager* prjman =
      dynamic_cast<VDKBProjectManager*>(owner_form->Owner());
      if(prjman)
      {
        char textname[256];
        sprintf(textname,"%s.cc",(char*) owner_form->Name());
        prjman->DefineFormEventHandler(textname,evtable->Tuples[ndx][0]);
      }
    }
  return true;
}
/*
 */
bool
VDKBObjectInspector::ConnectToFormEvent(VDKObject*)
{
  bool write_response = false;
  if(!active)
    return true;
  int ndx = evtable->Selected.Row();
  if( (ndx < 0) || ( ndx >= (evtable->Tuples.size())) )
    return true;
  VDKString True = CHECK_TRUE;
  VDKBGuiForm* owner_form =
      dynamic_cast<VDKBGuiForm*>(active);
  if(owner_form)
    {
      VDKString prop = owner_form->GetProp((char*) evtable->Tuples[ndx][0]);
      // toggles property
      if(prop == True)
      {
        owner_form->SetPropValue((char*) evtable->Tuples[ndx][0],CHECK_FALSE);
        evTableItems[ndx].items[1] = CHECK_NO;
        add_remove_event->Caption = _(wi_prompts[1]);
        evtable->Titles[0]->Enabled = true;
      }
      else
      {
        owner_form->SetPropValue((char*)evtable->Tuples[ndx][0],CHECK_TRUE);
        add_remove_event->Caption = _(wi_prompts[0]);
        write_response = true;
        evTableItems[ndx].items[1] = CHECK_YES;
        evtable->Titles[0]->Enabled = false;
      }
      evtable->UpdateRow(ndx,evTableItems[ndx].items);
      VDKBProjectManager* prjman =
      dynamic_cast<VDKBProjectManager*>(owner_form->Owner());
      if(write_response && prjman)
      {
        char textname[256];
        sprintf(textname,"%s.cc",(char*) owner_form->Name());
        prjman->DefineFormEventHandler(textname,evtable->Tuples[ndx][0]);
      }
    }
  FormNeedToBeChanged();
  return true;
}
// call project manager to write or jump to
// response method
bool
VDKBObjectInspector::OnSelectEventTable(VDKObject*)
{
  if(!active)
    return true;
  int ndx = evtable->Selected.Row();
  if( (ndx < 0) || ( ndx >= (evtable->Tuples.size())) )
    return true;
  VDKString True = CHECK_TRUE;
  VDKBGuiForm* owner_form =
      dynamic_cast<VDKBGuiForm*>(active);
  if(owner_form)
    {
      VDKString prop = owner_form->GetProp((char*) evtable->Tuples[ndx][0]);
      if( prop == True)
      {
        add_remove_event->Caption = _(wi_prompts[1]);
        evtable->Titles[0]->Enabled = true;
      }
      else
      {
        add_remove_event->Caption = _(wi_prompts[0]);
        evtable->Titles[0]->Enabled = false;
      }
    }
  return true;
}
/*
 */
// call project manager to write or jump to
// response method
bool
VDKBObjectInspector::OnSelectTable(VDKObject*)
{
  if(!active)
    return true;
  int ndx = sigtable->Selected.Row();
  if( (ndx <= 0) || ( ndx >= (sigtable->Tuples.size()-1)) )
    return true;
  VDKObject* vdkobj = dynamic_cast<VDKObject*>(active);
  if(vdkobj)
    {
      VDKBGuiForm* owner_form =
      dynamic_cast<VDKBGuiForm*>(vdkobj->Owner());
      if(owner_form)
      {
        VDKBProjectManager* prjman =
          dynamic_cast<VDKBProjectManager*>(owner_form->Owner());
        if(prjman)
          {
            char textname[256];
            sprintf(textname,"%s.cc",(char*) owner_form->Name());
            prjman->
            DefineResponseMethod(textname,
                             owner_form->SignalList[ndx-1].slot);
          }
      }
    }
  FormNeedToBeChanged();
  return true;
}

/*
 */
bool
VDKBObjectInspector::DeleteConnection(VDKObject* sender)
{
  if(!active)
    return true;
  int ndx = sigtable->Selected.Row();
  VDKObject* vdkobj = dynamic_cast<VDKObject*>(active);
  if(vdkobj)
    {
      VDKBGuiForm* owner_form =
      dynamic_cast<VDKBGuiForm*>(vdkobj->Owner());
      if(owner_form)
      {
        // firs sigtable row unused
        owner_form->SignalList.unlink(ndx-1);
        LoadStaticTable();
      }
    }
  FormNeedToBeChanged();
  return true;
}
// into vdkb_design.cc
extern char*
WidgetClassName(int action_target);
extern OpState  OperationalState;
/*
 */
bool
VDKBObjectInspector::OnWidgetsTreeButtonPress(VDKObject* sender,
                                   GdkEvent* event)
{
  // FIX ME: language support
  GdkEventButton* ev = (GdkEventButton*) event;
  if(ev->button != 3)
    return false;
  if(OperationalState.state == op_stand_by &&
     OperationalState.action == act_add_widget &&
     OperationalState.target == NULL)
    {
      // can do if is a container or form is selected
      bool canDo  = dynamic_cast<VDKBEventContainer*>(active) || !active;
      if(canDo)
      {
        char* name = WidgetClassName(OperationalState.action_target);
        char* targetname = active ? (char*) active->Name() :
          activeOwner ? (char*) activeOwner->Name() : (char*) "unknown";
        sprintf(buff,_(wi_prompts[2]), name ? name : "unknown", targetname);
        dropwidget->Caption = buff;
        treepopmenu->Popup();
      }
    }
  else if(active)
    active->PopMenu();
  return false;
}
/*
 */
bool
VDKBObjectInspector::DropWidget(VDKObject* sender)
{
  GdkEventButton event;
  event.type = GDK_BUTTON_PRESS;
  event.button = 1;
  VDKBGuiForm* ownerform = active ?
    dynamic_cast<VDKBGuiForm*>(active->ObjectFromVDK()->Owner()) :
    activeOwner ? activeOwner : NULL;
  if(ownerform)
    {
      // call active widget owner form that makes the job
      // calling with NULL add to innerbox
      VDKObject* target = active ? active->ObjectFromVDK(): NULL;
      ownerform->OnButtonPress( target, (GdkEvent*) &event);
    }
  return true;
}
/*
 */
bool
VDKBObjectInspector::OnSignalListButtonPress(VDKObject* sender,
                                   GdkEvent* event)
{
  if(!active)
    return false;
  GdkEventButton* ev = (GdkEventButton*) event;
  if(ev->button != 3)
    return false;
  else
    {
      int ndx = sigtable->Selected.Row();
      if( (ndx > 0) && ( ndx < (sigtable->Tuples.size()-1)) )
      popmenu->Popup();
    }
  return false;
}
/*
 */
bool
VDKBObjectInspector::OnActivateSlotName(VDKObject* sender)
{
    if(!active)
    return true;
  // looks on entries array
  int t;
  for(t = 0; t < sigEntries.size(); t++)
    if(sender == sigEntries[t])
      break;
  // freezes the slot
  if(t < sigEntries.size())
    {
      active->SignalList()[t].Slot(sigEntries[t]->Text);
      active->SignalList()[t].SlotFixed(true);
    }
  FormNeedToBeChanged();
  return true;
}
/*
 */
bool
VDKBObjectInspector::OnMultipleConnect(VDKObject*)
{
  int sel;
  if(!active)
    return true;
  else
    sel = sigcombo->Selected;
  if(sel < 0)
    return true;
  VDKString slot = (sigcombo->GetPopdownStrings())[sel];
  // find signal with that slot
  VDKObject* vdkobj = dynamic_cast<VDKObject*>(active);
  if(vdkobj)
    {
      VDKBConnectionList* list = NULL;
      VDKBGuiForm *owner_form =
      dynamic_cast<VDKBGuiForm*>(vdkobj->Owner());
      if(owner_form)
      list = &(owner_form->SignalList);
      else
      return true;
      VDKBConnectionListIterator li(*list);
      for(;li;li++)
      {
        VDKString list_slot = li.current().slot;
        if ( list_slot == slot)
          {
            VDKBConnection c(active->Name(),
                         (char*) li.current().signal,
                         (char*) list_slot, false);
            if(!owner_form->SignalList.find(c))
            {
              owner_form->SignalList.add(c);
              LoadStaticTable();
              return true;
            }
            else
            {
            Application()->VDKMessageBox(APPNAME, _(wi_prompts[3]),
                                VDK_OK| VDK_ICONINFORMATION);
            return true;
            }
          }
      }
    }
  Application()->VDKMessageBox(APPNAME,_(wi_prompts[3]), VDK_OK| VDK_ICONINFORMATION);
  return true;
}
/*
 */
bool
VDKBObjectInspector::OnConnectSignal(VDKObject* sender)
{
    if(!active)
    return true;

  // looks on button array
  int t;
  for(t = 0; t < connectButtons.size(); t++)
    if(sender == connectButtons[t])
      break;
  if(t < connectButtons.size())
    {
      VDKBConnection c(active->SignalList()[t].Sender()->Name(),
                   active->SignalList()[t].Signal(),
                   active->SignalList()[t].Slot());
      VDKObject* vdkobj = dynamic_cast<VDKObject*>(active);
      if(vdkobj)
      {
        VDKBGuiForm* owner_form =
          dynamic_cast<VDKBGuiForm*>(vdkobj->Owner());
        if(owner_form )
          {
            if(!owner_form->SignalList.find(c))
            {
              owner_form->SignalList.add(c);
              LoadStaticTable();
            }
            else
            Application()->VDKMessageBox(APPNAME,
                                _(wi_prompts[5]),
                                VDK_OK| VDK_ICONINFORMATION);
          }
      }
    }
  FormNeedToBeChanged();
  return true;
}
/*
 */
void
VDKBObjectInspector::LoadStaticTable()
{
    if(!active)
    return ;

  int t = 0;
  VDKBConnectionList* list = NULL;
  VDKBGuiForm* owner_form = NULL;
  char* p = buff;
  char formname[128];
  VDKObject* vdkobj = dynamic_cast<VDKObject*>(active);
  if(vdkobj)
    {
      owner_form =
      dynamic_cast<VDKBGuiForm*>(vdkobj->Owner());
      if(owner_form)
      list = &(owner_form->SignalList);
      else
      return;
    }
  else
    return;
  sigtable->Clear();
  strcpy(formname,owner_form->Name());
  formname[0] = toupper(formname[0]);
  sprintf(buff,"DEFINE_SIGNAL_MAP(%sForm,VDKForm)",formname);
  sigtable->AddRow(&p);
  VDKBConnectionListIterator li(*list);
  StringList sl;
  for(;li;li++,t++)
    {
      if(li.current().declare)
      sl.add(li.current().slot);
      sprintf(buff,"ON_SIGNAL(%s,%s,%s),",
            (char*) li.current().sender,
            (char*) li.current().signal,
            (char*) li.current().slot);
      if(t == (list->size()-1) )
      buff[strlen(buff)-1] = '\0';
      sigtable->AddRow(&p);
    }
  sprintf(buff,"END_SIGNAL_MAP");
  sigtable->AddRow(&p);
  sigcombo->ClearList();
  if(sl.size() > 0)
    sigcombo->PopdownStrings = sl;
}
/*
 */
bool
VDKBObjectInspector::OnPageSwitch(VDKObject*)
{
  if(!active)
    return true;

  int activePage = nbook->ActivePage;
  if(activePage < 0 || activePage >= nbook->Pages.size())
    return true;
  switch(activePage)
    {
    case 1: // signal page
      SetSlotEntries();
      break;
    }
return true;
}
/*
 */
void
VDKBObjectInspector::SetSlotEntries()
{
  if( !active || (active->SignalList().size() <= 0 ) )
    return;
  int t;
  for(t=0; t < sigEntries.size();t++)
    {
      if(! active->SignalList()[t].SlotFixed())
      {
        sprintf(buff,"On%s%s",
              (char*) active->SignalList()[t].Sender()->Name(),
              (char*) active->SignalList()[t].Nickname());
        sigEntries[t]->Text = buff;
        active->SignalList()[t].Slot(buff);
      }
    }
}
/*
 */
bool
VDKBObjectInspector::SetWidgetName(VDKObject*)
{
  if(!active)
    return true;

  VDKObject* vdkobj = dynamic_cast<VDKObject*>(active);
  if(vdkobj)
    {
      VDKBGuiForm* owner_form = dynamic_cast<VDKBGuiForm*>(vdkobj->Owner());
      if(owner_form && owner_form->ChildWithName((char*) name->Text))
      // FIX ME: language support
      Application()->VDKMessageBox(APPNAME, _(wi_prompts[6]),
                          VDK_OK| VDK_ICONINFORMATION);
      else if(owner_form && (strlen((char*) name->Text) > 0))
      {
        // widget name is changed so it's
        // necessary to update also signal table
        VDKString oldname = oldWidgetName;
        VDKString newname = (char*) name->Text;
        active->Name((char*) name->Text);
        // changes widget name
        owner_form->ChangeConnectionSenderName(newname,oldname);
        // update signal table
        SetSlotEntries(); 
        oldWidgetName = newname;
        // reactivate inspector
        SetActive(active);
        LoadTree(owner_form);
        FormNeedToBeChanged();
      }
      else
      {
        // widget name can't be empty
        // FIX ME: language support
        Application()->VDKMessageBox(APPNAME,
                            _(wi_prompts[7]),
                            VDK_OK| VDK_ICONINFORMATION);
        name->Text = (char*) oldWidgetName;
      }

    }
return true;
}

/*
  warning: function behaviour heavily depends on
  which theme we are using.
  Works well on default theme, some erratic behaviour with
  pixmapped themes.
 */
bool
VDKBObjectInspector::OnRestoreDefaultStyle(VDKObject* sender)
{
  char color[32];
  GtkWidget* wid;
  //  char* fontname;
  if(!active)
    return true;
  wid = active->ObjectFromVDK()->WrappedWidget();
  // restore default style & font
  // doesn't work for fonts :-(
  gtk_widget_restore_default_style(wid); 
  /*
  GtkStyle* rcstyle = gtk_rc_get_style(wid);
  GtkStyle* style = gtk_style_copy(gtk_widget_get_style(wid));
  g_return_val_if_fail(rcstyle != NULL,TRUE);
  g_return_val_if_fail(style != NULL,TRUE);
  gtk_style_ref(style);
  style->font = rcstyle->font;
  gtk_widget_set_style(wid,style);
  */
  // resets to nihil all color/font properties
  sprintf(color,"nihil");
  active->SetPropValue(NORMALBACKGROUND,color);
  active->SetPropValue(PRELIGHTBACKGROUND,color);
  active->SetPropValue(INSENSITIVEBACKGROUND,color);
  active->SetPropValue(ACTIVEBACKGROUND,color);
  active->SetPropValue(SELECTEDBACKGROUND,color);
  active->SetPropValue(FOREGROUND,color);
  active->SetPropValue(FONT,color);
  font->Text = "";
  // here an exception, since canvas do not display immediately changes
  VDKBGuiCanvas* canvas;
  VDKBPlaceHolder* pholder;
  if( (canvas = dynamic_cast<VDKBGuiCanvas*>(active)) )
    {
      ((VDKCanvas*)canvas->ObjectFromVDK())->Clear();
       ((VDKCanvas*)canvas->ObjectFromVDK())->Redraw();
    }
  else if( (pholder = dynamic_cast<VDKBPlaceHolder*>(active)) )
    {
      ((VDKCanvas*)pholder->ObjectFromVDK())->Clear();
      ((VDKCanvas*)pholder->ObjectFromVDK())->Redraw();
    }
  FormNeedToBeChanged();
  return true;
}

/*
 */
bool
VDKBObjectInspector::OnChangeColor(VDKObject* sender)
{
  int ndx;
  char color[32];
  VDKDefaultColor parms;
  if(!active)
    return true;
  else if(sender == NULL)
    {
      gtk_widget_restore_default_style(active->ObjectFromVDK()->WrappedWidget());
      active->SetPropValue(NORMALBACKGROUND,NIHIL_PROP);
      return true;
    }
  else
    {
      ndx = colortypecombo->Selected;
      if(ndx < 0)
      return true;
      VDKBColorBrowser* dlg = new VDKBColorBrowser(this,&parms);
      dlg->Setup();
      dlg->ShowModal(GTK_WIN_POS_CENTER);
      // calls GC now
      CollectGarbage();
      if(parms.red < 0)
      return true;

    }
  VDKRgb newcolor(parms.red, parms.green, parms.blue);
  sprintf(color,"%d,%d,%d", newcolor.red, newcolor.green, newcolor.blue);
  
  switch(ndx)
    {
    case 0: // normal background
      active->ObjectFromVDK()->NormalBackground = newcolor;
      active->SetPropValue(NORMALBACKGROUND,color);
      break;
    case 1: // prelight background
      active->ObjectFromVDK()->PrelightBackground = newcolor;
      active->SetPropValue(PRELIGHTBACKGROUND,color);
      break;
    case 2: // InsensitiveBackground
      active->ObjectFromVDK()->InsensitiveBackground = newcolor;
      active->SetPropValue(INSENSITIVEBACKGROUND,color);
      break;
    case 3: // ActiveBackground
      active->ObjectFromVDK()->ActiveBackground = newcolor;
      active->SetPropValue(ACTIVEBACKGROUND,color);
      break;
    case 4:
      active->ObjectFromVDK()->SelectedBackground = newcolor;
      active->SetPropValue(SELECTEDBACKGROUND,color);
      break;
    case 5: // Foreground
      active->ObjectFromVDK()->Foreground = newcolor;
      active->SetPropValue(FOREGROUND,color);
      break;
    }
  // here an exception, since canvas do not display immediately changes
  VDKBGuiCanvas* canvas;
  VDKBPlaceHolder* pholder;
  if( (canvas = dynamic_cast<VDKBGuiCanvas*>(active)) )
    {
      ((VDKCanvas*)canvas->ObjectFromVDK())->Clear();
       ((VDKCanvas*)canvas->ObjectFromVDK())->Redraw();
    }
  else if( (pholder = dynamic_cast<VDKBPlaceHolder*>(active)) )
    {
      ((VDKCanvas*)pholder->ObjectFromVDK())->Clear();
      ((VDKCanvas*)pholder->ObjectFromVDK())->Redraw();
    }
  FormNeedToBeChanged();
  return true;
}

/*
 */
VDKBObjectInspector::VDKBObjectInspector(VDKForm* owner, VDKBObject* active,
                               char* title,
                               int mode,
                               GtkWindowType display):
  VDKForm(owner,title,mode,display),active(active)
{
  active = NULL;
  ForceToClose = false;
  extrawidget = NULL;
  sigpageBox = evpageBox = NULL;
}
/*
 */
VDKBObjectInspector::~VDKBObjectInspector()
{
}
/*
 */
bool
VDKBObjectInspector::CanClose()
{
return ForceToClose == true;
}


/*
 */
void
VDKBObjectInspector::OnShow(VDKForm*)
{
  // modifyng window policy and or window position
  // on modals makes XServer die :-(
  if(!IsModal())
    {
      VDKPoint ownerPos = Owner()->Position;
      VDKPoint ownerSize = Owner()->Usize;
      VDKPoint p(ownerPos.X() + 30, ownerPos.Y() + 50);
      Position = p;
      // does not allow to shrink or grow
      VDKString Yes = CHECK_YES;
      if(VDKBuilder::ideDefaults.project.wi_resizeable != Yes)
      gtk_window_set_policy(GTK_WINDOW(Window()),false,false,true);
    }
  else
    ForceToClose = true;
}
/*
Tries to load
/var/X11R6/lib/rgb.txt colors database
Unused, substituted with VDKColorBrowser
 */
bool
VDKBObjectInspector::LoadRGB(StringList& colors)
{
  printf("\ncall to unused VDKBObjectInspector::LoadRGB()");
  fflush(stdout);
  return true;
}
/*
 */
void
VDKBObjectInspector::Setup()
{
  sprintf(buff,_(wi_prompts[8]));
  Title = buff;
  int layout = atoi((char*) VDKBuilder::ideDefaults.project.wi_layout);
  VDKBox* panebox = new VDKBox(this,layout);
  panebox->Add(MakeWidgetsTreePage(),l_justify,false,false,2);
  nbook = new VDKNotebook(this);
  nbook->AddPage(mainbox = MakePropertiesPage(),_(wi_prompts[9]));
  // set signal page container to NULL
  sigpageBox = NULL;
  // set signal table to NULL
  sigtable = NULL;
  // set pop menu
  popmenu = new VDKMenu(this);
  // FIX ME: lang support
  VDKMenuItem *nop = new VDKMenuItem(popmenu,"Nop");
  nop->Enabled = false;
  delConnection = new VDKMenuItem(popmenu,_(wi_prompts[10]));
  SignalConnect(delConnection,"activate",&VDKBObjectInspector::DeleteConnection);
  /*
    better add it to owner, so will be surely
    destroyed even if never popped
  */
  AddItem(popmenu);
  panebox->Add(new VDKSeparator(this),l_justify,false,false,0);
  dockerbox = new VDKDockerBox(this);
  dockerbox->Add(nbook,l_justify,false,false,0);
  panebox->Add(dockerbox,l_justify,false,false,0);
  SignalConnect(dockerbox,"docked",&VDKBObjectInspector::OnDocked,false);
  SignalConnect(dockerbox,"undocked",&VDKBObjectInspector::OnDocked,false);
  Add(panebox);
}
/*
 */
bool
VDKBObjectInspector::OnDocked(VDKObject* sender)
{
      if(dockerbox->Docked)
      {
        WidgetsTree->SetSize(-1,350);
        dockerbox->DockForm()->Title = _("Properties and signals");
        gtk_window_set_resizable(GTK_WINDOW(dockerbox->DockForm()->Window()),false);
      }
      else
        WidgetsTree->SetSize(-1,150);
  return true;
}

/*
 */
VDKBox*
VDKBObjectInspector::MakePropertiesPage()
{
  // main page box
  int t;
  VDKBox* Nbook0_Page0 = new VDKBox(this,v_box);
  Nbook0_Page0->SetSize(220,-1);
  CommonPropertiesFrame = new VDKFrame(this,_(wi_prompts[11]),v_box,shadow_etched_in);
  CommonPropertyTable = new VDKTable(this,7,2,true);
  CommonPropertyTable->RowSpacing = 0;
  CommonPropertyTable->ColSpacing = 0;
  CommonPropertyTable->SetSize(-1,200); 
  // widget name
  VDKBox* nbox = new VDKBox(this,h_box);
  declarePublic = new VDKCheckButton(this,_(wi_prompts[36]));
  declarePublic->SetTip(_("Declare as public member"));
  nbox->Add(declarePublic,l_justify,false,false,0);
  nameButton = new VDKCustomButton(this,(const char**) widname_xpm,NULL);// _(wi_prompts[12]));
  nameButton->Relief = (GtkReliefStyle) 2;
  nameButton->SetTip(_("Click to change widget name"));
  nameButton->Enabled = false;
  nbox->Add(nameButton,l_justify,false,false,0);
  CommonPropertyTable->AddToCell(nbox,0,0);
  name = new VDKEntry(this,0);
  name->SetTip(_(wi_prompts[13]));
  CommonPropertyTable->AddToCell(name,0,1);
  // widget color
  VDKBox* cbox = new VDKBox(this,h_box);
  colorButton = new VDKCustomButton(this,(const char**)setcolor16_xpm,NULL);//,_(wi_prompts[15]));
  colorButton->Relief = (GtkReliefStyle) 2;
  colorButton->Enabled = false;
  colorButton->SetTip(_("Click to change widget color"));
  cbox->Add(colorButton,l_justify,false,false,0);
  // font
  fontButton = new VDKCustomButton(this,(const char**)font16_xpm,NULL);// ,_(wi_prompts[16]));
  fontButton->Relief = (GtkReliefStyle) 2;
  fontButton->Enabled = false;
  fontButton->SetTip(_("Click to change widget font"));
  cbox->Add(fontButton,l_justify,false,false,0);
  // restore default style button
  restoreDefaultButton = new VDKCustomButton(this,(const char**) undo_xpm,NULL);//,_(wi_prompts[35])); 
  restoreDefaultButton->Relief = (GtkReliefStyle) 2;
  restoreDefaultButton->Enabled = false;
  restoreDefaultButton->SetTip(_("Restore default font & colors (backgrounds)"));
  cbox->Add(restoreDefaultButton,l_justify,false,false,0);
  cbox->Add(new VDKLabel(this,"Widget state"));
  CommonPropertyTable->AddToCell(cbox,1,0);
  // widget states
  colortypecombo = new VDKCombo(this,NORMALBACKGROUND);
  colortypecombo->SetTip(_("Select widget state to set colors"));
  StringList sc = colortypecombo->PopdownStrings;
  for(t=0; color_states[t]; t++)
    sc.add(VDKString(color_states[t]));
  colortypecombo->PopdownStrings = sc;
  colortypecombo->SelectItem(0);
  CommonPropertyTable->AddToCell(colortypecombo,1,1);
  // widget font
  font = new VDKEntry(this,0);
  font->Editable = false;
  CommonPropertyTable->AddToCell(font,2,0);
  // visible & enabled
  VDKBox* ebox = new VDKBox(this,h_box);
  visible = new VDKCheckButton(this,_("visible"));
  visible->SetTip(_("Uncheck to hide the widget"));
  ebox->Add(visible);
  // enabled
  enabled = new VDKCheckButton(this,_("enabled"));
  // enabled->Enabled = false;
  enabled->SetTip(_("Uncheck to disable the widget"));
  ebox->Add(enabled);
  CommonPropertyTable->AddToCell(ebox,2,1);
  // justification
  VDKBox* fbox = new VDKBox(this,h_box);
  fill = new VDKCheckButton(this,_(wi_prompts[19]));
  fill->Enabled = false;
  fbox->Add(fill,l_justify,false,false,3);
  expand = new VDKCheckButton(this,_(wi_prompts[18]));
  expand->Enabled = false;
  fbox->Add(expand,l_justify,false,false,0);
  CommonPropertyTable->AddToCell(fbox,3,0);
  justification = new VDKCombo(this);
  justification->SetTip(_("Select packing mode"));
  CommonPropertyTable->AddToCell(justification,3,1);
  StringList sj = justification->PopdownStrings;
  for(t=0;justifications[t];t++)
      sj.add(VDKString(justifications[t]));
  justification->PopdownStrings = sj;
  // packing flags
  VDKBox* lhbox = new VDKBox(this,h_box);
  lhbox->Add(new VDKLabel(this,_(wi_prompts[20])),l_justify,false,false,false);
  padding = new VDKSpinButton(this, 0, 0, 20 , 1 ,0 );
  padding->SetTip(_("Select padding size"));
  lhbox->Add(padding,l_justify,false,false,false);
  padding->Enabled = false;
  CommonPropertyTable->AddToCell(lhbox,4,0);

  repackButton = new VDKCustomButton(this,(const char**) repack_xpm,_(wi_prompts[21]));
  repackButton->Relief = (GtkReliefStyle) 2;
  repackButton->Enabled = false;
  repackButton->SetTip(_("Click to repack the widget"));
  CommonPropertyTable->AddToCell(repackButton,4,1);
  // box preview
  preview = new VDKCheckButton(this,_(wi_prompts[22]));
  preview->SetTip(_("Toggle preview mode"));
  CommonPropertyTable->AddToCell(preview,5,0);

  VDKBox* hbbox2 = new VDKBox(this,h_box);
  // widget tip
  tipButton = new VDKCustomButton(this,(const char**) calltip_xpm,NULL);// ,_(wi_prompts[28]));
  tipButton->Relief = (GtkReliefStyle) 2;
  tipButton->Enabled = false;
  tipButton->SetTip(_("Click to set the widget tip"));
  hbbox2->Add(tipButton,l_justify,false,false,0);
  tip = new VDKEntry(this,0);
  hbbox2->Add(tip);
  CommonPropertyTable->AddToCell(hbbox2,6,0);
  // widget tag
  VDKBox* hbbox3 = new VDKBox(this,h_box);
  tagButton = new VDKCustomButton(this,(const char**) tag_xpm,NULL);//,_(wi_prompts[29]));
  tagButton->Relief = (GtkReliefStyle) 2;
  tagButton->Enabled = false;
  tagButton->SetTip(_("Click to set the widget tag\ntag is an integer >= 0"));
  hbbox3->Add(tagButton,l_justify,false,false,0);
  tag = new VDKEntry(this,0);
  hbbox3->Add(tag);
  CommonPropertyTable->AddToCell(hbbox3,6,1);
  //
  CommonPropertiesFrame->Add(CommonPropertyTable,l_justify,false,false,0);// true,true,false);
  Nbook0_Page0->Add(CommonPropertiesFrame,l_justify,false,false,2);
  return Nbook0_Page0;
}

/*
 */
void
VDKBObjectInspector::DisableInspector()
{

  active = NULL;
  name->Text = "";
  tip->Text = "";
  //colortypecombo->ClearList();
  if(sigpageBox)
    {
      int t;
      // disconnects signals
      for(t=0; t < slots.size();t++)
      if (slots[t] > 0)
        SignalDisconnect(slots[t]);
      //
      connectTable->RemoveObjects();
      sigpageBox->RemoveObjects();
      // remove notebook signal page
      if(nbook->Pages.size() > 1)
      nbook->RemovePage(1);
      sigpageBox = NULL;
    }
  else if(evpageBox)
    {
      evpageBox->RemoveObjects();
      // remove notebook event page
      if(nbook->Pages.size() > 1)
      nbook->RemovePage(1);
      evpageBox = NULL;
    }
  // disable all
  nameButton->Enabled = false;
  colorButton->Enabled = false;
  restoreDefaultButton->Enabled = false;
  fontButton->Enabled = false;
  enabled->Enabled = false;
  visible->Enabled = false;
  justification->Enabled = false;
  expand->Enabled = false;
  fill->Enabled = false;
  padding->Enabled = false;
  tipButton->Enabled = false;
  tagButton->Enabled = false;
  repackButton->Enabled = false;
  // set title
  sprintf(buff,_(wi_prompts[30]));
  Title = buff;
  return;
}
/*
 */
void
VDKBObjectInspector::RemoveExtraWidget()
{
  if (mainbox && extrawidget)
    {
      extrawidget->RemoveObjects();
      mainbox->RemoveObject(extrawidget);
      extrawidget= NULL;
    }
}
/*
normally called by a gui object to
add his own properties widget to inspector.
 */
void
VDKBObjectInspector::AddExtraWidget(VDKObjectContainer* wid)
{
if(mainbox && wid)
  {
    mainbox->Add(wid,l_justify,false,false,0);
    extrawidget = wid;
  }
}

/*
activate inspector
with a gui object selected by user
 */
void
VDKBObjectInspector::SetActive(VDKBObject* act, bool loadWidgetsTree)
{
  // wi going to be disabled
  if(act == NULL)
    {
      DisableInspector();
      RemoveExtraWidget();
      // clear widgets tree
      WidgetsTree->Clear();
      // disable toolbar
      BList* widlist = treeToolbar->ButtonList();
      for(int t = 0; t < widlist->size()-1; t++)
      (*treeToolbar)[t]->Enabled = false;
      return;
    }
  // avoid unuseful wi reloads (except notebook
  // where we should handle page switches
  else if(active == act)
    {
      VDKBGuiNotebook* nb = dynamic_cast<VDKBGuiNotebook*>(active);
      if(!nb)
      return;
    }
  else
      active = act;

  // remove extra fields specific to widget
  if(active)
      RemoveExtraWidget();
      
  // some useful flags
  bool isForm = dynamic_cast<VDKBGuiForm*>(act) != NULL;
  bool isContainer = dynamic_cast<VDKBEventContainer*>(active) != NULL;
  bool isNotebook = dynamic_cast<VDKBGuiNotebook*>(active)!= NULL;
  bool isToolbar = dynamic_cast<VDKBToolbar*>(active)!= NULL;
  bool isLabel = dynamic_cast<VDKBTextLabel*>(active)!= NULL;
  bool isHandle = dynamic_cast<VDKBHandleBox*>(active)!= NULL;
  bool isRadioButtonGroup = dynamic_cast<VDKBRadioButtonGroup*>(active)!= NULL;
  VDKBEventBox* isBox = dynamic_cast<VDKBEventBox*>(active);
  bool cantJustify =
    dynamic_cast<VDKBPaned*>(active->ObjectFromVDK()->Parent())!= NULL;
  bool parentIsPacker = false;
  //     dynamic_cast<VDKBPacker*>(active->ObjectFromVDK()->Parent())!= NULL;
  bool parentIsFixed =
    dynamic_cast<VDKBFixed*>(active->ObjectFromVDK()->Parent())!= NULL;
  // const true and nihil
  VDKString True = CHECK_TRUE;
  VDKString Nihil = NIHIL_PROP;
  // set widget and widget old name
  name->Text = active->Name();
  oldWidgetName = active->Name();
  VDKString _font = active->GetProp( FONT);
  font->Text =  strcmp(_font,NIHIL_PROP) ? (char*) _font : (char*) "";
  // set font also as entry tips
  font->SetTip(_font);
  // set prop values
  if(active->GetProp(ENABLED) != Nihil)
    enabled->Checked = active->GetProp(ENABLED) == True;
  if(active->GetProp(VISIBLE) != Nihil)
    visible->Checked = active->GetProp(VISIBLE) == True;
  if(isBox)
    {
      preview->Enabled = true;
      preview->Checked = isBox->PreviewFlag;
    }
  else
      preview->Enabled = false;
  // packing args
  int justarg = atoi(active->GetProp(JUSTIFY_INTERNAL));
  int exparg = atoi(active->GetProp( EXPAND_INTERNAL));
  int fillarg = atoi(active->GetProp(FILL_INTERNAL));
  int paddarg = atoi(active->GetProp(PADDING_INTERNAL));
  justification->SelectItem(justarg);
  expand->Checked = exparg != 0;
  padding->ValueAsFloat = float(paddarg);
  fill->Checked = fillarg != 0;
  /*
  side->SelectItem(justarg);
  anchor->SelectItem(exparg);
  GtkPackerOptions opts = (GtkPackerOptions) fillarg;
  fillx->Checked = opts & GTK_FILL_X;
  filly->Checked = opts & GTK_FILL_Y;
  p_expand->Checked = opts & GTK_PACK_EXPAND;
  */
  if(!isContainer && !isLabel)
    {
      if(active->GetProp(TIP) != Nihil)
      tip->Text = (char*) active->GetProp(TIP);
      else
      tip->Text = "";
    }
  else
    tip->Text = "";

  if(!isForm)
    {
      if(active->GetProp(TAG) != Nihil)
      tag->Text = (char*) active->GetProp(TAG);
      else
      tag->Text = "";
      declarePublic->Checked = 
      !strcmp((char*) active->GetProp(DECLARE_PUBLIC),CHECK_YES); 
    }
  else
    tag->Text = "";

  // remove notebook page widgets && disconnect signals
  int ndx = nbook->ActivePage;
  if(sigpageBox)
    {
      int t;
      // disconnects signals
      for(t=0; t < slots.size();t++)
      if (slots[t] > 0)
        SignalDisconnect(slots[t]);
      //
      connectTable->RemoveObjects();
      sigpageBox->RemoveObjects();
      sigpageBox = NULL;
    }
  // remove notebook event page
  if(evpageBox)
    {
      evpageBox->RemoveObjects();
      evpageBox = NULL;
    }
  // remove notebook page (sigpageBox included) and reload
  // a new one
  if(nbook->Pages.size() > 1)
    nbook->RemovePage(1);

  // make signals page for all widgets except:
  // forms, labels, containers
  // above widgets do not have any signal provided
  // with these exceptions:
  // notebook,toolbar,handle, radiobutton group
  if((!isForm && !isContainer && !isLabel) ||
     isNotebook ||
     isToolbar ||
     isHandle ||
     isRadioButtonGroup)
    {
#if VERBOSE
      printf("\nmaking signal page");
      fflush(stdout);
#endif
      sigpageBox = MakeSignalsPage();
      nbook->AddPage(sigpageBox,_(wi_prompts[31]));
      nbook->ActivePage = ndx;
      //      gtk_widget_queue_draw(GTK_WIDGET(nbook->WrappedWidget()));
    }
  else
    // no signals at all
    // makes two empty arrays
    {
      sigEntries = VDKArray<VDKEntry*>(0);
      slots = VDKArray<int>(0);
    }
    
  // makes default events page for forms
  if(isForm)
    {
      nbook->AddPage(evpageBox = MakeFormEventsPage(),_(wi_prompts[32]));
      nbook->ActivePage = ndx;
    }

  // enable what can be enabled
  nameButton->Enabled = !isForm;
  fontButton->Enabled = !isContainer;
  enabled->Enabled = !isContainer && !isLabel;
  // visible->Enabled = !isContainer;
  visible->Enabled = true;
  repackButton->Enabled =
    (!cantJustify) && (!isForm) && !(parentIsPacker) && !(parentIsFixed);
  justification->Enabled = (!cantJustify) && (!isForm) && !(parentIsPacker);
  expand->Enabled = !isForm && !(parentIsPacker) && !(parentIsFixed) ;
  fill->Enabled = !isForm && !(parentIsPacker) && !(parentIsFixed);
  padding->Enabled = !isForm && !(parentIsPacker) && !(parentIsFixed);
  tipButton->Enabled =  !isContainer && !isLabel && !isForm;
  tagButton->Enabled = !isForm;
  //  side->Enabled = parentIsPacker;
  // anchor->Enabled = parentIsPacker;
  // p_expand->Enabled = parentIsPacker;
  // fillx->Enabled = parentIsPacker;
  // filly->Enabled = parentIsPacker;
  // reconfigure->Enabled = parentIsPacker;
  colorButton->Enabled = !isContainer;
  restoreDefaultButton->Enabled = !isContainer;
  declarePublic->Enabled = !isForm; 
  /*
    call selected object to let it
    add his own widget here.
    All gui widgets should implement ExtraWidget(),
    otherwise an unuseful root class call will be made.
    (ExtraWidget is virtual on VDKBObject)
   */
  AddExtraWidget(active->ExtraWidget(this));
  // set title
  VDKObject* vdkobj = dynamic_cast<VDKObject*>(active);
  if(vdkobj)
    {
      VDKBGuiForm* ownerform = NULL;
      if(!isForm)
      ownerform = dynamic_cast<VDKBGuiForm*>(vdkobj->Owner());
      else
      ownerform = dynamic_cast<VDKBGuiForm*>(active);
      if(ownerform)
      {
        char name[128];
        strcpy(name,(char*) ownerform->Name());
        name[0] = toupper(name[0]);
        sprintf(buff,"%sForm->%s::%s",
              name,
              active->VDKName(),
              (char*) active->Name()
              );
        Title = buff;
        if(loadWidgetsTree)
          LoadTree(ownerform);
      }
    }

}

static char *colTitle = N_("Write or jump to response method");
static char *evcolTitle[] =
{
  N_("Jump to event handler"),
  N_("Connected")
};
/*
 */
VDKBox*
VDKBObjectInspector::MakeFormEventsPage()
{
  int t = 0;
  VDKString True = CHECK_TRUE;
  VDKBox* vbox = new VDKBox(this);
  evtable = new VDKCustomList(this,2,evcolTitle);
  evtable->AutoResize = true;
  evtable->ActiveTitle(1,false);
  evtable->Titles[0]->Enabled = false;
  VDKBGuiForm* owner_form =
      dynamic_cast<VDKBGuiForm*>(active);
  if(owner_form)
    {
      for(t=0;evTableItems[t].items[0];t++)
      {
        VDKString prop = owner_form->GetProp(evTableItems[t].items[0]);
        if(prop == True)
          evTableItems[t].items[1] = CHECK_YES;
        else
          evTableItems[t].items[1] = CHECK_NO;
      }
    } 
  for(t=0;evTableItems[t].items[0];t++)
    evtable->AddRow(evTableItems[t].items);
  vbox->Add(evtable);
  add_remove_event = new VDKCustomButton(this,_(wi_prompts[0]));
  vbox->Add(add_remove_event,l_justify,false,false,false);
  return vbox;
}
/*
 */
VDKBox*
VDKBObjectInspector::MakeSignalsPage()
{
  VDKBox* vbox = new VDKBox(this);
  const int rows = active->SignalList().size();
  const int cols = 2;
  int t,z = 0;
  // connecting table
  connectTable = new VDKTable(this,rows+2,cols);
  connectTable->ColSpacing = 1;
  connectTable->RowSpacing = 1;
  sigEntries = VDKArray<VDKEntry*>(rows);
  connectButtons = VDKArray<VDKCustomButton*>(rows);
  slots = VDKArray<int>(rows*2);
  VDKBSListIterator li(active->SignalList());

  connectTable->AddToCell(new VDKLabel(this,_(wi_prompts[31])),0,0);
  connectTable->AddToCell(new VDKLabel(this,_(wi_prompts[33])),0,1);
  connectTable->AddToCell(new VDKSeparator(this),1,0);
  connectTable->AddToCell(new VDKSeparator(this),1,1);
  for(t=0;li;li++,t++)
    {
      bool isContainer = dynamic_cast<VDKBEventContainer*>(active) != NULL;
      connectButtons[t] = new VDKCustomButton(this,li.current().Nickname()/*Signal()*/);
      sigEntries[t] = new VDKEntry(this,0,li.current().Slot());
      slots[z++] = SignalConnect(sigEntries[t],"activate",
                &VDKBObjectInspector::OnActivateSlotName);
      slots[z++] = SignalConnect(connectButtons[t],"clicked",
                &VDKBObjectInspector::OnConnectSignal);
      connectTable->AddToCell(connectButtons[t],t+2,0);
      connectTable->AddToCell(sigEntries[t],t+2,1);
      if(t==0 && isContainer)
      {
        connectButtons[t]->Enabled = false;
        sigEntries[t]->Enabled = false;
      }
    }
  vbox->Add(connectTable,l_justify,false,false,false);
  // make and load static signal table (a list)
  char* p = _(colTitle);
  sigtable = new VDKCustomList(this,1,&p,GTK_SELECTION_EXTENDED);
  sigtable->ActiveTitles(true);
  EventConnect(sigtable,"button_press_event",
             &VDKBObjectInspector:: OnSignalListButtonPress);
  // cast white background to override some gtk-themes defaults
  //sigtable->NormalBackground = clWhite;
  vbox->Add(sigtable);
  // make and load combo signal list
  VDKBox* hbox = new VDKBox(this,h_box);
  mul_connect = new VDKCustomButton(this,_(wi_prompts[34]));
  hbox->Add(mul_connect,l_justify,false,false,false);
  hbox->Add(sigcombo = new VDKCombo(this),l_justify,false,false,false);
  vbox->Add(hbox,l_justify,false,false,false);
  LoadStaticTable();
  return vbox;
}

///////////////////////////////////////////////
// WIDGET TREE
//////////////////////////////////////////////
extern char *mininewform_xpm[];
/// some pixmaps
/* XPM */
static char *container_xpm[] = {
"16 16 5 1",
". c #000000",
"# c #808000",
"a c #c0c000",
"b c #ffffc0",
"c c None",
/* pixels */
"ccccc..ccc.ccccc",
"ccc..bb...b..ccc",
"c..bb..#a..bb..c",
".bb..###aaa..bb.",
"...#####aaaaa...",
"c.b..###aaa...cc",
"c.bbb..#a..aa.cc",
"c.bbbbb..aaaa.cc",
"c.bbbbbbaaaaa.cc",
"c.bbbbbbaaaaa.cc",
"c.bbbbbbaaaaa.cc",
"c.bbbbbbaaaaa.cc",
"c.abbbbbaaaa..cc",
"cc..abbbaa..cccc",
"cccc..ab..cccccc",
"cccccc..cccccccc"
};
/* XPM */
static char *widget_xpm[]={
"16 16 14 1",
"# c #000000",
"c c #008000",
"d c #00c000",
"g c #008080",
"h c #00c0c0",
"f c #00ffff",
"k c #808000",
"l c #c0c000",
"j c #ffff00",
"a c #c0ffc0",
"e c #c0ffff",
"i c #ffffc0",
"b c #00ff00",
". c None",
".....##.........",
"....#aa##.......",
"...#aaabb#......",
"..#bbbbbc###....",
"..#ddbbcc#ee##..",
"..#dddcc#eeeff#.",
"..#dddc#fffffg#.",
"...###c#hhffgg#.",
"...#ii##hhhggg#.",
"..#iiijj#hhgg#..",
".#jjjjjk##hg#...",
".#lljjkk#.##....",
".#lllkkk#.......",
".#lllkk#........",
"..##lk#.........",
"....##.........."};

#include "./pixmaps/cut.xpm"
#include "./pixmaps/copy.xpm"
#include "./pixmaps/paste.xpm"
#include "./pixmaps/paste_others.xpm"
extern VDKBWidgetClipboard* WidgetClipboard;

bool
VDKBObjectInspector::OnToolbarClicked(VDKObject* sender)
{
  gpointer gp = NULL;
  VDKBObject* selected_object = NULL;
  int button = treeToolbar->ButtonPressed;
  VDKTreeNode node = WidgetsTree->SelectedNode;
  // dock/undock request
  if(button == 4)
    {
      dockerbox->Docked = dockerbox->Docked ? false : true;
      return true;
    }

  if(! node)
    return true;
  else
    {
      // retrieve widget address stored by LoadTree()
      gp =
      gtk_ctree_node_get_row_data(GTK_CTREE(WidgetsTree->CustomWidget()),
                            node);
      // cast it to a VDKBObject
      selected_object = reinterpret_cast<VDKBObject*> (gp);
    }
  if(!selected_object)
    return true;

  switch(button)
    {
    case 0:// cut
      WidgetClipboard->CutWidget(selected_object->ObjectFromVDK());
      break;
    case 1:// copy
      WidgetClipboard->CopyWidget(selected_object->ObjectFromVDK());
      break;
    case 2:// paste
        WidgetClipboard->PasteWidget(selected_object->ObjectFromVDK(),0);
      break;
    case 3:// paste others
      PasteOthers(selected_object);
      break;
    }
  return true;
}
/*
paste others widgets on stack.
An empty array is passed to dialog,
it returns the array filled with widget
to be pasted, or an empty array id user
press cancel button.
 */
void
VDKBObjectInspector::PasteOthers(VDKBObject* selected_object)
{
  VDKBWidgetClipboardArray cliparray;
  VDKBWidgetClipboardDialog* child =
    new VDKBWidgetClipboardDialog(this,&cliparray, NULL);
  child->Setup();
  child->ShowModal(GTK_WIN_POS_MOUSE);
  if(cliparray.size() > 0)
    {
      if(cliparray.size() == 1)
      {
        VDKBWidgetClipboardItem item = cliparray[0];
        // finds widget ordinal position
        // into clipboard
        int ndx = WidgetClipboard->at(item);
        if(ndx >= 0)
          // paste widget resetting WI
          WidgetClipboard->PasteWidget(selected_object->ObjectFromVDK(),ndx, true);
      }
      else
      {
        int z = 0;
        for(; z < cliparray.size(); z++)
          {
            VDKBWidgetClipboardItem item = cliparray[z];
            int ndx = WidgetClipboard->at(item);
            // finds widget ordinal position
            // into clipboard
            if(ndx >= 0)
            // reset WI only on last item
            WidgetClipboard->PasteWidget(selected_object->ObjectFromVDK(),
                                   ndx,
                                   z < (cliparray.size()-1) ?
                                   false: true);
          }
      }
    }
}

/*
 */
void
VDKBObjectInspector::OnTreeMove (GtkCTree *wid,
             GtkCTreeNode *child,
             GtkCTreeNode *parent,
             GtkCTreeNode *sibling,
             gpointer data)
{
  gpointer gp;
  VDKBObject* source,*target,*sibling_target;
  g_return_if_fail(wid != NULL);
  g_return_if_fail(data != NULL);
  VDKCustomTree* tree = reinterpret_cast<VDKCustomTree*>(data);
  gp =  gtk_ctree_node_get_row_data(GTK_CTREE(tree->CustomWidget()),
                            child);
  source = reinterpret_cast<VDKBObject*> (gp);
  gp = gtk_ctree_node_get_row_data(GTK_CTREE(tree->CustomWidget()),
                            parent);
  target = reinterpret_cast<VDKBObject*> (gp);
  if(sibling)
    {
      gp = gtk_ctree_node_get_row_data(GTK_CTREE(tree->CustomWidget()),
                               sibling);
      sibling_target = reinterpret_cast<VDKBObject*> (gp);
    }
  else
    sibling_target = NULL;
  gtk_signal_emit_stop_by_name(GTK_OBJECT(wid),"tree_move");
  if(!source || !target)
      return;

  if(activeOwner)
    {
      // cut source and paste it to target
      WidgetClipboard->CutWidget(source->ObjectFromVDK());
      // set target or sibling as active
      if(sibling_target && dynamic_cast<VDKBEventContainer*>(sibling_target))
      activeOwner->Active = sibling_target;
      else
      activeOwner->Active = target;
      WidgetClipboard->PasteWidget(target->ObjectFromVDK(),0);
      // reload tree
      tree->SignalEmit(click_column_signal);
    }

}

/*
 */
VDKBox*
VDKBObjectInspector::MakeWidgetsTreePage()
{
  char * title = _("Refresh widgets tree");
  VDKBox* box = new VDKBox(this);
  // treeToolbar = new VDKToolbar(this);
  treeToolbar = new VDKHLButtonBar(this,h_box,shadow_etched_in);
  treeToolbar->AddButton((const char**)cut_xpm,_(popmenu_prompts[0]));
  treeToolbar->AddButton((const char**)copy_xpm,_(popmenu_prompts[1]));
  treeToolbar->AddButton((const char**)paste_xpm,_(popmenu_prompts[2]));
  treeToolbar->AddButton((const char**)paste_others_xpm,_(popmenu_prompts[3]));
  treeToolbar->AddButton((const char**)dock_xpm,_("docks/undocks properties & signals"));

  box->Add(treeToolbar,l_justify,false,false,0);
  SignalConnect(treeToolbar,"clicked",&VDKBObjectInspector::OnToolbarClicked,false);

  BList* widlist = treeToolbar->ButtonList();
  for(int t = 0; t < widlist->size()-1; t++)
    (*treeToolbar)[t]->Enabled = false;

  WidgetsTree  = new VDKCustomTree(this,1,&title);
  WidgetsTree->SetSize(200,150);
  WidgetsTree->AutoResize = true;
  gtk_clist_set_reorderable (GTK_CLIST(WidgetsTree->CustomWidget()),
                       true);
  // cast white background to override some gtk-themes defaults
  // WidgetsTree->NormalBackground = clWhite;
  box->Add(WidgetsTree);
  gtk_signal_connect (GTK_OBJECT (WidgetsTree->CustomWidget()),
                  "tree_move",
                  GTK_SIGNAL_FUNC(VDKBObjectInspector::OnTreeMove),
                  (gpointer) WidgetsTree);
  EventConnect(WidgetsTree,"button_press_event",
             &VDKBObjectInspector::OnWidgetsTreeButtonPress);
  treepopmenu = new VDKMenu(this);
  // FIX ME: lang support
  VDKMenuItem *nop = new VDKMenuItem(treepopmenu,"Nop");
  nop->Enabled = false;
  dropwidget = new VDKMenuItem(treepopmenu,_(popmenu_prompts[4]));
  SignalConnect(dropwidget,"activate",
            &VDKBObjectInspector::DropWidget);
  /*
    better explicitely add it to owner, so will be surely
    destroyed even if never popped
  */
  AddItem(treepopmenu);
  return box;
}

/*
 */
void
RecursiveLoadTree( EventBoxList& list,
               VDKCustomTree* tree,
               VDKTreeNode root)
{
  char *objname;
  if(list.size() == 0)
    return;
  // iterates on boxes
  EventBoxListIterator li(list);
  for(;li;li++)
    {
      bool hasChilds = false;
      VDKTreeNode child = NULL;
      VDKBEventContainer* box = NULL;
      VDKBMenuItem* mi = NULL;
      VDKObject* object = li.current();
      VDKBObject* vdkobj = dynamic_cast<VDKBObject*>(object);
      if(vdkobj)
      {
        box = dynamic_cast<VDKBEventContainer*>(vdkobj);
        if(!box)
          mi = dynamic_cast<VDKBMenuItem*>(vdkobj);
        if(box)
          hasChilds = box->boxlist.size() > 0;
        else if(mi)
          hasChilds = mi->boxlist.size() > 0;
      }
      // gui widgets inner canvases must be neglected
       if(vdkobj && vdkobj->isA() != vdkbcanvas_class)
       {
         objname = (char*) vdkobj->Name();
         child = tree->AddNode(&objname,
                               root,
                               hasChilds ? true : false,
                               hasChilds ? false : true,
                               box ? container_xpm : widget_xpm,
                               box ? container_xpm : widget_xpm);
         if(child)
           gtk_ctree_node_set_row_data(GTK_CTREE(tree->CustomWidget()),
                               child,
                               (gpointer) vdkobj);
       }
       // recurs on inner boxes or menu items (if any)
       if(vdkobj && box && hasChilds)
       {
         VDKBEventContainer* box = (VDKBEventContainer*) vdkobj;
         RecursiveLoadTree(box->boxlist,tree,child);
       }
       else if(vdkobj && mi && hasChilds)
       RecursiveLoadTree(mi->boxlist,tree,child);
       else  if(vdkobj && dynamic_cast<VDKBMenuItem*>(vdkobj))
       {
         VDKBMenuItem* item = (VDKBMenuItem*) vdkobj;
         if(item)
           RecursiveLoadTree(item->boxlist,tree,child);
       }
    }
}
/*
 */
void
VDKBObjectInspector::LoadTree(VDKBGuiForm* owner)
{
  char *objname, *formname;
  char  name[128];
  strcpy(name,(char*) owner->Name());
  name[0] = toupper(name[0]);
  formname = name;
  // set static activeOwner
  activeOwner = owner;
  WidgetsTree->Clear();
  WidgetsTree->Freeze();
  VDKTreeNode root = WidgetsTree->AddNode(&formname,
      NULL,
      owner->InnerBox()->boxlist.size() > 0 ? true : false,
      owner->InnerBox()->boxlist.size() > 0 ? false : true,
      mininewform_xpm,
      mininewform_xpm);
  if(root)
    gtk_ctree_node_set_row_data(GTK_CTREE(WidgetsTree->CustomWidget()),
                        root,
                        (gpointer) NULL);
  EventBoxListIterator li(owner->InnerBox()->boxlist);
  for(;li;li++)
    {
      bool hasChilds = false;
      VDKTreeNode child = NULL;
      VDKBEventContainer* box = NULL;
      VDKBMenuItem* mi = NULL;
      VDKObject* object = li.current();
      VDKBObject* vdkobj = dynamic_cast<VDKBObject*>(object);
      if(vdkobj)
      {
        box = dynamic_cast<VDKBEventContainer*>(vdkobj);
        if(!box)
          mi = dynamic_cast<VDKBMenuItem*>(vdkobj);
        if(box)
          hasChilds = box->boxlist.size() > 0;
        else if(mi)
          hasChilds = mi->boxlist.size() > 0;
      }
      if(vdkobj && vdkobj->isA() != vdkbcanvas_class)
      {
        objname = (char*) vdkobj->Name();
        child = WidgetsTree->AddNode(&objname,
                               root,
                               hasChilds ? true : false,
                               hasChilds ? false : true,
                               box ? container_xpm : widget_xpm,
                               box ? container_xpm : widget_xpm);
        if(child)
          gtk_ctree_node_set_row_data(GTK_CTREE(WidgetsTree->CustomWidget()),
                              child,
                              (gpointer) vdkobj);
      }
      if(box && hasChilds)
      RecursiveLoadTree(box->boxlist,WidgetsTree,child);
      else if(mi && hasChilds)
      RecursiveLoadTree(mi->boxlist,WidgetsTree,child);
    }
  WidgetsTree->Thaw();
}

////////////////////////////////////////////////////////////////////////
/*
 * GtkFontSelection
 */

void
font_selection_ok (GtkWidget *w,
               GtkFontSelectionDialog *fs)
{
  selected_font = gtk_font_selection_dialog_get_font_name (fs);
  gtk_widget_destroy (GTK_WIDGET (fs));
  /* This is needed to get out of gtk_main */
  gtk_main_quit ();

}
/*
 */
void
font_selection_cancel (GtkWidget *w,
               GtkFontSelectionDialog *fs)
{
  selected_font = NULL;
  gtk_widget_destroy (GTK_WIDGET (fs));
  gtk_main_quit ();
}
void
create_font_selection (void)
{
  GtkWidget *window = NULL;
  window = gtk_font_selection_dialog_new (_("Font Selection Dialog"));
  //  gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
  gtk_signal_connect (GTK_OBJECT (window), "destroy",
                  GTK_SIGNAL_FUNC(gtk_widget_destroyed),
                  &window);
  gtk_signal_connect (
                  GTK_OBJECT (GTK_FONT_SELECTION_DIALOG
                          (window)->ok_button),"clicked",
                  GTK_SIGNAL_FUNC(font_selection_ok),
                  GTK_FONT_SELECTION_DIALOG (window)
                  );
  gtk_signal_connect (
                  GTK_OBJECT (GTK_FONT_SELECTION_DIALOG
                          (window)->cancel_button),"clicked",
                  GTK_SIGNAL_FUNC(font_selection_cancel),
                  GTK_FONT_SELECTION_DIALOG (window)
                  );
  /* Set window as modal */
  gtk_window_set_modal (GTK_WINDOW(window),TRUE);
  if(window)
    gtk_widget_show (window);
    /* wait until dialog get destroyed */
  gtk_main();
}



Generated by  Doxygen 1.6.0   Back to index