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

EntityHandler.cpp

#include <algorithm>

#include "mudclient.h"


#include <gmodule.h>


#define ENTITY_HANDLER_C
#include "EntityHandler.h"

#include "AliasEntity.h"
#include "TriggerEntity.h"

extern EntityHandler * entities;

EntityHandler::EntityHandler() {

  tree_model = NULL;
  selection = NULL;

  entity_widget = NULL;
  xml = NULL;
}

EntityHandler::~EntityHandler() {
}

static int GroupCmp(EntityGroup * e1, EntityGroup * e2) {
  return (e1 < e2);
}

void EntityHandler::addEntity(char * group, Entity * e) {
  EntityGroup * eg = findGroup(group, true);
  eg->addEntity(e);
}

void EntityHandler::removeEntity(Entity * e) {
  for (GroupList::iterator i = groups.begin(); i != groups.end(); i++) {
    if ((*i)->removeEntity(e))
      return;
  }
}

void EntityHandler::removeEntityGroup(EntityGroup * e) {
  GroupList::iterator i = std::lower_bound(groups.begin(),
                                 groups.end(),
                                 e,
                                 GroupCmp);

  if (i == groups.end() || (*i) != e)
    return;

  groups.erase(i);
}

EntityGroup * EntityHandler::findGroup(char * in_name, bool create) {

  for (GroupList::iterator i = groups.begin(); i != groups.end(); i++) {
    if (!strcmp((*i)->getName(), in_name))
      return (*i);
  }

  if (!create)
    return NULL;

  EntityGroup * eg = new EntityGroup();
  eg->setName(in_name);
  eg->setDescription(_("Dummy description."));
  addGroup(eg);
  return eg;
}

void EntityHandler::addGroup(EntityGroup * e) {
  GroupList::iterator i = std::lower_bound(groups.begin(),
                                  groups.end(),
                                  e,
                                  GroupCmp);
  groups.insert(i, e);
}

void EntityHandler::moveGroup(Entity * e, char * group) {

  EntityGroup * new_group = findGroup(group, false);
  EntityGroup * old_group = NULL;
  
  for (GroupList::iterator i = groups.begin(); i != groups.end(); ++i) {
    if ((*i)->contains(e)) {
      old_group = *i;
      break;
    }
  }
 
  if (new_group == old_group)
    return;

  old_group->removeEntity(e);
  new_group->addEntity(e);
}

void EntityHandler::removeGroup(EntityGroup * e) {
  GroupList::iterator i = std::lower_bound(groups.begin(),
                                  groups.end(),
                                  e,
                                  GroupCmp);
  if (i == groups.end() || (*i) != e)
    return;

  groups.erase(i);
}

void EntityHandler::findExecute(EntityType type, char * field, char * value, void * data, bool multiple) {
  for (GroupList::iterator i = groups.begin(); i != groups.end(); i++)
    if ((*i)->findExecute(type, field, value, data, multiple) && !multiple)
      return;
}

void EntityHandler::load() {
  FILE * fp;

  fp = openFile("entities.dat", NULL, "r");
  if (!fp)
    return;

  load(fp);
}

void EntityHandler::importEntities(char * filename) {
  FILE * fp;

  fp = fopen(filename, "r");
  if (!fp) {
    g_warning(_("Could not open %s for reading."), filename);
    return;
  }

  load(fp);
  fclose(fp);
  update();
}

void EntityHandler::load(FILE * fp) {
  char buf[16384];

  while (true) {
    if (!fgets(buf, 16384, fp)) {
      if (!feof(fp))
      perror("fgets");
      fclose(fp);
      return;
    }

    if (!strncasecmp(buf, "EntityGroup", 11)) {
      char name[16384];
      if (sscanf(buf, "EntityGroup %[^\n]\n", name) != 1) {
      perror("sscanf");
      fclose(fp);
      return;
      }

      EntityGroup * tmp = new EntityGroup();
      if (!tmp->load(fp, name)) {
      delete tmp;
      return;
      }

      addGroup(tmp);
      continue;
    }

    return;
  }

  xml = NULL;

}

void EntityHandler::save() {
  FILE * fp;

  fp = openFile("entities.dat", NULL, "w");
  if (!fp) {
    perror(_("Cannot save entities.dat"));
    return;
  }

  for (GroupList::iterator i = groups.begin(); i != groups.end(); i++)
    (*i)->save(fp);

  fclose(fp);
}

