/* Copyright (C) 2000,2001,2002 Manuel Amador (Rudd-O) This file is part of Directory administrator. Directory administrator 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.1 of the License, or (at your option) any later version. Directory administrator 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 General Public License for more details. You should have received a copy of the GNU General Public License along with Directory administrator; if not, send e-mail to amador@alomega.com */ #include #include "appglobals.h" #include "appfunctions.h" #include "appsupport.h" #include "profile.h" #include "usergrouplists.h" #include "dir_entry.h" #include "charset.h" #include guint32 objectview_last_keypress = 0; gchar* typeaheadcontents = NULL; //return false if you want the keypress to be processed, true to kill it before it reaches the UI gboolean objectview_keypress (GdkEventKey* event) { guint32 delta; gchar*tmp; GtkWidget * delbutton; unsigned char letter; int key; // GtkWidget * temp; GtkWidget * objectview, *scrolledwindow; gboolean processed = FALSE; GtkWindow * b = (GtkWindow*)app; letter=event->string[0]; key = event->keyval; objectview = lookup_widget(app,"itemlist"); scrolledwindow= lookup_widget(app,"itemlistscrolledwindow"); g_print("Processing keypress %d in main window\n",event->keyval); if (b->focus_widget == NULL) gtk_widget_grab_focus(scrolledwindow); g_print("Focused widget name: %s\n",gtk_widget_get_name(b->focus_widget)); // convenience functions for keypresses in filter items if (event->keyval == 65293 || event->keyval == 65421) { if (GTK_WIDGET_HAS_FOCUS(lookup_widget(app,"filter"))){ processed = TRUE; delbutton = lookup_widget (GTK_WIDGET (app),"filterbutton"); if (GTK_WIDGET_SENSITIVE (delbutton)) { gtk_signal_emit_by_name (GTK_OBJECT (delbutton),"clicked"); gtk_widget_grab_focus(lookup_widget(app,"filter")); } } if (GTK_WIDGET_HAS_FOCUS(lookup_widget(app,"filterbutton"))){ processed = TRUE; delbutton = lookup_widget (GTK_WIDGET (app),"filterbutton"); if (GTK_WIDGET_SENSITIVE (delbutton)) { gtk_signal_emit_by_name (GTK_OBJECT (delbutton),"clicked"); gtk_widget_grab_focus(lookup_widget(app,"filter")); } } if (GTK_WIDGET_HAS_FOCUS(lookup_widget(app,"filterclear"))){ processed = TRUE; delbutton = lookup_widget (GTK_WIDGET (app),"filterclear"); if (GTK_WIDGET_SENSITIVE (delbutton)) { gtk_signal_emit_by_name (GTK_OBJECT (delbutton),"clicked"); gtk_widget_grab_focus(lookup_widget(app,"filter")); } } } // if NOT icon list has focus... return, do not process anything further if ( GTK_WIDGET_HAS_FOCUS(lookup_widget(app,"filtertype")) || GTK_WIDGET_HAS_FOCUS(lookup_widget(app,"filterdropdown")) || GTK_WIDGET_HAS_FOCUS(lookup_widget(app,"filter")) || GTK_WIDGET_HAS_FOCUS(lookup_widget(app,"filterbutton")) || GTK_WIDGET_HAS_FOCUS(lookup_widget(app,"filterclear")) || GTK_WIDGET_HAS_FOCUS(lookup_widget(app,"filteradvanced")) ) { g_print("A filter control is focused, no longer processing keys\n"); return FALSE; } // else, key processing for object view g_print("Processing keypress for object view\n"); /* tab key, bro */ if (event->keyval == 65289) { g_print("Focusing filter box\n"); gtk_widget_grab_focus(lookup_widget(app,"filtertype")); processed = TRUE; } /* procesamiento de arrow keys */ if (event->keyval == 65363) { objectview_move_right (); processed = TRUE; } if (event->keyval == 65361) { objectview_move_left (); processed = TRUE;} if (event->keyval == 65362) { objectview_move_up ();processed = TRUE;} if (event->keyval == 65364) { objectview_move_down ();processed = TRUE;} /* del key */ if (event->keyval == 65535) { processed = TRUE; delbutton = lookup_widget (GTK_WIDGET (app),"button_removeselection"); if (GTK_WIDGET_SENSITIVE (delbutton)) { gtk_signal_emit_by_name (GTK_OBJECT(delbutton), "clicked"); } } /* enter keys */ if (event->keyval == 65293 || event->keyval == 65421) { processed = TRUE; delbutton = lookup_widget (GTK_WIDGET (app),"button_modifyselection"); if (GTK_WIDGET_SENSITIVE (delbutton)) { gtk_signal_emit_by_name (GTK_OBJECT (delbutton),"clicked"); } } /* type ahead find */ if (isalnum(letter) || isspace(letter)) { processed = TRUE; delta = event->time - objectview_last_keypress; //g_print("\nKeypress delta: %u", delta); if (delta <= 1000 || objectview_last_keypress == 0) { tmp = typeaheadcontents; if (typeaheadcontents) typeaheadcontents = g_strconcat(typeaheadcontents,event->string,NULL); else typeaheadcontents = g_strconcat(event->string,NULL); if (tmp) g_free(tmp); // g_print("\nType ahead begun: %s",typeaheadcontents); objectview_typeahead_find(typeaheadcontents); } else { // g_print("\nType ahead reset - time expired"); g_free(typeaheadcontents); typeaheadcontents = g_strdup(event->string); objectview_typeahead_find(typeaheadcontents); } objectview_last_keypress = event->time; } else if (key == 65505 || key == 65507 || key == 65513 || key == 65407 || key == 65509 || key == 65506 || key == 65508 || key == 65406 ){ } else { /* otra tecla, se cancela el typeahead */ g_free(typeaheadcontents); typeaheadcontents =NULL; } return processed; } void objectview_select_all() { objectview_icon_select_all((GnomeIconList *) lookup_widget (app,"itemlist")); } void objectview_typeahead_find (gchar* string) { GList* a; gboolean found = FALSE; dir_entry*e =NULL; for (a=cached_dir_entries;a;a=a->next) { e= a->data; if (strncasecmp(dir_entry_get_name(e),string,strlen(string)) == 0) { g_print("\n\nFound a match while typeahead searching\n\n"); found = TRUE; break; } } if (found) { objectview_icon_clear_selection((GnomeIconList *) lookup_widget (app,"itemlist")); objectview_icon_select_by_entry ((GnomeIconList *) lookup_widget (app,"itemlist"),e); } } void objectview_icon_select_by_entry (GnomeIconList*list, dir_entry* e) { int pos; pos = gnome_icon_list_find_icon_from_data(list,e); if (pos>=0) { gnome_icon_list_select_icon(list,pos); if (gnome_icon_list_icon_is_visible(list,pos) != GTK_VISIBILITY_FULL) gnome_icon_list_moveto(list,pos,0.5); } } void objectview_icon_select_all (GnomeIconList*list) { int pos; for (pos = list->icons-1;pos>=0;pos--) // gnome_icon_list_unselect_all(list,NULL,NULL); //gnome_icon_list_freeze(list); gnome_icon_list_select_icon(list,pos); //gnome_icon_list_thaw(list); } void objectview_clear(void) { objectview_icon_clear((GnomeIconList *) lookup_widget (app,"itemlist")); } void objectview_icon_clear(GnomeIconList *list) { gnome_icon_list_clear (list); } void objectview_fill (void) { GList* l; dir_entry*stuff; char* filter = NULL; char*eluno;char*elotro; // GtkOptionMenu*n; // GtkMenuItem*m; // GtkButton* i; // GtkBin*z; // GtkLabel*j; // char**whatselected; filter = gtk_entry_get_text(GTK_ENTRY(lookup_widget(app,"filter"))); if (strlen(filter)<1) filter = NULL; /* n=(GtkOptionMenu*)lookup_widget(app,"filtertype"); m=n->menu_item; g_assert(GTK_IS_MENU_ITEM(m)); g_print("%s\n",gtk_type_name(GTK_WIDGET_TYPE(m))); z=&(m->item.bin); g_print("%s\n",gtk_type_name(GTK_WIDGET_TYPE(z))); // j=(z->child); g_assert(j); g_print("%d\n",GTK_WIDGET_TYPE(j)); g_assert(GTK_IS_BUTTON(j)); gtk_label_get(j,whatselected); g_print("This is selected on the dropdown: %s\n",whatselected); */ objectview_add_begun(); objectview_clear(); for (l = g_list_first(cached_dir_entries); l; l = g_list_next (l)) { stuff = l->data; if (filter) { eluno = g_strdup(filter);g_strdown(eluno); } else eluno = NULL; elotro = g_strdup(stuff->dn);g_strdown(elotro); if (eluno == NULL || strstr(elotro,eluno)) { objectview_add (l->data); } if (filter) { g_free(eluno);} g_free(elotro); } objectview_add_finished(); } void objectview_add_finished(void) { objectview_icon_add_finished((GnomeIconList *)lookup_widget (app, "itemlist")); } void objectview_icon_add_finished(GnomeIconList*list) { // gtk_signal_emit_by_name (GTK_OBJECT(list), "unselect_icon"); gnome_icon_list_thaw (list); } void objectview_add_begun(void) { objectview_icon_add_begun((GnomeIconList *)lookup_widget (app, "itemlist")); } void objectview_icon_add_begun(GnomeIconList*list) { //check if icons are properly installed gchar*pixmapfile; pixmapfile = gnome_pixmap_file ("directory_administrator/user-icon.xpm"); if (pixmapfile == NULL){ gtk_widget_show( create_messagebox_with_message("Your Directory administrator installation is faulty. Icons cannot be found.\nPlease ensure the icons were installed in the GNOME icons (pixmaps) directory.")); } // gtk_signal_emit_by_name (GTK_OBJECT(list), "unselect_icon"); gnome_icon_list_freeze (list); } gboolean objectview_has_selection (void) { return objectview_icon_has_selection((GnomeIconList *) lookup_widget (app, "itemlist")); } gboolean objectview_icon_has_selection (GnomeIconList* list) { if (g_list_length(list->selection)>0) return TRUE; return FALSE; } int objectview_num_entries (void) { return objectview_icon_num_entries( (GnomeIconList *) lookup_widget (app, "itemlist")); } int objectview_icon_num_entries (GnomeIconList* list) { return list->icons; } void objectview_select_first (void) { if (objectview_num_entries() > 0) objectview_icon_select_first( (GnomeIconList *) lookup_widget (app, "itemlist")); } void objectview_clear_selection () { objectview_icon_clear_selection( (GnomeIconList *) lookup_widget (app, "itemlist")); } void objectview_icon_clear_selection (GnomeIconList* list) { GList* iter=NULL; GList* copy=NULL; for (iter=list->selection;iter;iter=iter->next) { copy = g_list_append(copy,GINT_TO_POINTER(iter->data)); } for (iter=copy;iter;iter=iter->next) { // g_print("\n Unselecting icon %d",GPOINTER_TO_INT(iter->data)); gnome_icon_list_unselect_icon(list,GPOINTER_TO_INT(iter->data)); } g_list_free(copy); list->selection = NULL; objectview_icon_dump_selections(list); } void objectview_icon_dump_selections (GnomeIconList* list) { GList* iter=NULL; dir_entry* entry = NULL; int pos; /*g_print("\n\nDebugging information for icon selections:"); g_print("\nNumber of icons in list: %d list length: %d", list->icons,g_list_length(list->selection) );*/ for (iter=list->selection;iter;iter=iter->next) { pos = GPOINTER_TO_INT (iter->data); entry = gnome_icon_list_get_icon_data (list, pos); // g_print("\n Selected position: %d",pos); // g_print("\n Selected DN: %s",dir_entry_get_dn(entry)); } } void objectview_icon_select_first (GnomeIconList* list) { objectview_icon_clear_selection(list); gnome_icon_list_select_icon(list,0); if (gnome_icon_list_icon_is_visible(list,0) != GTK_VISIBILITY_FULL) gnome_icon_list_moveto(list,0,0); objectview_icon_dump_selections(list); } /* there are two views objectview_icon objectview_list_detailed objectview_icon_add (GnomeIconList* , dir_entry *) adds an entry to the icon view (dupes the icon_entry for itself and frees it on item removal) objectview_list_detailed_add (GtkCList* , icon_entry *) adds an entry to the detail list view (dupes the icon_entry for itself and frees it on item removal) objectview_icon_remove_bydn(GnomeIconList*,gchar*) finds the entry with the corr. DN and removes it objectview_list_detailed_remove_bydn(GnomeIconList*,gchar*) does the same thing for the list view those two functions are marshaled by the master functions objectview_add (dir_entry *) objectview_remove_bydn (gchar *) */ void objectview_add (dir_entry * entry) { objectview_icon_add ((GnomeIconList *) lookup_widget (app, "itemlist"), entry); } void objectview_move_left (void) { if (objectview_has_selection()) { // g_print("\nMoving left"); objectview_icon_move_left ( (GnomeIconList *) lookup_widget (app, "itemlist")); } else objectview_select_first(); } void objectview_icon_move_left( GnomeIconList * list ){ int currpos ; int pos; currpos = GPOINTER_TO_INT(list->selection->data); pos = currpos - 1; if (pos >=0 && pos < list->icons) { objectview_icon_clear_selection(list); gnome_icon_list_select_icon(list,pos); if (gnome_icon_list_icon_is_visible(list,pos) != GTK_VISIBILITY_FULL) gnome_icon_list_moveto(list,pos,0); } } void objectview_move_up (void) { if (objectview_has_selection()) { // g_print("\nMoving up"); objectview_icon_move_up ( (GnomeIconList *) lookup_widget (app, "itemlist"));} else objectview_select_first(); } void objectview_icon_move_up( GnomeIconList * list ){ int currpos ; int itemsxline ; int pos; itemsxline = gnome_icon_list_get_items_per_line (list); currpos = GPOINTER_TO_INT(list->selection->data); pos = currpos - itemsxline; if (pos >= 0 && pos < list->icons){ objectview_icon_clear_selection(list); gnome_icon_list_select_icon(list,pos); if (gnome_icon_list_icon_is_visible(list,pos) != GTK_VISIBILITY_FULL) gnome_icon_list_moveto(list,pos,0); } } void objectview_move_down (void) { if (objectview_has_selection()) { // g_print("\nMoving down"); objectview_icon_move_down ( (GnomeIconList *) lookup_widget (app, "itemlist")); } else objectview_select_first(); } void objectview_icon_move_down( GnomeIconList * list ){ int currpos ; int itemsxline ; int pos; itemsxline = gnome_icon_list_get_items_per_line (list); currpos = GPOINTER_TO_INT(list->selection->data); pos = currpos + itemsxline; if (pos >= 0 && pos < list->icons){ objectview_icon_clear_selection(list); gnome_icon_list_select_icon(list,pos); if (gnome_icon_list_icon_is_visible(list,pos) != GTK_VISIBILITY_FULL) gnome_icon_list_moveto(list,pos,1); } /*(estoy en la ultima linea?) si la posicion del icono actual esta entre los ultimos N iconos donde N es el numero de items x linea */ /*if (pos >= list->icons && !()) gnome_icon_list_select_icon(list,list->icons -1); */ } void objectview_move_right (void) { if (objectview_has_selection()) { // g_print("\nMoving right"); objectview_icon_move_right ( (GnomeIconList *) lookup_widget (app, "itemlist")); } else objectview_select_first(); } void objectview_icon_move_right( GnomeIconList * list ){ int currpos ; int pos; currpos = GPOINTER_TO_INT(list->selection->data); pos = currpos +1; if (pos >= 0 && pos < list->icons){ objectview_icon_clear_selection(list); gnome_icon_list_select_icon(list,pos); if (gnome_icon_list_icon_is_visible(list,pos) != GTK_VISIBILITY_FULL) gnome_icon_list_moveto(list,pos,1); } } void objectview_icon_add (GnomeIconList * list, dir_entry * entry) { // SACA UN DUPLICADO DEL ENTRY int pos; gchar *pixmapfile = NULL; g_assert(entry); if (entry->type == DENTRY_USER) pixmapfile = gnome_pixmap_file ("directory_administrator/user-icon.xpm"); if (entry->type == DENTRY_GROUP) pixmapfile = gnome_pixmap_file ("directory_administrator/group-icon.xpm"); if (pixmapfile) { pos = gnome_icon_list_append (list, pixmapfile, dir_entry_get_name(entry)); gnome_icon_list_set_icon_data (list, pos, entry); g_free (pixmapfile);} } /*void objectview_remove_bydn (gchar * dn) { objectview_icon_remove_bydn ((GnomeIconList *) lookup_widget (app, "itemlist"), dn); } void objectview_icon_remove_bydn (GnomeIconList * list, gchar * dn) { icon_entry *curr_entry; int pos; for (pos = 0; pos < list->icons; pos++) { curr_entry = gnome_icon_list_get_icon_data (list, pos); if (g_strcasecmp (dn, dir_entry_get_dn(curr_entry) == 0) { g_print("\nRemoving %s from icon view",curr_entry->dn); gnome_icon_list_remove (list, pos); pos = list->icons + 1; } } } */ GList * refresh_directory_data (connection_profile * usethisone) { //needs a connection profile already connected. thanks. REMEMBER DAT!!! LDAP *conn = NULL; gchar *root = NULL; gchar *filter = NULL; LDAPMessage *results = NULL; LDAPMessage *entry = NULL; gchar *attributetoreturn[8]; char **value_collection; char **oc_collection; int oc_iterator; int ldap_errors; GList *direntries; gchar *uid_holder; gchar *cn_holder; gchar *gecos_holder; gchar *dn_holder; gchar *ou_holder; gint uidnumber_holder, gidnumber_holder; dir_entry *d_entry; float progress; gint totalentries, currententrynumber; g_print ("\ncalled: refresh_directory_data\n"); direntries = NULL; //check 4 connection if (connection_profile_is_connected (usethisone) == FALSE) { g_print ("\ndisconnected: list emptied\n"); return NULL; } conn = connection_profile_get_ldap_handler (usethisone); root = connection_profile_get_treeroot (usethisone); attributetoreturn[0] = "objectClass"; attributetoreturn[1] = "uid"; attributetoreturn[2] = "cn"; attributetoreturn[3] = "gecos"; attributetoreturn[4] = "gidnumber"; attributetoreturn[5] = "uidnumber"; attributetoreturn[6] = "ou"; attributetoreturn[7] = NULL; filter = "(|(objectclass=posixAccount)(objectclass=posixGroup)(objectclass=organizationalUnit))"; //look data up ldap_errors = ldap_search_s (conn, root, LDAP_SCOPE_SUBTREE, filter, attributetoreturn, 0, &results); if (ldap_errors) { g_print ("LDAP error while filling icon list: %s\n", ldap_err2string (ldap_errors)); return NULL; } g_assert (results); totalentries = ldap_count_entries (conn,results); currententrynumber = 0; oc_iterator = 0; for (entry=ldap_first_entry(conn,results);entry;entry=ldap_next_entry (conn, entry)) { currententrynumber++; progress = (float) currententrynumber/totalentries; app_set_progress(progress); //quiero ver que chucha hay en la lista de objectClass dn_holder = ldap_get_dn(conn,entry); oc_collection = ldap_get_values (conn, entry, "objectClass"); g_assert (oc_collection); oc_iterator = 0; d_entry=NULL; while (oc_collection[oc_iterator] || d_entry==NULL) { //si es un posix account, aniadir como usuario if (g_strcasecmp (oc_collection[oc_iterator], "posixAccount") == 0) { cn_holder = NULL; uid_holder = NULL; gecos_holder = NULL; uidnumber_holder = 0; gidnumber_holder = 0; value_collection = ldap_get_values (conn, entry, "cn"); if (value_collection) { cn_holder = convert_from_utf8(value_collection[0]); ldap_value_free (value_collection); } value_collection = ldap_get_values (conn, entry, "gecos"); if (value_collection) { gecos_holder = convert_from_utf8(value_collection[0]); ldap_value_free (value_collection); } value_collection = ldap_get_values (conn, entry, "uid"); if (value_collection) { uid_holder = convert_from_utf8(value_collection[0]); ldap_value_free (value_collection); } value_collection = ldap_get_values (conn, entry, "uidnumber"); if (value_collection) { uidnumber_holder = atoi(value_collection[0]); ldap_value_free (value_collection); } value_collection = ldap_get_values (conn, entry, "gidnumber"); if (value_collection) { gidnumber_holder = atoi(value_collection[0]); ldap_value_free (value_collection); } //si no hay common name, al menos use gecos if (cn_holder == NULL) cn_holder = gecos_holder; d_entry = dir_entry_user_new (dn_holder, uid_holder, cn_holder, uidnumber_holder, gidnumber_holder); g_free(uid_holder); g_free (cn_holder); g_free(gecos_holder); } //si es un posix group, aadir como grupo else if (g_strcasecmp (oc_collection[oc_iterator], "posixGroup") == 0) { cn_holder = NULL; gidnumber_holder =0; value_collection = ldap_get_values (conn, entry, "cn"); if (value_collection) { cn_holder = convert_from_utf8(value_collection[0]); ldap_value_free (value_collection); } value_collection = ldap_get_values (conn, entry, "gidnumber"); g_assert (value_collection); gidnumber_holder = atoi(value_collection[0]); ldap_value_free (value_collection); d_entry = dir_entry_group_new (dn_holder, cn_holder, gidnumber_holder); g_free (cn_holder); } else if (g_strcasecmp (oc_collection[oc_iterator], "organizationalUnit") == 0) { ou_holder = NULL; value_collection = ldap_get_values (conn, entry, "ou"); if (value_collection) { ou_holder = convert_from_utf8(value_collection[0]); ldap_value_free (value_collection); } d_entry = dir_entry_orgunit_new (dn_holder, ou_holder); g_free (ou_holder); } /* else { d_entry = dir_entry_undef_new (dn_holder); }*/ oc_iterator++; } if (d_entry) direntries = g_list_append(direntries,d_entry); ldap_value_free (oc_collection); g_free (dn_holder); } ldap_msgfree (results); return g_list_first(direntries); }