void EntityHandler::exportEntities(char * output) {
  FILE * fp;
  
  fp = fopen(output, "w");
  if (!fp) {
    g_warning(_("Could not export aliases and triggers."));
    return;
  }

  // Need to get the list of selected entities.

  // selection
  GList * list = getSelectedEntities();

  for (GroupList::iterator i = groups.begin(); i != groups.end(); i++)
    (*i)->exportEntities(fp, list);

  // Free up the tosave list - Don't free the contents
  g_list_free(list);
  fclose(fp);
}

extern "C" G_MODULE_EXPORT gint on_entity_handler_delete_event(GtkWidget * window, GdkEvent * event, gpointer data) {
    entities->close();
      return 1;
}

extern "C" G_MODULE_EXPORT gint on_apply_button_clicked(GtkWidget * button, gpointer data) {
  Entity * e = entities->getSelectedEntity();
  entities->apply();

  entities->update();
  if (e)
    entities->selectEntity(e);

  return 1;
}

extern "C" G_MODULE_EXPORT gint on_ok_button_clicked(GtkWidget * button, gpointer data) {
  entities->apply();
  entities->close();
  return 1;
}

extern "C" G_MODULE_EXPORT gint on_cancel_button_clicked(GtkWidget * button, gpointer data) {
  entities->close();
  return 1;
}

void EntityHandler::close() {

  // Remove the entity widget from the vbox.
  if (entity_widget) {
    GtkWidget * vbox = glade_xml_get_widget(xml, "entity_widget_vbox");
    gtk_widget_ref(entity_widget);
    gtk_container_remove(GTK_CONTAINER(vbox), entity_widget);
    entity_widget = NULL;
  }

  // Cause all the plugins to destroy their widgets.
  for (GroupList::iterator i = groups.begin(); i != groups.end(); i++) {
    (*i)->destroyWidgets();
  }

  GtkWidget * window = glade_xml_get_widget(xml, "aliases_window");
  gtk_widget_hide(window);
  gtk_widget_destroy(window);

  if (xml) {
    g_object_unref(xml);
    xml = NULL;
  }
}

void EntityHandler::apply() {
  for (GroupList::iterator i = groups.begin(); i != groups.end(); i++) {
    (*i)->apply();
  }
  save();
}


void display_entity(GtkTreeModel * model, GtkTreePath * path, GtkTreeIter  * iter, gpointer user_data) {

  // Can we figure out the name of the item at iter?

  GValue value;
  gtk_tree_model_get_value(model, iter, 0, &value);

  g_value_unset(&value);
  

}

void tree_view_row_activated(GtkTreeSelection * selection, gpointer user_data) {
  entities->row_selected(selection, user_data);
}

void EntityHandler::row_selected (GtkTreeSelection *selection,
                          gpointer          data) {
  int id = getSelectedID();

  GtkWidget * vbox = glade_xml_get_widget(xml, "entity_widget_vbox");

  if (id >= 0) {
    Entity * e = findByID(id);
    if (!e) {
      printf ("FIXME: Entity in list selected, but not found!\n");
      return;
    }

    if (entity_widget) {
      gtk_widget_ref(entity_widget);
      gtk_container_remove(GTK_CONTAINER(vbox), entity_widget);
      entity_widget = NULL;
    }
    entity_widget = e->getWidgets();
    gtk_box_pack_start(GTK_BOX(vbox), entity_widget, TRUE, TRUE, 0);
    gtk_widget_unref(entity_widget);
    gtk_widget_show(entity_widget);
  } else {    
    if (entity_widget) {
      gtk_widget_ref(entity_widget);
      gtk_container_remove(GTK_CONTAINER(vbox), entity_widget);
      entity_widget = NULL;
    }
  }
}

extern "C" G_MODULE_EXPORT gint on_new_group_button_activate(GtkWidget * widget, gpointer data) {

  char buf[1024];

  EntityGroup * eg = new EntityGroup();

  int i;
  for (i = 0; i < 100; i++) {
    snprintf(buf, 1024, "Group %d", i);
    if (!entities->findGroup(buf, false)) {
      eg->setName(buf);
      break;
    }
  }

  if (i == 100) {
    printf ("FIXME: 100 dummy entity groups are insufficient.\n");
    return 1;
  }

  entities->addGroup(eg);

  // Update the tree and ensure this is the selected item.
  entities->update();

  entities->selectEntity(eg);
  return 1;
}

gboolean select_by_id(GtkTreeModel * tree_model, GtkTreePath * path, GtkTreeIter * iter, gpointer data) {
  entities->selectByID(iter, data);
  return false;
}

void EntityHandler::selectByID(GtkTreeIter * iter, gpointer data) {
  int id = *(int *)data;
  char * id_buf;

  gtk_tree_model_get(GTK_TREE_MODEL(tree_model), iter, 1, &id_buf, -1);

  if (atoi(id_buf) == id) {
    gtk_tree_selection_select_iter(selection, iter);
  }

  g_free(id_buf);
}

void EntityHandler::selectEntity(Entity * e) {
  int id = e->getID();
  gtk_tree_model_foreach(GTK_TREE_MODEL(tree_model), select_by_id, (gpointer)&id);
}

void EntityHandler::newAlias() {

  GroupList::iterator i = groups.begin();
  if (!(*i)) {
    new Message("Error", _("You need to create a group first."), true);
    return;
  }

  EntityGroup * group = getSelectedGroup();
  if (!group) {
    new Message("Error", _("Please select only the group you wish the alias to be entered into and then choose 'New Alias'"), true);
    return;
  }

  AliasEntity * a = new AliasEntity();
  a->setName(_("EDIT ME"));
  addEntity(group->getName(), a);
  a->setCommand(_("EDIT ME"));

  update();

  selectEntity(a);
}

void EntityHandler::newTrigger() {
  GroupList::iterator i = groups.begin();
  if (!(*i)) {
    new Message("Error", _("You need to create a group first."), true);
    return;
  }

  EntityGroup * group = getSelectedGroup();
  if (!group) {
    new Message("Error", _("Please select only the group you wish the trigger to be entered into and then choose 'New Trigger'"), true);
    return;
  }

  TriggerEntity * t = new TriggerEntity();
  
  t->setName(_("EDIT ME"));
  addEntity(group->getName(), t);
  t->setText(_("EDIT ME"));
  update();

  selectEntity(t);
}

extern "C" G_MODULE_EXPORT gint on_new_alias_button_activate(GtkWidget * widget, gpointer data) {
  entities->newAlias();
  return 1;
}

extern "C" G_MODULE_EXPORT gint on_new_trigger_button_activate(GtkWidget * widget, gpointer data) {
  entities->newTrigger();
  return 1;
}

extern "C" G_MODULE_EXPORT gint on_delete_button_activate(GtkWidget * widget, gpointer data) {
  entities->deleteSelected();
  return 1;
}

extern "C" G_MODULE_EXPORT gint on_export_button_activate(GtkWidget * widget, gpointer data) {
  entities->exportSelected();
  return 1;
}

extern "C" G_MODULE_EXPORT gint on_import_button_activate(GtkWidget * widget, gpointer data) {
  entities->importSelected();
  return 1;
}

void entity_handler_export(GtkFileSelection * selector, gpointer data) {
  const gchar * filename;
  filename = gtk_file_selection_get_filename(GTK_FILE_SELECTION(data));
  entities->exportEntities((char *)filename);
}

void entity_handler_import(GtkFileSelection * selector, gpointer data) {
  const gchar * filename;
  filename = gtk_file_selection_get_filename(GTK_FILE_SELECTION(data));
  entities->importEntities((char *)filename);
}

void EntityHandler::exportSelected() {
  GtkWidget * exportFileSelection = gtk_file_selection_new("Please select an entity data file for exporting.");
  g_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (exportFileSelection)->ok_button),
                "clicked",
                G_CALLBACK (entity_handler_export),
                exportFileSelection);
  
  g_signal_connect_swapped (GTK_OBJECT (GTK_FILE_SELECTION (exportFileSelection)->ok_button),
                      "clicked",
                      G_CALLBACK (gtk_widget_destroy), 
                      (gpointer) exportFileSelection); 
  
  g_signal_connect_swapped (GTK_OBJECT (GTK_FILE_SELECTION (exportFileSelection)->cancel_button),
                      "clicked",
                      G_CALLBACK (gtk_widget_destroy),
                      (gpointer) exportFileSelection); 

  gtk_widget_show (exportFileSelection);

}

void EntityHandler::importSelected() {
  GtkWidget * importFileSelection = gtk_file_selection_new("Please select an entity data file for importing.");
  g_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (importFileSelection)->ok_button),
                "clicked",
                G_CALLBACK (entity_handler_import),
                importFileSelection);
  
  g_signal_connect_swapped (GTK_OBJECT (GTK_FILE_SELECTION (importFileSelection)->ok_button),
                      "clicked",
                      G_CALLBACK (gtk_widget_destroy), 
                      (gpointer) importFileSelection); 
  
  g_signal_connect_swapped (GTK_OBJECT (GTK_FILE_SELECTION (importFileSelection)->cancel_button),
                      "clicked",
                      G_CALLBACK (gtk_widget_destroy),
                      (gpointer) importFileSelection); 

  gtk_widget_show (importFileSelection);
}

// Returns the first selected entity
Entity * EntityHandler::getSelectedEntity() {

  GList * list = getSelectedEntities();
  if (g_list_length(list) > 0) {
    Entity * e = (Entity *)g_list_nth_data(list, 0);
    g_list_free(list);
    return e;
  }

  g_list_free(list);
  return NULL;
}

static void get_selected_rows(GtkTreeModel * model, GtkTreePath * path, GtkTreeIter * iter, gpointer data) {
  GList ** list = (GList **)data;
  *list = g_list_append(*list, gtk_tree_path_copy(path));
}

GList * EntityHandler::getSelectedEntities() {
  GtkTreeModel * model = GTK_TREE_MODEL(tree_model);
  GList * selected = NULL;

  gtk_tree_selection_selected_foreach(selection, get_selected_rows, &selected);
  
  // GTK 2.2 function.
  //  GList * selected = gtk_tree_selection_get_selected_rows(selection, &model);
  
  GList * tosave = NULL;
  GtkTreeIter iter;
  for (int i = 0; i < g_list_length(selected); i++) {
    GtkTreePath * path = (GtkTreePath *)g_list_nth_data(selected, i);
    gtk_tree_model_get_iter(GTK_TREE_MODEL(tree_model), &iter, path);
    
    int id;
    gchar * id_buf;
    
    gtk_tree_model_get(GTK_TREE_MODEL(tree_model), &iter, 1, &id_buf, -1);
    id = atoi(id_buf);
    g_free(id_buf);

    Entity * e = findByID(id);
    if (e) {
      // Add this entity to the entities glist.
      tosave = g_list_append(tosave, e);
    }

  }

  // Free the returned list.
  //  g_list_foreach (selected, gtk_tree_path_free, NULL);
  g_list_free (selected);

  return tosave;
}

EntityGroup * EntityHandler::getSelectedGroup() {

  GList * list = getSelectedEntities();
  if (g_list_length(list) == 1) {
    Entity * e = (Entity *)g_list_nth_data(list, 0);
    g_list_free(list);
    if (e && e->getType() == EntityGroupGroup)
      return (EntityGroup *)e;
    return NULL;
  }

  g_list_free(list);
  return NULL;
}

void EntityHandler::deleteSelected() {

  GList * list = getSelectedEntities();
  for (int i = g_list_length(list) - 1; i >= 0; i--) {
    Entity * e = (Entity *)g_list_nth_data(list, i);
    deleteEntity(e);
  }

  g_list_free(list);

  // Now remove whatever entity_widget was being displayed as it's almost
  // certainly out of date.
  GtkWidget * vbox = glade_xml_get_widget(xml, "entity_widget_vbox");
  if (entity_widget) {
    gtk_container_remove(GTK_CONTAINER(vbox), entity_widget);
    entity_widget = NULL;
  }

}

void EntityHandler::deleteEntity(Entity * e) {

  
  int count = 0;
  switch (e->getType()) {
  case EntityGroupGroup:
    count = ((EntityGroup *)e)->count();
    if (count) {
      new Message("Error", _("A group must be empty before it can be deleted.  The selected group was not empty."), true);
      return;
    }

    removeEntityGroup((EntityGroup *)e);
    break;
    
  default:
    removeEntity(e);
    break;
    
  case EntitySystemTrigger:
    new Message("Error", _("This System Trigger is in use by a plugin or Papaya and may not be deleted."), true);
    break;
    
  }

  update();
}

int EntityHandler::getSelectedID() {
  GList * list = getSelectedEntities();
  if (g_list_length(list) > 0) {
    Entity * e = (Entity *)g_list_nth_data(list, 0);
    g_list_free(list);
    return e->getID();
  }

  g_list_free(list);
  return -1;
}

void EntityHandler::update() {
  populate_tree_model(tree_model);
  GtkWidget * tree_view = glade_xml_get_widget(xml, "treeview");
  gtk_tree_view_expand_all(GTK_TREE_VIEW(tree_view));
}

void EntityHandler::edit() {

  if (xml) { // Entity edit already open, raise it
    gtk_window_present((GtkWindow *)glade_xml_get_widget(xml, "aliases_window"));
    return;
  }

  char buf[1024];

  snprintf(buf, 1024, "%s/share/papaya/aliasesandtriggers.glade", getPrefix());
  xml = glade_xml_new(buf, NULL, NULL);
  if (!xml) {
    printf (_("Unable to load %s to create aliases and triggers dialog.\n"), buf);
    return;
  }

  glade_xml_signal_autoconnect(xml);

  GtkWidget * vbox = glade_xml_get_widget(xml, "entity_widget_vbox");
  GtkWidget * tree_view = glade_xml_get_widget(xml, "treeview");

  GtkCellRenderer * tree_renderer;
  GtkTreeViewColumn * tree_column, *tree_data_column;

  // Create the tree model and configure the view with it.
  tree_model = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
  gtk_tree_view_set_model(GTK_TREE_VIEW(tree_view), GTK_TREE_MODEL(tree_model));
  g_object_unref(tree_model);

  tree_renderer = gtk_cell_renderer_text_new();
  tree_column = gtk_tree_view_column_new_with_attributes(_("Triggers and Aliases"),
                                        tree_renderer,
                                        "text", 0,
                                        NULL);

  gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), tree_column);

  tree_data_column = gtk_tree_view_column_new();
  gtk_tree_view_column_set_visible(tree_data_column, false);

  gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), tree_data_column);

  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view));

  g_signal_connect_data(G_OBJECT(selection), "changed",
                  GTK_SIGNAL_FUNC(tree_view_row_activated),
                  this, NULL, (GConnectFlags) 0);

  gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);

  entity_widget = NULL;

  update();
}

void EntityHandler::populate_tree_model(GtkTreeStore * model) {

  gtk_tree_store_clear(model);

  for (GroupList::iterator i = groups.begin(); i != groups.end(); i++) {
    GtkTreeIter iter;
    char id_buf[1024];

      EntityGroup * eg = (EntityGroup *)(*i);

    

      gtk_tree_store_insert(GTK_TREE_STORE(model),
                    &iter,
                    NULL,
                    0);


    snprintf(id_buf, 1024, "%d", (*i)->getID());

    gtk_tree_store_set(GTK_TREE_STORE(model), &iter,
                   0, (*i)->getName(), 1, id_buf, -1);

    (*i)->populate_tree_model(model, &iter);
  }

}

Entity * EntityHandler::findByID(int id) {

  for (GroupList::iterator i = groups.begin(); i != groups.end(); i++) {
    if ((*i)->getID() == id)
      return (*i);
    Entity * e = (*i)->findByID(id);
    if (e)
      return e;
  }

  return NULL;
}

EntityGroup * EntityHandler::getEntityGroupForEntity(Entity * e) {
  for (GroupList::iterator i = groups.begin(); i != groups.end(); i++) {
    if ((*i)->contains(e))
      return (*i);
  }
  return NULL;
}

GList * EntityHandler::getGroupOptionMenuList() {
  GList * list = NULL;
  for (GroupList::iterator i = groups.begin(); i != groups.end(); ++i) {
    list = g_list_append(list, (*i)->getName());
  }

  return list;
}

GtkWidget * EntityHandler::getGroupOptionMenu(Entity * e) {

  GtkWidget * option_menu;
  GtkWidget * menu;
  GtkWidget * item;
  int count = 0;
  int selected_item = 0;

  option_menu = gtk_option_menu_new();
  gtk_widget_ref(option_menu);
  menu = gtk_menu_new();
  gtk_widget_ref(menu);

  EntityGroup * eg = getEntityGroupForEntity(e);

  for (GroupList::iterator i = groups.begin(); i != groups.end(); ++i) {
    item = gtk_menu_item_new_with_label((*i)->getName());
    gtk_widget_ref(item);
    gtk_widget_show(item);
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);

    if ((*i) == eg)
      selected_item = count;

    count++;
  }

  gtk_option_menu_set_menu(GTK_OPTION_MENU(option_menu), menu);
  gtk_option_menu_set_history(GTK_OPTION_MENU(option_menu), selected_item);

  return option_menu;
}

Generated by  Doxygen 1.6.0   Back to index