+2003-06-19 [match] 0.9.0claws50
+
+ * src/addressbook.[ch]
+ * src/addrindex.[ch]
+ * src/addr_compl.[ch]
+ * src/editldap.[ch]
+ * src/editldap_basedn.[ch]
+ * src/addritem.[ch]
+ * src/ldapquery.h
+ re-implemented dynamic LDAP search. works without
+ slowdown on display sender with addressbook
+ option.
+ * src/addrbook.c
+ documented code.
+
2003-06-19 [paul] 0.9.0claws49
* src/compose.c
MICRO_VERSION=0
INTERFACE_AGE=0
BINARY_AGE=0
-EXTRA_VERSION=claws49
+EXTRA_VERSION=claws50
VERSION=$MAJOR_VERSION.$MINOR_VERSION.$MICRO_VERSION$EXTRA_VERSION
dnl set $target
pine.c pine.h \
importpine.c importpine.h \
jpilot.c jpilot.h \
- syldap.c syldap.h \
+ ldapctrl.c ldapctrl.h \
+ ldapquery.c ldapquery.h \
+ ldapserver.c ldapserver.h \
+ ldaputil.c ldaputil.h \
editbook.c editbook.h \
editgroup.c editgroup.h \
editaddress.c editaddress.h \
#include "addressbook.h"
#include "addr_compl.h"
#include "utils.h"
+#include <pthread.h>
-/* How it works:
+/*
+ * How it works:
*
* The address book is read into memory. We set up an address list
* containing all address book entries. Next we make the completion
* any of those words).
*/
-/* address_entry - structure which refers to the original address entry in the
- * address book
+/**
+ * Reference to address index.
+ */
+static AddressIndex *_addressIndex_ = NULL;
+
+/**
+ * address_entry - structure which refers to the original address entry in the
+ * address book .
*/
typedef struct
{
gchar *address;
} address_entry;
-/* completion_entry - structure used to complete addresses, with a reference
+/**
+ * completion_entry - structure used to complete addresses, with a reference
* the the real address information.
*/
typedef struct
/*******************************************************************************/
-/* completion_func() - used by GTK to find the string data to be used for
- * completion
+/**
+ * Function used by GTK to find the string data to be used for completion.
+ * \param data Pointer to data being processed.
*/
static gchar *completion_func(gpointer data)
{
return ((completion_entry *)data)->string;
}
+/**
+ * Initialize all completion index data.
+ */
static void init_all(void)
{
g_completion = g_completion_new(completion_func);
g_return_if_fail(g_completion != NULL);
}
+/**
+ * Free up all completion index data.
+ */
static void free_all(void)
{
GList *walk;
g_completion = NULL;
}
+/**
+ * Append specified address entry to the index.
+ * \param str Index string value.
+ * \param ae Entry containing address data.
+ */
static void add_address1(const char *str, address_entry *ae)
{
completion_entry *ce1;
g_completion_list = g_list_prepend(g_completion_list, ce1);
}
-/* add_address() - adds address to the completion list. this function looks
- * complicated, but it's only allocation checks.
+/**
+ * Adds address to the completion list. This function looks complicated, but
+ * it's only allocation checks. Each value will be included in the index.
+ * \param name Recipient name.
+ * \param address EMail address.
+ * \param alias Alias to append.
+ * \return <code>0</code> if entry appended successfully, or <code>-1</code>
+ * if failure.
*/
static gint add_address(const gchar *name, const gchar *address, const gchar *alias)
{
ae->name = g_strdup(name);
ae->address = g_strdup(address);
- g_address_list = g_list_prepend(g_address_list, ae);
+ g_address_list = g_list_prepend(g_address_list, ae);
add_address1(name, ae);
add_address1(address, ae);
return 0;
}
-/* read_address_book()
+/**
+ * Read address book, creating all entries in the completion index.
*/
static void read_address_book(void) {
- addressbook_load_completion( add_address );
+ addrindex_load_completion( _addressIndex_, add_address );
g_address_list = g_list_reverse(g_address_list);
g_completion_list = g_list_reverse(g_completion_list);
}
-/* start_address_completion() - returns the number of addresses
- * that should be matched for completion.
+/**
+ * Test whether there is a completion pending.
+ * \return <code>TRUE</code> if pending.
+ */
+static gboolean is_completion_pending(void)
+{
+ /* check if completion pending, i.e. we might satisfy a request for the next
+ * or previous address */
+ return g_completion_count;
+}
+
+/**
+ * Clear the completion cache.
+ */
+static void clear_completion_cache(void)
+{
+ if (is_completion_pending()) {
+ if (g_completion_prefix)
+ g_free(g_completion_prefix);
+
+ if (g_completion_addresses) {
+ g_slist_free(g_completion_addresses);
+ g_completion_addresses = NULL;
+ }
+
+ g_completion_count = g_completion_next = 0;
+ }
+}
+
+/**
+ * Prepare completion index. This function should be called prior to attempting
+ * address completion.
+ * \return The number of addresses in the completion list.
*/
gint start_address_completion(void)
{
return g_list_length(g_completion_list);
}
-/* get_address_from_edit() - returns a possible address (or a part)
- * from an entry box. To make life easier, we only look at the last valid address
- * component; address completion only works at the last string component in
- * the entry box.
- */
-gchar *get_address_from_edit(GtkEntry *entry, gint *start_pos)
+/**
+ * Retrieve a possible address (or a part) from an entry box. To make life
+ * easier, we only look at the last valid address component; address
+ * completion only works at the last string component in the entry box.
+ *
+ * \param entry Address entry field.
+ * \param start_pos Address of start position of address.
+ * \return Possible address.
+ */
+static gchar *get_address_from_edit(GtkEntry *entry, gint *start_pos)
{
const gchar *edit_text;
gint cur_pos;
return str;
}
-/* replace_address_in_edit() - replaces an incompleted address with a completed one.
+/**
+ * Replace an incompleted address with a completed one.
+ * \param entry Address entry field.
+ * \param newtext New text.
+ * \param start_pos Insertion point in entry field.
*/
-void replace_address_in_edit(GtkEntry *entry, const gchar *newtext,
+static void replace_address_in_edit(GtkEntry *entry, const gchar *newtext,
gint start_pos)
{
if (!newtext) return;
-
gtk_editable_delete_text(GTK_EDITABLE(entry), start_pos, -1);
gtk_editable_insert_text(GTK_EDITABLE(entry), newtext, strlen(newtext),
&start_pos);
gtk_editable_set_position(GTK_EDITABLE(entry), -1);
}
-/* complete_address() - tries to complete an addres, and returns the
- * number of addresses found. use get_complete_address() to get one.
- * returns zero if no match was found, otherwise the number of addresses,
- * with the original prefix at index 0.
+/**
+ * Attempt to complete an address, and returns the number of addresses found.
+ * Use <code>get_complete_address()</code> to get an entry from the index.
+ *
+ * \param str Search string to find.
+ * \return Zero if no match was found, otherwise the number of addresses; the
+ * original prefix (search string) will appear at index 0.
*/
guint complete_address(const gchar *str)
{
return count;
}
-/* get_complete_address() - returns a complete address. the returned
- * string should be freed
+/**
+ * Return a complete address from the index.
+ * \param index Index of entry that was found (by the previous call to
+ * <code>complete_address()</code>
+ * \return Completed address string; this should be freed when done.
*/
gchar *get_complete_address(gint index)
{
if (p != NULL) {
if (!p->name || p->name[0] == '\0')
address = g_strdup_printf(p->address);
- else if (p->name[0] != '"' &&
- strpbrk(p->name, ",.[]<>") != NULL)
+ else if (strchr_with_skip_quote(p->name, '"', ','))
address = g_strdup_printf
("\"%s\" <%s>", p->name, p->address);
else
return address;
}
-gchar *get_next_complete_address(void)
+/**
+ * Return the next complete address match from the completion index.
+ * \return Completed address string; this should be freed when done.
+ */
+static gchar *get_next_complete_address(void)
{
if (is_completion_pending()) {
gchar *res;
return NULL;
}
-gchar *get_prev_complete_address(void)
+/**
+ * Return the previous complete address match from the completion index.
+ * \return Completed address string; this should be freed when done.
+ */
+static gchar *get_prev_complete_address(void)
{
if (is_completion_pending()) {
int n = g_completion_next - 2;
return NULL;
}
-guint get_completion_count(void)
+/**
+ * Return a count of the completed matches in the completion index.
+ * \return Number of matched entries.
+ */
+static guint get_completion_count(void)
{
if (is_completion_pending())
return g_completion_count;
return 0;
}
-/* should clear up anything after complete_address() */
-void clear_completion_cache(void)
-{
- if (is_completion_pending()) {
- if (g_completion_prefix)
- g_free(g_completion_prefix);
-
- if (g_completion_addresses) {
- g_slist_free(g_completion_addresses);
- g_completion_addresses = NULL;
- }
-
- g_completion_count = g_completion_next = 0;
- }
-}
-
-gboolean is_completion_pending(void)
-{
- /* check if completion pending, i.e. we might satisfy a request for the next
- * or previous address */
- return g_completion_count;
-}
-
-/* invalidate_address_completion() - should be called if address book
- * changed;
+/**
+ * Invalidate address completion index. This function should be called whenever
+ * the address book changes. This forces data to be read into the completion
+ * data.
+ * \return Number of entries in index.
*/
gint invalidate_address_completion(void)
{
free_all();
init_all();
read_address_book();
- if (g_completion_list)
- g_completion_add_items(g_completion, g_completion_list);
+ g_completion_add_items(g_completion, g_completion_list);
clear_completion_cache();
}
return g_list_length(g_completion_list);
}
+/**
+ * Finished with completion index. This function should be called after
+ * matching addresses.
+ * \return Reference count.
+ */
gint end_address_completion(void)
{
clear_completion_cache();
return g_ref_count;
}
+/*
+ * Define the structure of the completion window.
+ */
+typedef struct _CompletionWindow CompletionWindow;
+struct _CompletionWindow {
+ gint listCount;
+ gchar *searchTerm;
+ GtkWidget *window;
+ GtkWidget *entry;
+ GtkWidget *clist;
+};
+
+/**
+ * Completion window.
+ */
+static CompletionWindow *_compWindow_ = NULL;
+
+/**
+ * Mutex to protect callback from multiple threads.
+ */
+static pthread_mutex_t _completionMutex_ = PTHREAD_MUTEX_INITIALIZER;
-/* address completion entry ui. the ui (completion list was inspired by galeon's
+/**
+ * Completion queue list.
+ */
+static GList *_displayQueue_ = NULL;
+
+/**
+ * Current query ID.
+ */
+static gint _queryID_ = 0;
+
+/**
+ * Completion idle ID.
+ */
+static gint _completionIdleID_ = 0;
+
+/*
+ * address completion entry ui. the ui (completion list was inspired by galeon's
* auto completion list). remaining things powered by sylpheed's completion engine.
*/
-#define ENTRY_DATA_TAB_HOOK "tab_hook" /* used to lookup entry */
-#define WINDOW_DATA_COMPL_ENTRY "compl_entry" /* used to store entry for compl. window */
-#define WINDOW_DATA_COMPL_CLIST "compl_clist" /* used to store clist for compl. window */
+#define ENTRY_DATA_TAB_HOOK "tab_hook" /* used to lookup entry */
static void address_completion_mainwindow_set_focus (GtkWindow *window,
GtkWidget *widget,
gint row,
gint col,
GdkEvent *event,
- GtkWidget **completion_window);
+ CompletionWindow *compWin );
+
static gboolean completion_window_button_press
(GtkWidget *widget,
GdkEventButton *event,
- GtkWidget **completion_window);
+ CompletionWindow *compWin );
+
static gboolean completion_window_key_press
(GtkWidget *widget,
GdkEventKey *event,
- GtkWidget **completion_window);
+ CompletionWindow *compWin );
+static void address_completion_create_completion_window( GtkEntry *entry_ );
+
+/**
+ * Create a completion window object.
+ * \return Initialized completion window.
+ */
+static CompletionWindow *addrcompl_create_window( void ) {
+ CompletionWindow *cw;
+
+ cw = g_new0( CompletionWindow, 1 );
+ cw->listCount = 0;
+ cw->searchTerm = NULL;
+ cw->window = NULL;
+ cw->entry = NULL;
+ cw->clist = NULL;
+ return cw;
+}
+
+/**
+ * Destroy completion window.
+ * \param cw Window to destroy.
+ */
+static void addrcompl_destroy_window( CompletionWindow *cw ) {
+ /* Remove idler function... or application may not terminate */
+ if( _completionIdleID_ != 0 ) {
+ gtk_idle_remove( _completionIdleID_ );
+ _completionIdleID_ = 0;
+ }
+
+ /* Now destroy window */
+ if( cw ) {
+ /* Clear references to widgets */
+ cw->entry = NULL;
+ cw->clist = NULL;
+
+ /* Free objects */
+ if( cw->window ) {
+ gtk_widget_hide( cw->window );
+ gtk_widget_destroy( cw->window );
+ }
+ cw->window = NULL;
+ }
+}
+
+/**
+ * Free up completion window.
+ * \param cw Window to free.
+ */
+static void addrcompl_free_window( CompletionWindow *cw ) {
+ if( cw ) {
+ addrcompl_destroy_window( cw );
+ g_free( cw->searchTerm );
+ cw->searchTerm = NULL;
+
+ /* Clear references */
+ cw->listCount = 0;
+
+ /* Free object */
+ g_free( cw );
+ }
+}
+
+/**
+ * Select specified row in list.
+ * \param clist List to process.
+ * \param row Row to select.
+ */
static void completion_window_advance_to_row(GtkCList *clist, gint row)
{
g_return_if_fail(row < g_completion_count);
gtk_clist_select_row(clist, row, 0);
}
+/**
+ * Advance selection to previous/next item in list.
+ * \param clist List to process.
+ * \param forward Set to <i>TRUE</i> to select next or <i>FALSE</i> for
+ * previous entry.
+ */
static void completion_window_advance_selection(GtkCList *clist, gboolean forward)
{
int row;
g_return_if_fail(clist != NULL);
- g_return_if_fail(clist->selection != NULL);
- row = GPOINTER_TO_INT(clist->selection->data);
-
- row = forward ? (row + 1) % g_completion_count :
- (row - 1) < 0 ? g_completion_count - 1 : row - 1;
-
- gtk_clist_freeze(clist);
- completion_window_advance_to_row(clist, row);
- gtk_clist_thaw(clist);
+ if( clist->selection ) {
+ row = GPOINTER_TO_INT(clist->selection->data);
+ row = forward ? ( row + 1 ) : ( row - 1 );
+ gtk_clist_freeze(clist);
+ gtk_clist_select_row(clist, row, 0);
+ gtk_clist_thaw(clist);
+ }
}
#if 0
}
#endif
-/* completion_window_apply_selection() - apply the current selection in the
- * clist */
+/**
+ * Resize window to accommodate maximum number of address entries.
+ * \param cw Completion window.
+ */
+static void addrcompl_resize_window( CompletionWindow *cw ) {
+ GtkRequisition r;
+ gint x, y, width, height, depth;
+
+ /* Get current geometry of window */
+ gdk_window_get_geometry( cw->window->window, &x, &y, &width, &height, &depth );
+
+ gtk_widget_size_request( cw->clist, &r );
+ gtk_widget_set_usize( cw->window, width, r.height );
+ gtk_widget_show_all( cw->window );
+ gtk_widget_size_request( cw->clist, &r );
+
+ /* Adjust window height to available screen space */
+ if( ( y + r.height ) > gdk_screen_height() ) {
+ gtk_window_set_policy( GTK_WINDOW( cw->window ), TRUE, FALSE, FALSE );
+ gtk_widget_set_usize( cw->window, width, gdk_screen_height() - y );
+ }
+}
+
+/**
+ * Add an address the completion window address list.
+ * \param cw Completion window.
+ * \param address Address to add.
+ */
+static void addrcompl_add_entry( CompletionWindow *cw, gchar *address ) {
+ gchar *text[] = { NULL, NULL };
+
+ /* printf( "\t\tAdding :%s\n", address ); */
+ text[0] = address;
+ gtk_clist_append( GTK_CLIST(cw->clist), text );
+ cw->listCount++;
+
+ /* Resize window */
+ addrcompl_resize_window( cw );
+ gtk_grab_add( cw->window );
+
+ if( cw->listCount == 1 ) {
+ /* Select first row for now */
+ gtk_clist_select_row( GTK_CLIST(cw->clist), 0, 0);
+ }
+ else if( cw->listCount == 2 ) {
+ /* Move off first row */
+ gtk_clist_select_row( GTK_CLIST(cw->clist), 1, 0);
+ }
+}
+
+/**
+ * Completion idle function. This function is called by the main (UI) thread
+ * during UI idle time while an address search is in progress. Items from the
+ * display queue are processed and appended to the address list.
+ *
+ * \param data Target completion window to receive email addresses.
+ * \return <i>TRUE</i> to ensure that idle event do not get ignored.
+ */
+static gboolean addrcompl_idle( gpointer data ) {
+ GList *node;
+ gchar *address;
+ CompletionWindow *cw;
+
+ /* Process all entries in display queue */
+ pthread_mutex_lock( & _completionMutex_ );
+ if( _displayQueue_ ) {
+ cw = data;
+ node = _displayQueue_;
+ while( node ) {
+ address = node->data;
+ /* printf( "address ::: %s :::\n", address ); */
+ addrcompl_add_entry( cw, address );
+ g_free( address );
+ node = g_list_next( node );
+ }
+ g_list_free( _displayQueue_ );
+ _displayQueue_ = NULL;
+ }
+ pthread_mutex_unlock( & _completionMutex_ );
+
+ return TRUE;
+}
+
+/**
+ * Callback entry point. The background thread (if any) appends the address
+ * list to the display queue.
+ * \param queryID Query ID of search request.
+ * \param listEMail List of zero of more email objects that met search
+ * criteria.
+ * \param target Target object to received data.
+ */
+static gint addrcompl_callback(
+ gint queryID, GList *listEMail, gpointer target )
+{
+ GList *node;
+ gchar *address;
+
+ /* printf( "addrcompl_callback::queryID=%d\n", queryID ); */
+ pthread_mutex_lock( & _completionMutex_ );
+ if( queryID == _queryID_ ) {
+ /* Append contents to end of display queue */
+ node = listEMail;
+ while( node ) {
+ ItemEMail *email = node->data;
+ if( target ) {
+ address = addritem_format_email( email );
+ /* printf( "\temail/address ::%s::\n", address ); */
+ _displayQueue_ = g_list_append( _displayQueue_, address );
+ }
+ node = g_list_next( node );
+ }
+ }
+ pthread_mutex_unlock( & _completionMutex_ );
+ /* printf( "addrcompl_callback...done\n" ); */
+}
+
+/**
+ * Clear the display queue.
+ */
+static void addrcompl_clear_queue( void ) {
+ /* Clear out display queue */
+ pthread_mutex_lock( & _completionMutex_ );
+
+ g_list_free( _displayQueue_ );
+ _displayQueue_ = NULL;
+
+ pthread_mutex_unlock( & _completionMutex_ );
+}
+
+/**
+ * Add a single address entry into the display queue.
+ * \param address Address to append.
+ */
+static void addrcompl_add_queue( gchar *address ) {
+ pthread_mutex_lock( & _completionMutex_ );
+ _displayQueue_ = g_list_append( _displayQueue_, address );
+ pthread_mutex_unlock( & _completionMutex_ );
+}
+
+/**
+ * Load list with entries from local completion index.
+ * \param cw Completion window.
+ */
+static void addrcompl_load_local( CompletionWindow *cw ) {
+ guint count = 0;
+
+ for (count = 0; count < get_completion_count(); count++) {
+ gchar *address;
+
+ address = get_complete_address( count );
+ /* printf( "\taddress ::%s::\n", address ); */
+
+ /* Append contents to end of display queue */
+ addrcompl_add_queue( address );
+ }
+}
+
+/**
+ * Start the search.
+ */
+static void addrcompl_start_search( void ) {
+ gchar *searchTerm;
+
+ searchTerm = g_strdup( _compWindow_->searchTerm );
+
+ /* Setup the search */
+ _queryID_ = addrindex_setup_search(
+ _addressIndex_, searchTerm, _compWindow_, addrcompl_callback );
+ g_free( searchTerm );
+ /* printf( "addrcompl_start_search::queryID=%d\n", _queryID_ ); */
+
+ /* Load local stuff */
+ addrcompl_load_local( _compWindow_ );
+
+ /* Sit back and wait until something happens */
+ _completionIdleID_ =
+ gtk_idle_add( ( GtkFunction ) addrcompl_idle, _compWindow_ );
+ /* printf( "addrindex_start_search::queryID=%d\n", _queryID_ ); */
+
+ addrindex_start_search( _addressIndex_, _queryID_ );
+}
+
+/**
+ * Apply the current selection in the list to the entry field. Focus is also
+ * moved to the next widget so that Tab key works correctly.
+ * \param clist List to process.
+ * \param entry Address entry field.
+ */
static void completion_window_apply_selection(GtkCList *clist, GtkEntry *entry)
{
gchar *address = NULL, *text = NULL;
gint cursor_pos, row;
+ GtkWidget *parent;
g_return_if_fail(clist != NULL);
g_return_if_fail(entry != NULL);
g_return_if_fail(clist->selection != NULL);
+ /* First remove the idler */
+ if( _completionIdleID_ != 0 ) {
+ gtk_idle_remove( _completionIdleID_ );
+ _completionIdleID_ = 0;
+ }
+
+ /* Process selected item */
row = GPOINTER_TO_INT(clist->selection->data);
address = get_address_from_edit(entry, &cursor_pos);
g_free(address);
gtk_clist_get_text(clist, row, 0, &text);
replace_address_in_edit(entry, text, cursor_pos);
+
+ /* Move focus to next widget */
+ parent = GTK_WIDGET(entry)->parent;
+ if( parent ) {
+ gtk_container_focus( GTK_CONTAINER(parent), GTK_DIR_TAB_FORWARD );
+ }
}
-/* should be called when creating the main window containing address
- * completion entries */
+/**
+ * Start address completion. Should be called when creating the main window
+ * containing address completion entries.
+ * \param mainwindow Main window.
+ */
void address_completion_start(GtkWidget *mainwindow)
{
start_address_completion();
mainwindow);
}
-/* Need unique data to make unregistering signal handler possible for the auto
- * completed entry */
+/**
+ * Need unique data to make unregistering signal handler possible for the auto
+ * completed entry.
+ */
#define COMPLETION_UNIQUE_DATA (GINT_TO_POINTER(0xfeefaa))
+/**
+ * Register specified entry widget for address completion.
+ * \param entry Address entry field.
+ */
void address_completion_register_entry(GtkEntry *entry)
{
g_return_if_fail(entry != NULL);
0); /* magic */
}
+/**
+ * Unregister specified entry widget from address completion operations.
+ * \param entry Address entry field.
+ */
void address_completion_unregister_entry(GtkEntry *entry)
{
GtkObject *entry_obj;
COMPLETION_UNIQUE_DATA);
}
-/* should be called when main window with address completion entries
- * terminates.
- * NOTE: this function assumes that it is called upon destruction of
- * the window */
+/**
+ * End address completion. Should be called when main window with address
+ * completion entries terminates. NOTE: this function assumes that it is
+ * called upon destruction of the window.
+ * \param mainwindow Main window.
+ */
void address_completion_end(GtkWidget *mainwindow)
{
/* if address_completion_end() is really called on closing the window,
clear_completion_cache();
}
-/* watch for tabs in one of the address entries. if no tab then clear the
- * completion cache */
+/**
+ * Listener that watches for tab or other keystroke in address entry field.
+ * \param entry Address entry field.
+ * \param ev Event object.
+ * \param data User data.
+ * \return <i>TRUE</i>.
+ */
static gboolean address_completion_entry_key_pressed(GtkEntry *entry,
GdkEventKey *ev,
gpointer data)
{
if (ev->keyval == GDK_Tab) {
- if (address_completion_complete_address_in_entry(entry, TRUE)) {
- address_completion_create_completion_window(entry);
+ addrcompl_clear_queue();
+
+ if( address_completion_complete_address_in_entry( entry, TRUE ) ) {
/* route a void character to the default handler */
/* this is a dirty hack; we're actually changing a key
* reported by the system. */
ev->state &= ~GDK_SHIFT_MASK;
gtk_signal_emit_stop_by_name(GTK_OBJECT(entry),
"key_press_event");
- } else {
+
+ /* Create window */
+ address_completion_create_completion_window(entry);
+
+ /* Start remote queries */
+ addrcompl_start_search();
+ }
+ else {
/* old behaviour */
}
} else if (ev->keyval == GDK_Shift_L
return TRUE;
}
-
-/* initialize the completion cache and put first completed string
- * in entry. this function used to do back cycling but this is not
- * currently used. since the address completion behaviour has been
- * changed regularly, we keep the feature in case someone changes
- * his / her mind again. :) */
+/**
+ * Initialize search term for address completion.
+ * \param entry Address entry field.
+ */
static gboolean address_completion_complete_address_in_entry(GtkEntry *entry,
gboolean next)
{
gint ncount, cursor_pos;
- gchar *address, *new = NULL;
- gboolean completed = FALSE;
+ gchar *searchTerm, *new = NULL;
g_return_val_if_fail(entry != NULL, FALSE);
if (!GTK_WIDGET_HAS_FOCUS(entry)) return FALSE;
/* get an address component from the cursor */
- address = get_address_from_edit(entry, &cursor_pos);
- if (!address) return FALSE;
+ searchTerm = get_address_from_edit( entry, &cursor_pos );
+ if( ! searchTerm ) return FALSE;
+ /* printf( "search for :::%s:::\n", searchTerm ); */
- /* still something in the cache */
- if (is_completion_pending()) {
- new = next ? get_next_complete_address() :
- get_prev_complete_address();
- } else {
- if (0 < (ncount = complete_address(address)))
- new = get_next_complete_address();
+ /* Clear any existing search */
+ if( _compWindow_->searchTerm ) {
+ g_free( _compWindow_->searchTerm );
}
+ _compWindow_->searchTerm = g_strdup( searchTerm );
- if (new) {
- /* prevent "change" signal */
- /* replace_address_in_edit(entry, new, cursor_pos); */
- g_free(new);
- completed = TRUE;
+ /* Perform search on local completion index */
+ ncount = complete_address( searchTerm );
+ if( 0 < ncount ) {
+ new = get_next_complete_address();
+ g_free( new );
}
- g_free(address);
+ /* Make sure that drop-down appears uniform! */
+ if( ncount == 0 ) {
+ addrcompl_add_queue( g_strdup( searchTerm ) );
+ }
+ g_free( searchTerm );
- return completed;
+ return TRUE;
}
-static void address_completion_create_completion_window(GtkEntry *entry_)
+/**
+ * Create new address completion window for specified entry.
+ * \param entry_ Entry widget to associate with window.
+ */
+static void address_completion_create_completion_window( GtkEntry *entry_ )
{
- static GtkWidget *completion_window;
gint x, y, height, width, depth;
GtkWidget *scroll, *clist;
GtkRequisition r;
- guint count = 0;
+ GtkWidget *window;
GtkWidget *entry = GTK_WIDGET(entry_);
- if (completion_window) {
- gtk_widget_destroy(completion_window);
- completion_window = NULL;
- }
-
- scroll = gtk_scrolled_window_new(NULL, NULL);
+ /* Create new window and list */
+ window = gtk_window_new(GTK_WINDOW_POPUP);
clist = gtk_clist_new(1);
- gtk_clist_set_selection_mode(GTK_CLIST(clist), GTK_SELECTION_SINGLE);
-
- completion_window = gtk_window_new(GTK_WINDOW_POPUP);
+ /* Destroy any existing window */
+ addrcompl_destroy_window( _compWindow_ );
+
+ /* Create new object */
+ _compWindow_->window = window;
+ _compWindow_->entry = entry;
+ _compWindow_->clist = clist;
+ _compWindow_->listCount = 0;
+
+ scroll = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
- gtk_container_add(GTK_CONTAINER(completion_window), scroll);
+ gtk_container_add(GTK_CONTAINER(window), scroll);
gtk_container_add(GTK_CONTAINER(scroll), clist);
+ gtk_clist_set_selection_mode(GTK_CLIST(clist), GTK_SELECTION_SINGLE);
- /* set the unique data so we can always get back the entry and
- * clist window to which this completion window has been attached */
- gtk_object_set_data(GTK_OBJECT(completion_window),
- WINDOW_DATA_COMPL_ENTRY, entry_);
- gtk_object_set_data(GTK_OBJECT(completion_window),
- WINDOW_DATA_COMPL_CLIST, clist);
-
- gtk_signal_connect(GTK_OBJECT(clist), "select_row",
- GTK_SIGNAL_FUNC(completion_window_select_row),
- &completion_window);
-
- for (count = 0; count < get_completion_count(); count++) {
- gchar *text[] = {NULL, NULL};
-
- text[0] = get_complete_address(count);
- gtk_clist_append(GTK_CLIST(clist), text);
- g_free(text[0]);
- }
-
+ /* Use entry widget to create initial window */
gdk_window_get_geometry(entry->window, &x, &y, &width, &height, &depth);
gdk_window_get_deskrelative_origin (entry->window, &x, &y);
y += height;
- gtk_widget_set_uposition(completion_window, x, y);
-
- gtk_widget_size_request(clist, &r);
- gtk_widget_set_usize(completion_window, width, r.height);
- gtk_widget_show_all(completion_window);
- gtk_widget_size_request(clist, &r);
+ gtk_widget_set_uposition(window, x, y);
- if ((y + r.height) > gdk_screen_height()) {
- gtk_window_set_policy(GTK_WINDOW(completion_window),
- TRUE, FALSE, FALSE);
- gtk_widget_set_usize(completion_window, width,
- gdk_screen_height () - y);
- }
+ /* Resize window to fit initial (empty) address list */
+ gtk_widget_size_request( clist, &r );
+ gtk_widget_set_usize( window, width, r.height );
+ gtk_widget_show_all( window );
+ gtk_widget_size_request( clist, &r );
- gtk_signal_connect(GTK_OBJECT(completion_window),
+ /* Setup handlers */
+ gtk_signal_connect(GTK_OBJECT(clist), "select_row",
+ GTK_SIGNAL_FUNC(completion_window_select_row),
+ _compWindow_ );
+ gtk_signal_connect(GTK_OBJECT(window),
"button-press-event",
GTK_SIGNAL_FUNC(completion_window_button_press),
- &completion_window);
- gtk_signal_connect(GTK_OBJECT(completion_window),
+ _compWindow_ );
+ gtk_signal_connect(GTK_OBJECT(window),
"key-press-event",
GTK_SIGNAL_FUNC(completion_window_key_press),
- &completion_window);
- gdk_pointer_grab(completion_window->window, TRUE,
+ _compWindow_ );
+ gdk_pointer_grab(window->window, TRUE,
GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK,
NULL, NULL, GDK_CURRENT_TIME);
- gtk_grab_add(completion_window);
+ gtk_grab_add( window );
/* this gets rid of the irritating focus rectangle that doesn't
* follow the selection */
GTK_WIDGET_UNSET_FLAGS(clist, GTK_CAN_FOCUS);
- gtk_clist_select_row(GTK_CLIST(clist), 1, 0);
}
-
-/* row selection sends completed address to entry.
- * note: event is NULL if selected by anything else than a mouse button. */
+/**
+ * Respond to select row event in clist object. selection sends completed
+ * address to entry. Note: event is NULL if selected by anything else than a
+ * mouse button.
+ * \param widget Window object.
+ * \param event Event.
+ * \param compWind Reference to completion window.
+ */
static void completion_window_select_row(GtkCList *clist, gint row, gint col,
GdkEvent *event,
- GtkWidget **completion_window)
+ CompletionWindow *compWin )
{
GtkEntry *entry;
- g_return_if_fail(completion_window != NULL);
- g_return_if_fail(*completion_window != NULL);
+ g_return_if_fail(compWin != NULL);
- entry = GTK_ENTRY(gtk_object_get_data(GTK_OBJECT(*completion_window),
- WINDOW_DATA_COMPL_ENTRY));
+ entry = GTK_ENTRY(compWin->entry);
g_return_if_fail(entry != NULL);
- completion_window_apply_selection(clist, entry);
-
+ /* Don't update unless user actually selects ! */
if (!event || event->type != GDK_BUTTON_RELEASE)
return;
+ /* User selected address by releasing the mouse in drop-down list*/
+ completion_window_apply_selection( clist, entry );
+
clear_completion_cache();
- gtk_widget_destroy(*completion_window);
- *completion_window = NULL;
+ addrcompl_destroy_window( _compWindow_ );
}
-/* completion_window_button_press() - check is mouse click is anywhere
- * else (not in the completion window). in that case the completion
- * window is destroyed, and the original prefix is restored */
+/**
+ * Respond to button press in completion window. Check if mouse click is
+ * anywhere outside the completion window. In that case the completion
+ * window is destroyed, and the original searchTerm is restored.
+ *
+ * \param widget Window object.
+ * \param event Event.
+ * \param compWin Reference to completion window.
+ */
static gboolean completion_window_button_press(GtkWidget *widget,
GdkEventButton *event,
- GtkWidget **completion_window)
+ CompletionWindow *compWin )
{
GtkWidget *event_widget, *entry;
- gchar *prefix;
+ gchar *searchTerm;
gint cursor_pos;
gboolean restore = TRUE;
- g_return_val_if_fail(completion_window != NULL, FALSE);
- g_return_val_if_fail(*completion_window != NULL, FALSE);
+ g_return_val_if_fail(compWin != NULL, FALSE);
- entry = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(*completion_window),
- WINDOW_DATA_COMPL_ENTRY));
+ entry = compWin->entry;
g_return_val_if_fail(entry != NULL, FALSE);
+ /* Test where mouse was clicked */
event_widget = gtk_get_event_widget((GdkEvent *)event);
if (event_widget != widget) {
while (event_widget) {
restore = FALSE;
break;
}
- event_widget = event_widget->parent;
+ event_widget = event_widget->parent;
}
}
if (restore) {
- prefix = get_complete_address(0);
+ /* Clicked outside of completion window - restore */
+ searchTerm = _compWindow_->searchTerm;
g_free(get_address_from_edit(GTK_ENTRY(entry), &cursor_pos));
- replace_address_in_edit(GTK_ENTRY(entry), prefix, cursor_pos);
- g_free(prefix);
+ replace_address_in_edit(GTK_ENTRY(entry), searchTerm, cursor_pos);
}
clear_completion_cache();
- gtk_widget_destroy(*completion_window);
- *completion_window = NULL;
+ addrcompl_destroy_window( _compWindow_ );
return TRUE;
}
+/**
+ * Respond to key press in completion window.
+ * \param widget Window object.
+ * \param event Event.
+ * \param compWind Reference to completion window.
+ */
static gboolean completion_window_key_press(GtkWidget *widget,
GdkEventKey *event,
- GtkWidget **completion_window)
+ CompletionWindow *compWin )
{
GdkEventKey tmp_event;
GtkWidget *entry;
- gchar *prefix;
+ gchar *searchTerm;
gint cursor_pos;
GtkWidget *clist;
- g_return_val_if_fail(completion_window != NULL, FALSE);
- g_return_val_if_fail(*completion_window != NULL, FALSE);
+ g_return_val_if_fail(compWin != NULL, FALSE);
- entry = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(*completion_window),
- WINDOW_DATA_COMPL_ENTRY));
- clist = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(*completion_window),
- WINDOW_DATA_COMPL_CLIST));
+ entry = compWin->entry;
+ clist = compWin->clist;
g_return_val_if_fail(entry != NULL, FALSE);
/* allow keyboard navigation in the alternatives clist */
/* look for presses that accept the selection */
if (event->keyval == GDK_Return || event->keyval == GDK_space) {
+ /* User selected address with a key press */
+
+ /* Display selected address in entry field */
+ completion_window_apply_selection(
+ GTK_CLIST(clist), GTK_ENTRY(entry) );
+
+ /* Discard the window */
clear_completion_cache();
- gtk_widget_destroy(*completion_window);
- *completion_window = NULL;
+ addrcompl_destroy_window( _compWindow_ );
return FALSE;
}
return FALSE;
}
- /* other key, let's restore the prefix (orignal text) */
- prefix = get_complete_address(0);
+ /* some other key, let's restore the searchTerm (orignal text) */
+ searchTerm = _compWindow_->searchTerm;
g_free(get_address_from_edit(GTK_ENTRY(entry), &cursor_pos));
- replace_address_in_edit(GTK_ENTRY(entry), prefix, cursor_pos);
- g_free(prefix);
- clear_completion_cache();
+ replace_address_in_edit(GTK_ENTRY(entry), searchTerm, cursor_pos);
/* make sure anything we typed comes in the edit box */
tmp_event.type = event->type;
gtk_widget_event(entry, (GdkEvent *)&tmp_event);
/* and close the completion window */
- gtk_widget_destroy(*completion_window);
- *completion_window = NULL;
+ clear_completion_cache();
+ addrcompl_destroy_window( _compWindow_ );
return TRUE;
}
+
+/*
+ * ============================================================================
+ * Publically accessible functions.
+ * ============================================================================
+ */
+
+/**
+ * Setup completion object.
+ * \param addrIndex Address index object.
+ */
+void addrcompl_initialize( AddressIndex *addrIndex ) {
+ g_return_if_fail( addrIndex != NULL );
+ _addressIndex_ = addrIndex;
+
+ /* printf( "addrcompl_initialize...\n" ); */
+ if( ! _compWindow_ ) {
+ _compWindow_ = addrcompl_create_window();
+ }
+ _queryID_ = 0;
+ _completionIdleID_ = 0;
+ /* printf( "addrcompl_initialize...done\n" ); */
+}
+
+/**
+ * Teardown completion object.
+ */
+void addrcompl_teardown( void ) {
+ /* printf( "addrcompl_teardown...\n" ); */
+ addrcompl_free_window( _compWindow_ );
+ _compWindow_ = NULL;
+ if( _displayQueue_ ) {
+ g_list_free( _displayQueue_ );
+ }
+ _displayQueue_ = NULL;
+ _completionIdleID_ = 0;
+ _addressIndex_ = NULL;
+ /* printf( "addrcompl_teardown...done\n" ); */
+}
+
+/*
+ * End of Source.
+ */
+
#ifndef __ADDR_COMPL_H__
#define __ADDR_COMPL_H__
-gint start_address_completion (void);
-gint invalidate_address_completion (void);
-
-guint complete_address (const gchar *str);
-
-gchar *get_address_from_edit (GtkEntry *entry,
- gint *start_pos);
-void replace_address_in_edit (GtkEntry *entry,
- const gchar *newtext,
- gint start_pos);
-
-gchar *get_complete_address (gint index);
-
-gchar *get_next_complete_address (void);
-gchar *get_prev_complete_address (void);
-guint get_completion_count (void);
-
-gboolean is_completion_pending (void);
-
-void clear_completion_cache (void);
+#include "addrindex.h"
+gint start_address_completion (void);
+guint complete_address (const gchar *str);
+gchar *get_complete_address (gint index);
gint end_address_completion (void);
/* ui functions */
+void address_completion_start (GtkWidget *mainwindow);
+void address_completion_register_entry (GtkEntry *entry);
+void address_completion_unregister_entry(GtkEntry *entry);
+void address_completion_end (GtkWidget *mainwindow);
-void address_completion_start (GtkWidget *mainwindow);
-void address_completion_register_entry (GtkEntry *entry);
-void address_completion_unregister_entry (GtkEntry *entry);
-void address_completion_end (GtkWidget *mainwindow);
+void addrcompl_initialize ( AddressIndex *addrIndex );
+void addrcompl_teardown ( void );
#endif /* __ADDR_COMPL_H__ */
#define ID_TIME_OFFSET 998000000
-/* Create new address book */
+/**
+ * Create new address book
+ * \return Address book.
+ */
AddressBookFile *addrbook_create_book()
{
AddressBookFile *book;
book->tempList = NULL;
book->tempHash = NULL;
book->addressCache->modified = TRUE;
+
return book;
}
-/* Specify name to be used */
+/**
+ * Specify name to be used
+ * \param book Address book.
+ * \param value Name.
+ */
void addrbook_set_name(AddressBookFile *book, const gchar *value)
{
g_return_if_fail(book != NULL);
return addrcache_get_name(book->addressCache);
}
+/**
+ * Specify path to address book file.
+ * \param book Address book.
+ * \param value Path.
+ */
void addrbook_set_path(AddressBookFile *book, const gchar *value)
{
g_return_if_fail(book != NULL);
addrcache_set_dirty(book->addressCache, TRUE);
}
+/**
+ * Specify filename to be used
+ * \param book Address book.
+ * \param value Filename.
+ */
void addrbook_set_file(AddressBookFile *book, const gchar *value)
{
g_return_if_fail(book != NULL);
return book->addressCache->modified;
}
+/**
+ * Specify book as modified.
+ * \param book Address book.
+ * \param value Indicator.
+ */
void addrbook_set_modified(AddressBookFile *book, const gboolean value)
{
g_return_if_fail(book != NULL);
return book->addressCache->accessFlag;
}
+/**
+ * Specify address book as accessed.
+ * \param book Address book.
+ * \param value Value.
+ */
void addrbook_set_accessed(AddressBookFile *book, const gboolean value)
{
g_return_if_fail(book != NULL);
return book->addressCache->dataRead;
}
+/**
+ * Specify address book as read.
+ * \param book Address book.
+ * \param value Value.
+ */
void addrbook_set_read_flag(AddressBookFile *book, const gboolean value)
{
g_return_if_fail(book != NULL);
return addrcache_get_dirty(book->addressCache);
}
+/**
+ * Set address book as dirty (needs to be written to file).
+ * \param book Address book.
+ * \param value Dirty flag.
+ */
void addrbook_set_dirty(AddressBookFile *book, const gboolean value)
{
g_return_if_fail(book != NULL);
addrcache_set_dirty(book->addressCache, value);
}
-/* Empty address book */
+/**
+ * Empty address book contents.
+ * \param book Address book.
+ */
void addrbook_empty_book(AddressBookFile *book)
{
g_return_if_fail(book != NULL);
book->retVal = MGU_SUCCESS;
}
-/* Free address book */
+/**
+ * Free address book.
+ * \param book Address book.
+ */
void addrbook_free_book(AddressBookFile *book)
{
g_return_if_fail(book != NULL);
/* Clear cache */
- addrcache_clear(book->addressCache);
addrcache_free(book->addressCache);
/* Free up internal objects */
g_free(book);
}
-/* Print list of items */
+/**
+ * Print list of items.
+ * \param book Address book.
+ * \param stream Output stream.
+ */
void addrbook_print_item_list(GList *list, FILE *stream)
{
GList *node = list;
fprintf(stream, "\t---\n");
}
-/* Print address book */
+/**
+ * Print address book header.
+ * \param book Address book.
+ * \param stream Output stream.
+ */
void addrbook_print_book(AddressBookFile *book, FILE *stream)
{
g_return_if_fail(book != NULL);
addrcache_print(book->addressCache, stream);
}
-/* Dump entire address book traversing folders */
+/**
+ * Dump entire address book traversing folders.
+ * \param book Address book.
+ * \param stream Output stream.
+ */
void addrbook_dump_book(AddressBookFile *book, FILE *stream)
{
ItemFolder *folder;
addritem_print_item_folder(folder, stream);
}
-/* Remove group from address book.
- param: group Group to remove.
- return: Group, or NULL if not found.
- Note that object should still be freed */
+/**
+ * Remove specified group from address book. Note that object should still
+ * be freed.
+ * Specify name to be used
+ * \param book Address book.
+ * \param group Group to remove.
+ * \param value Name.
+ * \return Group, or NULL if not found.
+ */
ItemGroup *addrbook_remove_group(AddressBookFile *book, ItemGroup *group)
{
g_return_val_if_fail(book != NULL, NULL);
return addrcache_remove_group(book->addressCache, group);
}
-/* Remove specified person from address book.
- param: person Person to remove.
- return: Person, or NULL if not found.
- Note that object should still be freed */
+/**
+ * Remove specified person from address book. Note that object should still
+ * be freed.
+ * \param book Address book.
+ * \param person Person to remove.
+ * \return Person, or NULL if not found.
+ */
ItemPerson *addrbook_remove_person(AddressBookFile *book, ItemPerson *person)
{
g_return_val_if_fail(book != NULL, NULL);
return addrcache_remove_person(book->addressCache, person);
}
-/* Remove email address in address book for specified person.
- param: person Person.
- email EMail to remove.
- return: EMail object, or NULL if not found.
- Note that object should still be freed */
+/**
+ * Remove specified email address in address book for specified person.
+ * Note that object should still be freed.
+ * \param book Address book.
+ * \param person Person.
+ * \param email EMail to remove.
+ * \return EMail object, or NULL if not found.
+ */
ItemEMail *addrbook_person_remove_email(AddressBookFile *book,
ItemPerson *person, ItemEMail *email)
{
return addrcache_person_remove_email(book->addressCache, person, email);
}
-/* **********************************************************************
+/*
+* ***********************************************************************
* Read/Write XML data file...
* ===========================
* Notes:
#define AB_ATTAG_VAL_GROUP "group"
#define AB_ATTAG_VAL_FOLDER "folder"
-/* Parse address item for person */
+/**
+ * Parse address item for person from XML file.
+ * \param book Address book.
+ * \param file XML file handle.
+ * \param person Person.
+ */
static void addrbook_parse_address(AddressBookFile *book, XMLFile *file,
ItemPerson *person)
{
}
}
-/* Parse email address list */
+/**
+ * Parse list of email address for person from XML file.
+ * \param book Address book.
+ * \param file XML file handle.
+ * \param person Person.
+ */
static void addrbook_parse_addr_list(AddressBookFile *book, XMLFile *file,
ItemPerson *person)
{
}
}
-/* Parse attibute for person */
+/**
+ * Parse attribute for person from XML file.
+ * \param book Address book.
+ * \param file XML file handle.
+ * \param person Person.
+ */
static void addrbook_parse_attribute(XMLFile *file, ItemPerson *person)
{
GList *attr;
}
}
-/* Parse attribute list */
+/**
+ * Parse list of attributes for person from XML file.
+ * \param book Address book.
+ * \param file XML file handle.
+ * \param person Person.
+ */
static void addrbook_parse_attr_list(AddressBookFile *book, XMLFile *file,
ItemPerson *person)
{
}
}
-/* Parse person */
+/**
+ * Parse person from XML file.
+ * \param book Address book.
+ * \param file XML file handle.
+ */
static void addrbook_parse_person(AddressBookFile *book, XMLFile *file)
{
GList *attr;
}
}
-/* Parse group member */
+/**
+ * Parse group member from XML file.
+ * \param book Address book.
+ * \param file XML file handle.
+ * \param group Group.
+ */
static void addrbook_parse_member(AddressBookFile *book, XMLFile *file,
ItemGroup *group)
{
GList *attr;
gchar *name, *value;
- gchar *pid = NULL, *eid = NULL;
+ gchar *eid = NULL;
+ /* gchar *pid = NULL; */
ItemEMail *email = NULL;
attr = xml_get_current_tag_attr(file);
while (attr) {
name = ((XMLAttr *)attr->data)->name;
value = ((XMLAttr *)attr->data)->value;
+ /*
if (strcmp(name, AB_ATTAG_PID) == 0)
pid = g_strdup(value);
else if (strcmp(name, AB_ATTAG_EID) == 0)
eid = g_strdup(value);
+ */
+ if( strcmp( name, AB_ATTAG_EID ) == 0 )
+ eid = g_strdup( value );
attr = g_list_next(attr);
}
/* email = addrcache_get_email( book->addressCache, pid, eid ); */
}
}
-/* Parse group member list */
+/**
+ * Parse list of group members from XML file.
+ * \param book Address book.
+ * \param file XML file handle.
+ * \param group Group.
+ */
static void addrbook_parse_member_list(AddressBookFile *book, XMLFile *file,
ItemGroup *group)
{
}
}
-/* Parse group */
+/**
+ * Parse group object from XML file.
+ * \param book Address book.
+ * \param file XML file handle.
+ */
static void addrbook_parse_group(AddressBookFile *book, XMLFile *file)
{
GList *attr;
}
}
-/* Parse folder item */
+/**
+ * Parse folder item from XML file.
+ * \param book Address book.
+ * \param file XML file handle.
+ * \param folder Folder.
+ */
static void addrbook_parse_folder_item(AddressBookFile *book, XMLFile *file,
ItemFolder *folder)
{
}
}
-/* Parse folder item list */
+/**
+ * Parse list of folder items from XML file.
+ * \param book Address book.
+ * \param file XML file handle.
+ * \param folder Folder.
+ */
static void addrbook_parse_folder_list(AddressBookFile *book, XMLFile *file,
ItemFolder *folder)
{
}
}
-/* Parse folder */
+/**
+ * Parse folder from XML file.
+ * \param book Address book.
+ * \param file XML file handle.
+ */
static void addrbook_parse_folder(AddressBookFile *book, XMLFile *file)
{
GList *attr;
}
}
-/* Parse address book.
- Return: TRUE if data read successfully, FALSE if error reading data */
+/**
+ * Read address book (DOM) tree from file.
+ * \param book Address book.
+ * \param file XML file handle.
+ * \return <i>TRUE</i> if data read successfully, <i>FALSE</i> if error
+ * reading data.
+ */
static gboolean addrbook_read_tree(AddressBookFile *book, XMLFile *file)
{
gboolean retVal;
return retVal;
}
-/* Resolve folder items visitor function */
+/**
+ * Resolve folder items callback function.
+ * \param key Table key.
+ * \param value Reference to object contained in folder.
+ * \param data Reference to address book.
+ */
static void addrbook_res_items_vis(gpointer key, gpointer value, gpointer data)
{
AddressBookFile *book = data;
}
}
-/* Resolve folder items. Lists of UID's are replaced with pointers to
- data items */
+/**
+ * Resolve folder items. Lists of UID's are replaced with pointers to
+ * data items.
+ * \param book Address book.
+ */
static void addrbook_resolve_folder_items(AddressBookFile *book)
{
GList *nodeFolder = NULL;
book->tempList = NULL;
}
-/* Read address book file */
+/**
+ * Read address book.
+ * \param book Address book.
+ * \return Status code.
+ */
gint addrbook_read_data(AddressBookFile *book)
{
XMLFile *file = NULL;
return book->retVal;
}
+/**
+ * Write start element to file.
+ * \param fp File handle.
+ * \param lvl Indent level.
+ * \param name Element name.
+ */
static void addrbook_write_elem_s(FILE *fp, gint lvl, gchar *name)
{
gint i;
fputs(name, fp);
}
+/**
+ * Write end element to file.
+ * \param fp File handle.
+ * \param lvl Indent level.
+ * \param name Element name.
+ */
static void addrbook_write_elem_e(FILE *fp, gint lvl, gchar *name)
{
gint i;
fputs(">\n", fp);
}
+/**
+ * Write attribute name/value pair to file.
+ * \param fp File handle.
+ * \param name Attribute name.
+ * \param value Attribute value.
+ */
static void addrbook_write_attr(FILE *fp, gchar *name, gchar *value)
{
fputs(" ", fp);
fputs("\"", fp);
}
-/* Write file hash table visitor function */
+/**
+ * Write person and associated addresses and attributes to file.
+ * file hash table visitor function.
+ * \param key Table key.
+ * \param value Reference to person.
+ * \param data File pointer.
+ */
static void addrbook_write_item_person_vis(gpointer key, gpointer value,
gpointer data)
{
}
}
-/* Write file hash table visitor function */
+/**
+ * Write group and associated references to addresses to file.
+ * file hash table visitor function.
+ * \param key Table key.
+ * \param value Reference to group.
+ * \param data File pointer.
+ */
static void addrbook_write_item_group_vis(gpointer key, gpointer value,
gpointer data)
{
}
}
-/* Write file hash table visitor function */
+/**
+ * Write folder and associated references to addresses to file.
+ * file hash table visitor function.
+ * \param key Table key.
+ * \param value Reference to folder.
+ * \param data File pointer.
+ */
static void addrbook_write_item_folder_vis(gpointer key, gpointer value,
gpointer data)
{
}
}
-/* Output address book data to specified file.
- return: Status code */
+/**
+ * Output address book data to specified file.
+ * \param book Address book.
+ * \param newFile Filename of new file (in book's filepath).
+ * \return Status code.
+ */
gint addrbook_write_to(AddressBookFile *book, gchar *newFile)
{
FILE *fp;
return book->retVal;
}
-/* Output address book data to original file.
- return: Status code */
+/**
+ * Output address book data to original file.
+ * \param book Address book.
+ * \return Status code.
+ */
gint addrbook_save_data(AddressBookFile *book)
{
g_return_val_if_fail(book != NULL, -1);
return book->retVal;
}
-/* **********************************************************************
- Address book edit interface functions...
- ***********************************************************************
- Move person's email item.
- param: book Address book.
- person Person.
- itemMove Item to move.
- itemTarget Target item before which to move item */
+/*
+ * **********************************************************************
+ * Address book edit interface functions.
+ * **********************************************************************
+ */
+
+/**
+ * Move email item within list of person's email items.
+ * \param book Address book.
+ * \param person Person.
+ * \param itemMove EMail item to move.
+ * \param itemTarget EMail item to move before.
+ * \return Moved item.
+ */
ItemEMail *addrbook_move_email_before(AddressBookFile *book, ItemPerson *person,
ItemEMail *itemMove, ItemEMail *itemTarget)
{
return email;
}
-/* Move person's email item.
- param: book Address book.
- person Person.
- itemMove Item to move.
- itemTarget Target item after which to move item */
+/**
+ * Move email item within list of person's email items.
+ * \param book Address book.
+ * \param person Person.
+ * \param itemMove EMail item to move.
+ * \param itemTarget EMail item after which to move.
+ * \return Moved item.
+ */
ItemEMail *addrbook_move_email_after(AddressBookFile *book, ItemPerson *person,
ItemEMail *itemMove, ItemEMail *itemTarget)
{
return email;
}
-/* Hash table visitor function for deletion of hashtable entries */
+/**
+ * Hash table callback function for simple deletion of hashtable entries.
+ * \param key Table key (will be freed).
+ * \param value Value stored in table.
+ * \param data User data.
+ * \return <i>TRUE</i> to indicate that entry freed.
+ */
static gboolean addrbook_free_simple_hash_vis(gpointer *key, gpointer *value,
gpointer *data)
{
return TRUE;
}
-/* Update address book email list for specified person.
- Enter: book Address book.
- person Person to update.
- listEMail List of new email addresses.
- Note: The existing email addresses are replaced with the new addresses. Any references
- to old addresses in the groups are re-linked to the new addresses. All old addresses
- linked to the person are removed */
+/**
+ * Update address book email list for specified person. Note: The existing
+ * email addresses are replaced with the new addresses. Any references to
+ * old addresses in the groups are re-linked to the new addresses. All old
+ * addresses linked to the person are removed.
+ * \param book Address book.
+ * \param person Person to update.
+ * \param listEMail List of new email addresses.
+ */
void addrbook_update_address_list(AddressBookFile *book, ItemPerson *person,
GList *listEMail)
{
}
-/* Add person and address data to address book.
- Enter: book Address book.
- folder Folder where to add person, or NULL for root folder.
- listEMail New list of email addresses.
- Return: Person added.
- Note: A new person is created with specified list of email addresses. All objects inserted
- into address book */
+/**
+ * Create person object and add person with specified address data to address
+ * book. Note: A new person is created with specified list of email addresses.
+ * All objects inserted into address book.
+ *
+ * \param book Address book.
+ * \param folder Parent folder where to add person, or <i>NULL</i> for
+ * root folder.
+ * \param listEMail List of new email addresses to associate with person.
+ * \return Person object created.
+ */
ItemPerson *addrbook_add_address_list(AddressBookFile *book, ItemFolder *folder,
GList *listEMail)
{
return person;
}
-/* Build available email list visitor function */
+/**
+ * Build available email list visitor function.
+ * \param key Table key.
+ * \param value Value stored in table.
+ * \param data Reference to address book.
+ */
static void addrbook_build_avail_email_vis(gpointer key, gpointer value,
gpointer data)
{
}
}
-/* Return link list of available email items (which have not already been linked to
- groups). Note that the list contains references to items and should be g_free()
- when done. Do *NOT* attempt to used the addrbook_free_xxx() functions... this will
- destroy the addressbook data!
- Return: List of items, or NULL if none */
+/**
+ * Return link list of available email items that have not already been linked
+ * to groups. Note that the list contains references to items and should be
+ * <code>g_free()</code> when done. Do <b>*NOT*</b> attempt to used the
+ * <code>addrbook_free_xxx()<code> functions... this will destroy the
+ * addressbook data!
+ *
+ * \param book Address book.
+ * \param group Group to process.
+ * \return List of items, or <i>NULL</i> if none.
+ */
GList *addrbook_get_available_email_list(AddressBookFile *book, ItemGroup *group)
{
GList *list = NULL;
return list;
}
-/* Update address book email list for specified group.
- Enter: book Address book.
- group group to update.
- listEMail New list of email addresses. This should *NOT* be g_free() when done.
- Note: The existing email addresses are replaced with the new addresses. Any references
- to old addresses in the groups are re-linked to the new addresses. All old addresses
- linked to the person are removed */
+/**
+ * Update address book email list for specified group. Note: The existing email
+ * addresses are replaced with the new addresses. Any references to old addresses
+ * in the groups are re-linked to the new addresses. All old addresses linked to
+ * the person are removed.
+ *
+ * \param book Address book.
+ * \param group Group to process.
+ * \param listEMail List of email items. This should <b>*NOT*</b> be
+ * <code>g_free()</code> when done.
+ */
void addrbook_update_group_list(AddressBookFile *book, ItemGroup *group,
GList *listEMail)
{
oldData = NULL;
}
-/* Add group and email list to address book.
- Enter: book Address book.
- folder Parent folder, or NULL for root folder.
- listEMail New list of email addresses. This should *NOT* be g_free() when done.
- Return: Group object.
- Note: The existing email addresses are replaced with the new addresses. Any references
- to old addresses in the groups are re-linked to the new addresses. All old addresses
- linked to the person are removed */
+/**
+ * Create group object and add with specifed list of email addresses to
+ * address book. Note: The existing email addresses are replaced with the new
+ * addresses. Any references to old addresses in the groups are re-linked to
+ * the new addresses. All old addresses linked to the person are removed.
+ *
+ * \param book Address book.
+ * \param folder Parent folder where to add group, or <i>NULL</i> for
+ * root folder.
+ * \param listEMail List of email items. This should <b>*NOT*</b> be
+ * <code>g_free()</code> when done.
+ * \return Group object created.
+ */
ItemGroup *addrbook_add_group_list(AddressBookFile *book, ItemFolder *folder,
GList *listEMail)
{
return group;
}
-/* Add new folder to address book.
- Enter: book Address book.
- parent Parent folder.
- Return: Folder that was added. This should *NOT* be g_free() when done */
+/**
+ * Create a new folder and add to address book.
+ * \param book Address book.
+ * \param folder Parent folder where to add folder, or <i>NULL</i> for
+ * root folder.
+ * \return Folder that was created. This should <b>*NOT*</b> be
+ * <code>g_free()</code> when done.
+ */
ItemFolder *addrbook_add_new_folder(AddressBookFile *book, ItemFolder *parent)
{
ItemFolder *folder = NULL;
return folder;
}
-/* Update address book attribute list for specified person.
- Enter: book Address book.
- person Person to update.
- listAttrib New list of attributes.
- Note: The existing email addresses are replaced with the new addresses. All old attributes
- linked to the person are removed */
+/**
+ * Update address book attribute list for specified person. Note: The existing
+ * attributes are replaced with the new addresses. All old attributes linked
+ * to the person are removed.
+ *
+ * \param book Address book.
+ * \param person Person to receive attributes.
+ * \param listAttrib New list of attributes.
+ */
void addrbook_update_attrib_list(AddressBookFile *book, ItemPerson *person,
GList *listAttrib)
{
oldData = NULL;
}
-/*
-* Add attribute data for person to address book.
-* Enter: book Address book.
-* person New person object.
-* listAttrib New list of attributes.
-* Note: Only attributes are inserted into address book.
-*/
+/**
+ * Add attribute data for specified person to address book. Note: Only
+ * attributes are inserted into address book.
+ * \param book Address book.
+ * \param person Person to receive attributes.
+ * \param listAttrib List of attributes.
+ */
void addrbook_add_attrib_list( AddressBookFile *book, ItemPerson *person, GList *listAttrib ) {
GList *node;
addrcache_set_dirty( book->addressCache, TRUE );
}
-/* Return address book file for specified object.
- Enter: aio Book item object.
- Return: Address book, or NULL if not found */
+/*
+ * Return reference to address book file for specified object by traversing up
+ * address book heirarchy.
+ *
+ * \param aio Book item object.
+ * \return Address book, or <i>NULL</i> if not found.
+ */
AddressBookFile *addrbook_item_get_bookfile(AddrItemObject *aio)
{
AddressBookFile *book = NULL;
return book;
}
-/* Remove folder from address book. Children are re-parented to parent folder.
- param: folder Folder to remove.
- return: Folder, or NULL if not found. Note that object should still be freed */
+/**
+ * Remove folder from address book. Children are re-parented to the parent
+ * folder.
+ * \param book Address book.
+ * \param folder Folder to remove.
+ * \return Folder, or <i>NULL</i> if not found. Note that object should still
+ * be freed.
+ */
ItemFolder *addrbook_remove_folder(AddressBookFile *book, ItemFolder *folder)
{
ItemFolder *f;
return f;
}
-/* Remove folder from address book. Children are deleted.
- param: folder Folder to remove.
- return: Folder, or NULL if not found. Note that object should still be freed */
+/**
+ * Remove folder from address book. Children are deleted.
+ * \param book Address book.
+ * \param folder Folder to remove.
+ * \return Folder, or <i>NULL</i> if not found. Note that object should still
+ * be freed.
+ */
ItemFolder *addrbook_remove_folder_delete(AddressBookFile *book,
ItemFolder *folder)
{
#define WORK_BUFLEN 1024
#define ADDRBOOK_DIGITS "0123456789"
-/* Return list of existing address book files.
- Enter: book Address book file.
- Return: File list */
+/**
+ * Return list of existing address book files.
+ * \param book Address book.
+ * \return List of files (as strings).
+ */
GList *addrbook_get_bookfile_list(AddressBookFile *book) {
gchar *adbookdir;
DIR *dp;
strcat(buf, entry->d_name);
stat(buf, &statbuf);
if (S_IFREG & statbuf.st_mode) {
- if (strncmp(entry->d_name, ADDRBOOK_PREFIX, lenpre) == 0) {
- if (strncmp((entry->d_name) + lennum, ADDRBOOK_SUFFIX, lensuf) == 0) {
- strncpy(numbuf, (entry->d_name) + lenpre, FILE_NUMDIGITS);
+ if (strncmp(
+ entry->d_name,
+ ADDRBOOK_PREFIX, lenpre) == 0)
+ {
+ if (strncmp(
+ (entry->d_name) + lennum,
+ ADDRBOOK_SUFFIX, lensuf) == 0)
+ {
+ strncpy(numbuf,
+ (entry->d_name) + lenpre,
+ FILE_NUMDIGITS);
numbuf[FILE_NUMDIGITS] = '\0';
flg = TRUE;
for(i = 0; i < FILE_NUMDIGITS; i++) {
val = strtol(numbuf, &endptr, 10);
if (endptr && val > -1) {
if (val > maxval) maxval = val;
- fileList = g_list_append(fileList, g_strdup(entry->d_name));
+ fileList = g_list_append(
+ fileList,
+ g_strdup(entry->d_name));
}
}
}
return fileList;
}
-/* Return file name for specified file number.
- Enter: fileNum File number.
- Return: File name, or NULL if file number too large. Should be g_free() when done */
+/**
+ * Return file name for specified file number.
+ * \param fileNum File number.
+ * \return File name, or <i>NULL</i> if file number too large. Should be
+ * <code>g_free()</code> when done.
+ */
gchar *addrbook_gen_new_file_name(gint fileNum) {
gchar fmt[30];
gchar buf[WORK_BUFLEN];
return g_strdup(buf);
}
-/* **********************************************************************
- Address book test functions...
- **********************************************************************
-*/
-
/*
-* Test email address list.
-*/
+ * **********************************************************************
+ * Address book test functions...
+ * **********************************************************************
+ */
+
+/**
+ * Attempt to parse list of email address from file.
+ * \param book Address book.
+ * \param file XML file handle.
+ */
static void addrbook_chkparse_addr_list( AddressBookFile *book, XMLFile *file ){
guint prev_level;
GList *attr;
}
}
-/* Test user attributes for person */
+/**
+ * Attempt to parse attributes for person address from file.
+ * \param book Address book.
+ * \param file XML file handle.
+ */
static void addrbook_chkparse_attribute(AddressBookFile *book, XMLFile *file)
{
GList *attr;
/* printf( "\t\tattrib value : %s\n", element ); */
}
-/* Test attribute list */
+/**
+ * Attempt to parse list of attributes for person address from file.
+ * \param book Address book.
+ * \param file XML file handle.
+ */
static void addrbook_chkparse_attr_list(AddressBookFile *book, XMLFile *file)
{
guint prev_level;
}
}
-/* Test person */
+/**
+ * Attempt to parse person from file.
+ * \param book Address book.
+ * \param file XML file handle.
+ */
static void addrbook_chkparse_person(AddressBookFile *book, XMLFile *file)
{
GList *attr;
addrbook_chkparse_attr_list(book, file);
}
-/* Test group member list */
+/**
+ * Attempt to parse list of members from file.
+ * \param book Address book.
+ * \param file XML file handle.
+ */
static void addrbook_chkparse_member_list(AddressBookFile *book, XMLFile *file)
{
GList *attr;
}
}
-/* Test group */
+/**
+ * Attempt to parse group from file.
+ * \param book Address book.
+ * \param file XML file handle.
+ */
static void addrbook_chkparse_group(AddressBookFile *book, XMLFile *file)
{
GList *attr;
addrbook_chkparse_member_list(book, file);
}
-/* Test folder item list */
+/**
+ * Attempt to parse list of folders from file.
+ * \param book Address book.
+ * \param file XML file handle.
+ */
static void addrbook_chkparse_folder_list(AddressBookFile *book, XMLFile *file)
{
GList *attr;
}
}
-/* Test folder */
+/**
+ * Attempt to parse a folder from file.
+ * \param book Address book.
+ * \param file XML file handle.
+ */
static void addrbook_chkparse_folder(AddressBookFile *book, XMLFile *file)
{
GList *attr;
addrbook_chkparse_folder_list(book, file);
}
-/* Test address book */
+/**
+ * Attempt to parse (DOM) tree from file.
+ * \param book Address book.
+ * \param file XML file handle.
+ */
static gboolean addrbook_chkread_tree(AddressBookFile *book, XMLFile *file)
{
GList *attr;
return retVal;
}
-/* Test address book file by parsing contents.
- Enter: book Address book file to check.
- fileName File name to check.
- Return: MGU_SUCCESS if file appears to be valid format */
+/**
+ * Test address book file by parsing contents.
+ * \param book Address book.
+ * \param fileName Filename of XML file.
+ * \return Status code <i>MGU_SUCCESS</i> if file appears to be valid format.
+ */
gint addrbook_test_read_file(AddressBookFile *book, gchar *fileName)
{
XMLFile *file = NULL;
return book->retVal;
}
-/* Return link list of all persons in address book. Note that the list contains
- references to items. Do *NOT* attempt to use the addrbook_free_xxx() functions...
- this will destroy the addressbook data!
- Return: List of items, or NULL if none */
+/**
+ * Return link list of all persons in address book. Note that the list
+ * contains references to items. Do <b>*NOT*</b> attempt to use the
+ * <code>addrbook_free_xxx()</code> functions... this will destroy the
+ * addressbook data!
+ * \param book Address book.
+ * \return List of persons, or NULL if none.
+ */
GList *addrbook_get_all_persons(AddressBookFile *book)
{
g_return_val_if_fail(book != NULL, NULL);
return addrcache_get_all_persons(book->addressCache);
}
-/* Add person and address data to address book.
- Enter: book Address book.
- folder Folder where to add person, or NULL for root folder.
- name Common name.
- address EMail address.
- remarks Remarks.
- Return: Person added. Do not *NOT* to use the addrbook_free_xxx() functions...
- this will destroy the address book data */
+/**
+ * Add person and address data to address book.
+ * \param book Address book.
+ * \param folder Folder where to add person, or NULL for root folder.
+ * \param name Common name.
+ * \param address EMail address.
+ * \param remarks Remarks.
+ * \return Person added. Do not <b>*NOT*</b> to use the
+ * <code>addrbook_free_xxx()</code> functions... this will destroy
+ * the address book data.
+ */
ItemPerson *addrbook_add_contact(AddressBookFile *book, ItemFolder *folder,
const gchar *name,const gchar *address,
const gchar *remarks)
{
+ ItemPerson *person;
+
g_return_val_if_fail(book != NULL, NULL);
- return addrcache_add_contact(book->addressCache, folder, name, address,
- remarks);
+ person = addrcache_add_contact(
+ book->addressCache, folder, name, address, remarks );
+ return person;
}
-/* Return file name for next address book file.
- Enter: book Address book.
- Return: File name, or NULL if could not create. This should be g_free()
- when done */
+/**
+ * Return file name for next address book file.
+ * \param book Address book.
+ * \return File name, or <i>NULL</i> if could not create. This should be
+ * <code>g_free()</code> when done.
+ */
gchar *addrbook_guess_next_file(AddressBookFile *book)
{
gchar *newFile = NULL;
fileList = NULL;
return newFile;
}
+
+/*
+* End of Source.
+*/
+
+
#ifdef USE_LDAP
#include <pthread.h>
-#include "syldap.h"
+#include "ldapserver.h"
#include "editldap.h"
#define ADDRESSBOOK_LDAP_BUSYMSG "Busy"
GtkCTreeNode *node);
#ifdef USE_LDAP
-static void addressbook_ldap_show_message (SyldapServer *server);
+static void addressbook_ldap_show_message ( LdapServer *server );
#endif
/* LUT's and IF stuff */
addrclip_free( _clipBoard_ );
}
if( _addressIndex_ != NULL ) {
- addrindex_free_index( _addressIndex_ );
+ addrindex_free_index( _addressIndex_ );
+ addrindex_teardown( _addressIndex_ );
}
_addressSelect_ = NULL;
_clipBoard_ = NULL;
}
if( address ) {
if( name && name[0] != '\0' ) {
- if( name[0] != '"' && strpbrk( name, ",.[]<>" ) != NULL )
+ if( strchr_with_skip_quote( name, '"', ',' ) )
buf = g_strdup_printf( "\"%s\" <%s>", name, address );
else
buf = g_strdup_printf( "%s <%s>", name, address );
}
}
-static void addressbook_folder_load_one_person( GtkCTree *clist, ItemPerson *person,
- AddressTypeControlItem *atci, AddressTypeControlItem *atciMail) {
-
+static void addressbook_folder_load_one_person(
+ GtkCTree *clist, ItemPerson *person,
+ AddressTypeControlItem *atci,
+ AddressTypeControlItem *atciMail )
+{
GtkCTreeNode *nodePerson = NULL;
GtkCTreeNode *nodeEMail = NULL;
gchar *text[N_COLS];
addrbook.listSelected = NULL;
gtk_ctree_remove_node( clist, node );
addressbook_menubar_set_sensitive( FALSE );
- addressbook_menuitem_set_sensitive( gtk_ctree_node_get_row_data(
- GTK_CTREE(clist), addrbook.treeSelected ), addrbook.treeSelected );
+ addressbook_menuitem_set_sensitive(
+ gtk_ctree_node_get_row_data(
+ GTK_CTREE(clist), addrbook.treeSelected ),
+ addrbook.treeSelected );
}
static void addressbook_folder_refresh_one_person( GtkCTree *clist, ItemPerson *person ) {
/* Load root folder */
ItemFolder *rootFolder = NULL;
rootFolder = addrindex_ds_get_root_folder( ds );
- addressbook_folder_load_person( ctreelist, addrindex_ds_get_root_folder( ds ) );
- addressbook_folder_load_group( ctreelist, addrindex_ds_get_root_folder( ds ) );
+ addressbook_folder_load_person(
+ ctreelist, addrindex_ds_get_root_folder( ds ) );
+ addressbook_folder_load_group(
+ ctreelist, addrindex_ds_get_root_folder( ds ) );
}
}
else {
}
void addressbook_ads_set_name( AdapterDSource *adapter, gchar *value ) {
- ADDRESS_OBJECT_NAME(adapter) = mgu_replace_string( ADDRESS_OBJECT_NAME(adapter), value );
+ ADDRESS_OBJECT_NAME(adapter) =
+ mgu_replace_string( ADDRESS_OBJECT_NAME(adapter), value );
}
/*
ds = nodeDS->data;
newNode = NULL;
name = addrindex_ds_get_name( ds );
- ads = addressbook_create_ds_adapter( ds, atci->objectType, name );
- newNode = addressbook_add_object( node, ADDRESS_OBJECT(ads) );
+ ads = addressbook_create_ds_adapter(
+ ds, atci->objectType, name );
+ newNode = addressbook_add_object(
+ node, ADDRESS_OBJECT(ads) );
nodeDS = g_list_next( nodeDS );
}
gtk_ctree_expand( ctree, node );
}
addrIndex = addrindex_create_index();
+ addrindex_initialize( addrIndex );
/* Use new address book index. */
addrindex_set_file_path( addrIndex, get_rc_dir() );
* Return: Inserted node.
*/
static GtkCTreeNode *addressbook_node_add_folder(
- GtkCTreeNode *node, AddressDataSource *ds, ItemFolder *itemFolder, AddressObjectType otype )
+ GtkCTreeNode *node, AddressDataSource *ds,
+ ItemFolder *itemFolder, AddressObjectType otype )
{
GtkCTree *ctree = GTK_CTREE(addrbook.ctree);
GtkCTreeNode *newNode = NULL;
}
}
-static void addressbook_ldap_show_message( SyldapServer *svr ) {
+static void addressbook_ldap_show_message( LdapServer *svr ) {
gchar *name;
gchar *desc;
*addressbook_msgbuf = '\0';
if( svr ) {
- name = syldap_get_name( svr );
- if( svr->busyFlag ) {
+ name = ldapsvr_get_name( svr );
+ if( svr->retVal == MGU_SUCCESS ) {
g_snprintf( addressbook_msgbuf,
- sizeof(addressbook_msgbuf), "%s: %s", name,
- ADDRESSBOOK_LDAP_BUSYMSG );
+ sizeof(addressbook_msgbuf), "%s",
+ name );
}
else {
- if( svr->retVal == MGU_SUCCESS ) {
- g_snprintf( addressbook_msgbuf,
- sizeof(addressbook_msgbuf), "%s",
- name );
- }
- else {
- desc = addressbook_err2string(
- _lutErrorsLDAP_, svr->retVal );
- g_snprintf( addressbook_msgbuf,
- sizeof(addressbook_msgbuf),
- "%s: %s", name, desc );
- }
+ desc = addressbook_err2string(
+ _lutErrorsLDAP_, svr->retVal );
+ g_snprintf( addressbook_msgbuf,
+ sizeof(addressbook_msgbuf),
+ "%s: %s", name, desc );
}
}
addressbook_status_show( addressbook_msgbuf );
}
-static void addressbook_ldap_show_results( SyldapServer *sls ) {
+static void addressbook_ldap_show_results( LdapServer *server ) {
GtkCTree *ctree = GTK_CTREE(addrbook.ctree);
AddressObject *obj;
AdapterDSource *ads = NULL;
AddressDataSource *ds = NULL;
AddressInterface *iface = NULL;
- if( sls == NULL ) return;
+ if( server == NULL ) return;
if( ! addrbook.treeSelected ) return;
if( GTK_CTREE_ROW( addrbook.treeSelected )->level == 1 ) return;
if( obj->type == ADDR_DATASOURCE ) {
ads = ADAPTER_DSOURCE(obj);
if( ads->subType == ADDR_LDAP ) {
- SyldapServer *server;
+ LdapServer *ldapSvr;
ds = ads->dataSource;
if( ds == NULL ) return;
iface = ds->interface;
if( ! iface->haveLibrary ) return;
server = ds->rawDataSource;
- if( server == sls ) {
+ if( ldapSvr == server ) {
/* Read from cache */
gtk_widget_show_all(addrbook.window);
addressbook_set_clist( obj );
- addressbook_ldap_show_message( sls );
+ addressbook_ldap_show_message( server );
gtk_widget_show_all(addrbook.window);
gtk_entry_set_text( GTK_ENTRY(addrbook.entry), "" );
}
}
}
+static gint _idleID_ = 0;
+static gchar *_tempMessage_ = "Busy searching LDAP...";
+
/*
* LDAP idle function. This function is called during UI idle time while
* an LDAP search is in progress.
* Enter: data Reference to LDAP server object.
*/
static void addressbook_ldap_idle( gpointer data ) {
- SyldapServer *server;
-
- server = ( SyldapServer * ) data;
- if( ! server->busyFlag ) {
- /* Server has completed search - remove from idle list */
- gtk_idle_remove( server->idleId );
+}
- /* Process callback and free up the thread */
- addressbook_ldap_show_results( server );
- g_free( server->thread );
- server->thread = NULL;
+/*
+ * LDAP search completion function.
+ */
+static void addressbook_ldap_idle_end( void ) {
+ /* Server has completed search - remove from idle list */
+ printf( "addressbook_ldap_idle_end... completed" );
+ if( _idleID_ != 0 ) {
+ gtk_idle_remove( _idleID_ );
}
+ _idleID_ = 0;
}
/*
static void addressbook_ldap_lookup( AdapterDSource *ads, gchar *sLookup ) {
AddressDataSource *ds = NULL;
AddressInterface *iface = NULL;
- SyldapServer *server;
+ LdapServer *server;
+ printf( "addressbook_ldap_lookup/Searching for '%s'\n", sLookup );
ds = ads->dataSource;
if( ds == NULL ) return;
iface = ds->interface;
if( ! iface->haveLibrary ) return;
server = ds->rawDataSource;
if( server ) {
- syldap_cancel_read( server );
+ printf( "addressbook_ldap_lookup/Starting.../1\n" );
if( *sLookup == '\0' || strlen( sLookup ) < 1 ) return;
- syldap_set_search_value( server, sLookup );
- server->idleId = gtk_idle_add(
- ( GtkFunction ) addressbook_ldap_idle, server );
- syldap_read_data_th( server );
- addressbook_ldap_show_message( server );
+
+ /* Setup a query */
+ printf( "addressbook_ldap_lookup/Starting.../2\n" );
+
+ /* Sit back and wait for something to happen */
+ _idleID_ = gtk_idle_add(
+ ( GtkFunction ) addressbook_ldap_idle, NULL );
+ addrindex_search_ldap_noid( server, sLookup, addressbook_ldap_idle_end );
+ addressbook_status_show( _tempMessage_ );
}
}
#endif
#include <gtk/gtkwidget.h>
#include "compose.h"
-
-void addressbook_open (Compose *target);
-void addressbook_set_target_compose (Compose *target);
-Compose *addressbook_get_target_compose (void);
-void addressbook_read_file (void);
-void addressbook_export_to_file (void);
-gint addressbook_obj_name_compare (gconstpointer a,
- gconstpointer b);
+#include "addritem.h"
+
+void addressbook_open ( Compose *target );
+void addressbook_set_target_compose ( Compose *target );
+Compose *addressbook_get_target_compose ( void );
+void addressbook_read_file ( void );
+void addressbook_export_to_file ( void );
+gint addressbook_obj_name_compare ( gconstpointer a,
+ gconstpointer b );
void addressbook_destroy ( void );
-gboolean addressbook_add_contact ( const gchar *name,
- const gchar *address,
- const gchar *remarks );
-
-gboolean addressbook_load_completion ( gint (*callBackFunc) ( const gchar *, const gchar *, const gchar * ) );
+gboolean addressbook_add_contact ( const gchar *name,
+ const gchar *address,
+ const gchar *remarks );
+
+gboolean addressbook_load_completion (gint (*callBackFunc)
+ (const gchar *,
+ const gchar *,
+ const gchar *));
void addressbook_gather ( FolderItem *folderItem,
gboolean sourceInd,
GList *msgList );
-void addressbook_harvest (FolderItem *folderItem,
- gboolean sourceInd,
- GList *msgList);
+void addressbook_harvest ( FolderItem *folderItem,
+ gboolean sourceInd,
+ GList *msgList);
+
+void addressbook_read_all ( void );
#endif /* __ADDRESSBOOK_H__ */
#include "addrbook.h"
#include "addrindex.h"
#include "xml.h"
+#include "addrquery.h"
#ifndef DEV_STANDALONE
#include "prefs_gtk.h"
#endif
#ifdef USE_LDAP
-#include "syldap.h"
+#include "ldapserver.h"
+#include "ldapctrl.h"
+#include "ldapquery.h"
#endif
#define TAG_ADDRESS_INDEX "addressbook"
#define ATTAG_LDAP_CRITERIA "criteria"
#define ATTAG_LDAP_MAX_ENTRY "max-entry"
#define ATTAG_LDAP_TIMEOUT "timeout"
+#define ATTAG_LDAP_MAX_AGE "max-age"
+#define ATTAG_LDAP_DYN_SEARCH "dyn-search"
+
+#define ELTAG_LDAP_ATTR_SRCH "attribute"
+#define ATTAG_LDAP_ATTR_NAME "name"
+
+/* New attributes */
+#define ATTAG_LDAP_DEFAULT "default"
#if 0
N_("Common address")
#define DISP_OLD_COMMON _("Common address")
#define DISP_OLD_PERSONAL _("Personal address")
+/*
+ * Define attribute name-value pair.
+ */
typedef struct _AddressIfAttr AddressIfAttrib;
struct _AddressIfAttr {
gchar *name;
};
/*
-* Build interface with default values.
+ * Define DOM fragment.
+ */
+typedef struct _AddressIfFrag AddressIfFragment;
+struct _AddressIfFrag {
+ gchar *name;
+ GList *children;
+ GList *attributes;
+};
+
+/**
+ * Build interface with default values.
+ *
+ * \param type Interface type.
+ * \param name Interface name.
+ * \param tagIf XML tag name for interface in address index file.
+ * \param tagDS XML tag name for datasource in address index file.
+ * \return Address interface object.
*/
-static AddressInterface *addrindex_create_interface( gint type, gchar *name, gchar *tagIf, gchar *tagDS ) {
+static AddressInterface *addrindex_create_interface(
+ gint type, gchar *name, gchar *tagIf, gchar *tagDS )
+{
AddressInterface *iface = g_new0( AddressInterface, 1 );
ADDRITEM_TYPE(iface) = ITEMTYPE_INTERFACE;
iface->haveLibrary = TRUE;
iface->useInterface = TRUE;
iface->readOnly = TRUE;
+
+ /* Set callbacks to NULL values - override for each interface */
iface->getAccessFlag = NULL;
iface->getModifyFlag = NULL;
iface->getReadFlag = NULL;
iface->getAllGroups = NULL;
iface->getName = NULL;
iface->listSource = NULL;
+
+ /* Search stuff */
+ iface->externalQuery = FALSE;
+ iface->searchOrder = 0; /* Ignored */
+ iface->startSearch = NULL;
+ iface->stopSearch = NULL;
+
return iface;
}
-/*
-* Build table of interfaces.
-*/
+/**
+ * Build table of of all address book interfaces.
+ * \param addrIndex Address index object.
+ */
static void addrindex_build_if_list( AddressIndex *addrIndex ) {
AddressInterface *iface;
- iface = addrindex_create_interface( ADDR_IF_BOOK, "Address Book", TAG_IF_ADDRESS_BOOK, TAG_DS_ADDRESS_BOOK );
+ /* Create intrinsic XML address book interface */
+ iface = addrindex_create_interface(
+ ADDR_IF_BOOK, "Address Book", TAG_IF_ADDRESS_BOOK,
+ TAG_DS_ADDRESS_BOOK );
iface->readOnly = FALSE;
iface->getModifyFlag = ( void * ) addrbook_get_modified;
iface->getAccessFlag = ( void * ) addrbook_get_accessed;
iface->getAllPersons = ( void * ) addrbook_get_all_persons;
iface->getName = ( void * ) addrbook_get_name;
iface->setAccessFlag = ( void * ) addrbook_set_accessed;
- addrIndex->interfaceList = g_list_append( addrIndex->interfaceList, iface );
+ iface->searchOrder = 0;
+
+ /* Add to list of interfaces in address book */
+ addrIndex->interfaceList =
+ g_list_append( addrIndex->interfaceList, iface );
ADDRITEM_PARENT(iface) = ADDRITEM_OBJECT(addrIndex);
- iface = addrindex_create_interface( ADDR_IF_VCARD, "vCard", TAG_IF_VCARD, TAG_DS_VCARD );
+ /* Create vCard interface */
+ iface = addrindex_create_interface(
+ ADDR_IF_VCARD, "vCard", TAG_IF_VCARD, TAG_DS_VCARD );
iface->getModifyFlag = ( void * ) vcard_get_modified;
iface->getAccessFlag = ( void * ) vcard_get_accessed;
iface->getReadFlag = ( void * ) vcard_get_read_flag;
iface->getAllPersons = ( void * ) vcard_get_all_persons;
iface->getName = ( void * ) vcard_get_name;
iface->setAccessFlag = ( void * ) vcard_set_accessed;
- addrIndex->interfaceList = g_list_append( addrIndex->interfaceList, iface );
+ iface->searchOrder = 0;
+ addrIndex->interfaceList =
+ g_list_append( addrIndex->interfaceList, iface );
ADDRITEM_PARENT(iface) = ADDRITEM_OBJECT(addrIndex);
- iface = addrindex_create_interface( ADDR_IF_JPILOT, "J-Pilot", TAG_IF_JPILOT, TAG_DS_JPILOT );
+ /* Create JPilot interface */
+ iface = addrindex_create_interface(
+ ADDR_IF_JPILOT, "J-Pilot", TAG_IF_JPILOT,
+ TAG_DS_JPILOT );
#ifdef USE_JPILOT
iface->haveLibrary = jpilot_test_pilot_lib();
iface->useInterface = iface->haveLibrary;
iface->getAllPersons = ( void * ) jpilot_get_all_persons;
iface->getName = ( void * ) jpilot_get_name;
iface->setAccessFlag = ( void * ) jpilot_set_accessed;
+ iface->searchOrder = 0;
#else
iface->useInterface = FALSE;
iface->haveLibrary = FALSE;
#endif
- addrIndex->interfaceList = g_list_append( addrIndex->interfaceList, iface );
+ addrIndex->interfaceList =
+ g_list_append( addrIndex->interfaceList, iface );
ADDRITEM_PARENT(iface) = ADDRITEM_OBJECT(addrIndex);
- iface = addrindex_create_interface( ADDR_IF_LDAP, "LDAP", TAG_IF_LDAP, TAG_DS_LDAP );
+ /* Create LDAP interface */
+ iface = addrindex_create_interface(
+ ADDR_IF_LDAP, "LDAP", TAG_IF_LDAP, TAG_DS_LDAP );
#ifdef USE_LDAP
- iface->haveLibrary = syldap_test_ldap_lib();
+ /* iface->haveLibrary = ldapsvr_test_ldap_lib(); */
+ iface->haveLibrary = ldaputil_test_ldap_lib();
iface->useInterface = iface->haveLibrary;
- iface->getAccessFlag = ( void * ) syldap_get_accessed;
- /* iface->getModifyFlag = ( void * ) syldap_get_modified; */
- /* iface->getReadFlag = ( void * ) syldap_get_read_flag; */
- iface->getStatusCode = ( void * ) syldap_get_status;
- iface->getReadData = ( void * ) syldap_read_data;
- iface->getRootFolder = ( void * ) syldap_get_root_folder;
- iface->getListFolder = ( void * ) syldap_get_list_folder;
- iface->getListPerson = ( void * ) syldap_get_list_person;
- iface->getName = ( void * ) syldap_get_name;
- iface->setAccessFlag = ( void * ) syldap_set_accessed;
+ /* iface->getModifyFlag = ( void * ) ldapsvr_get_modified; */
+ iface->getAccessFlag = ( void * ) ldapsvr_get_accessed;
+ /* iface->getReadFlag = ( void * ) ldapsvr_get_read_flag; */
+ iface->getStatusCode = ( void * ) ldapsvr_get_status;
+ /* iface->getReadData = ( void * ) ldapsvr_read_data; */
+ iface->getRootFolder = ( void * ) ldapsvr_get_root_folder;
+ iface->getListFolder = ( void * ) ldapsvr_get_list_folder;
+ iface->getListPerson = ( void * ) ldapsvr_get_list_person;
+ iface->getName = ( void * ) ldapsvr_get_name;
+ iface->setAccessFlag = ( void * ) ldapsvr_set_accessed;
+ iface->externalQuery = TRUE;
+ iface->searchOrder = 1;
#else
iface->useInterface = FALSE;
iface->haveLibrary = FALSE;
#endif
- addrIndex->interfaceList = g_list_append( addrIndex->interfaceList, iface );
+ addrIndex->interfaceList =
+ g_list_append( addrIndex->interfaceList, iface );
ADDRITEM_PARENT(iface) = ADDRITEM_OBJECT(addrIndex);
- /* Two old legacy data sources */
+ /* Two old legacy data sources (pre 0.7.0) */
iface = addrindex_create_interface(
ADDR_IF_COMMON, "Old Address - common",
TAG_IF_OLD_COMMON, NULL );
iface->legacyFlag = TRUE;
- addrIndex->interfaceList = g_list_append( addrIndex->interfaceList, iface );
+ addrIndex->interfaceList =
+ g_list_append( addrIndex->interfaceList, iface );
ADDRITEM_PARENT(iface) = ADDRITEM_OBJECT(addrIndex);
iface = addrindex_create_interface(
ADDR_IF_COMMON, "Old Address - personal",
TAG_IF_OLD_PERSONAL, NULL );
iface->legacyFlag = TRUE;
- addrIndex->interfaceList = g_list_append( addrIndex->interfaceList, iface );
+ addrIndex->interfaceList =
+ g_list_append( addrIndex->interfaceList, iface );
ADDRITEM_PARENT(iface) = ADDRITEM_OBJECT(addrIndex);
}
-/*
-* Free name-value pairs.
-*/
-static void addrindex_free_attributes( GList *list ) {
- GList *node = list;
+/**
+ * Free DOM fragment.
+ * \param fragment Fragment to free.
+ */
+static addrindex_free_fragment( AddressIfFragment *fragment ) {
+ GList *node;
+
+ /* Free children */
+ node = fragment->children;
+ while( node ) {
+ AddressIfFragment *child = node->data;
+ addrindex_free_fragment( child );
+ node->data = NULL;
+ node = g_list_next( node );
+ }
+ g_list_free( fragment->children );
+
+ /* Free attributes */
+ node = fragment->attributes;
while( node ) {
AddressIfAttrib *nv = node->data;
- g_free( nv->name ); nv->name = NULL;
- g_free( nv->value ); nv->value = NULL;
+ g_free( nv->name );
+ g_free( nv->value );
g_free( nv );
node->data = NULL;
node = g_list_next( node );
}
- g_list_free( list );
+ g_list_free( fragment->attributes );
+
+ g_free( fragment->name );
+ fragment->name = NULL;
+ fragment->attributes = NULL;
+ fragment->children = NULL;
+
+ g_free( fragment );
}
-/*
-* Create new data source.
-* Enter: ifType Interface type to create.
-* Return: Initialized data source.
-*/
+/**
+ * Create a new data source.
+ * \param ifType Interface type to create.
+ * \return Initialized data source.
+ */
AddressDataSource *addrindex_create_datasource( AddressIfType ifType ) {
AddressDataSource *ds = g_new0( AddressDataSource, 1 );
return ds;
}
-/*
-* Free up data source.
-*/
+/**
+ * Free up data source.
+ * \param ds Data source to free.
+ */
void addrindex_free_datasource( AddressDataSource *ds ) {
AddressInterface *iface;
#endif
#ifdef USE_LDAP
else if( iface->type == ADDR_IF_LDAP ) {
- SyldapServer *server = ds->rawDataSource;
- syldap_free( server );
+ LdapServer *server = ds->rawDataSource;
+ ldapsvr_free( server );
}
#endif
else {
}
}
else {
- GList *list = ds->rawDataSource;
- addrindex_free_attributes( list );
+ AddressIfFragment *fragment = ds->rawDataSource;
+ addrindex_free_fragment( fragment );
}
}
}
ds->type = ADDR_IF_NONE;
ds->interface = NULL;
ds->rawDataSource = NULL;
+
g_free( ds );
}
+/**
+ * Free up all data sources for specified interface.
+ * \param iface Address interface to process.
+ */
static void addrindex_free_all_datasources( AddressInterface *iface ) {
GList *node = iface->listSource;
while( node ) {
}
}
+/**
+ * Free up specified interface.
+ * \param iface Interface to process.
+ */
static void addrindex_free_interface( AddressInterface *iface ) {
/* Free up data sources */
addrindex_free_all_datasources( iface );
iface->haveLibrary = FALSE;
iface->listSource = NULL;
+ /* Search stuff */
+ iface->searchOrder = 0;
+ iface->startSearch = NULL;
+ iface->stopSearch = NULL;
+
g_free( iface );
}
-/*
+/**
* Return cache ID for specified data source.
- * Enter: addrIndex Address index.
- * ds Data source.
- * Return: ID or NULL if not found. This can be g_free() when done.
+ *
+ * \param addrIndex Address index.
+ * \param ds Data source.
+ * \return ID or NULL if not found. This should be <code>g_free()</code>
+ * when done.
*/
gchar *addrindex_get_cache_id( AddressIndex *addrIndex, AddressDataSource *ds ) {
gchar *cacheID = NULL;
return cacheID;
}
-/*
- * Return data source for specified cacheID.
- * Enter: addrIndex Address index.
- * cacheID ID.
- * Return: Data source, or NULL if not found.
+/**
+ * Return reference to data source for specified cacheID.
+ * \param addrIndex Address index.
+ * \param cacheID ID.
+ * \return Data source, or NULL if not found.
*/
-AddressDataSource *addrindex_get_datasource( AddressIndex *addrIndex, const gchar *cacheID ) {
+AddressDataSource *addrindex_get_datasource(
+ AddressIndex *addrIndex, const gchar *cacheID )
+{
g_return_val_if_fail( addrIndex != NULL, NULL );
g_return_val_if_fail( cacheID != NULL, NULL );
return ( AddressDataSource * ) g_hash_table_lookup( addrIndex->hashCache, cacheID );
}
-/*
- * Return cache for specified cacheID.
- * Enter: addrIndex Address index.
- * cacheID ID.
- * Return: Address cache, or NULL if not found.
+/**
+ * Return reference to address cache for specified cacheID.
+ * \param addrIndex Address index.
+ * \param cacheID ID.
+ * \return Address cache, or NULL if not found.
*/
AddressCache *addrindex_get_cache( AddressIndex *addrIndex, const gchar *cacheID ) {
AddressDataSource *ds;
return cache;
}
-/*
- * Add data source into hash.
- * Enter: addrIndex Address index.
- * ds Data source.
+/**
+ * Add data source into hash table.
+ * \param addrIndex Address index.
+ * \param ds Data source.
*/
-static void addrindex_hash_add_cache( AddressIndex *addrIndex, AddressDataSource *ds ) {
+static void addrindex_hash_add_cache(
+ AddressIndex *addrIndex, AddressDataSource *ds )
+{
gchar *cacheID;
cacheID = addrindex_get_cache_id( addrIndex, ds );
}
/*
-* Free hash table callback function.
-*/
+ * Free hash table callback function.
+ */
static gboolean addrindex_free_cache_cb( gpointer key, gpointer value, gpointer data ) {
g_free( key );
key = NULL;
}
/*
-* Free hash table of address cache items.
-*/
+ * Free hash table of address cache items.
+ */
static void addrindex_free_cache_hash( GHashTable *table ) {
g_hash_table_freeze( table );
g_hash_table_foreach_remove( table, addrindex_free_cache_cb, NULL );
}
/*
-* Remove address cache for specified data source from internal hashtable.
-*/
-static void addrindex_hash_remove_cache( AddressIndex *addrIndex, AddressDataSource *ds ) {
+ * Remove data source from internal hashtable.
+ * \param addrIndex Address index.
+ * \param ds Data source to remove.
+ */
+static void addrindex_hash_remove_cache(
+ AddressIndex *addrIndex, AddressDataSource *ds )
+{
gchar *cacheID;
cacheID = addrindex_get_cache_id( addrIndex, ds );
}
/*
-* Create new object.
-*/
+ * Create a new address index.
+ * \return Initialized address index object.
+ */
AddressIndex *addrindex_create_index( void ) {
AddressIndex *addrIndex = g_new0( AddressIndex, 1 );
addrIndex->lastType = ADDR_IF_NONE;
addrIndex->dirtyFlag = FALSE;
addrIndex->hashCache = g_hash_table_new( g_str_hash, g_str_equal );
+ addrIndex->loadedFlag = FALSE;
+ addrIndex->searchOrder = NULL;
addrindex_build_if_list( addrIndex );
return addrIndex;
}
-/*
-* Specify file to be used.
-*/
+/**
+ * Property - Specify file path to address index file.
+ * \param addrIndex Address index.
+ * \param value Path to index file.
+ */
void addrindex_set_file_path( AddressIndex *addrIndex, const gchar *value ) {
g_return_if_fail( addrIndex != NULL );
addrIndex->filePath = mgu_replace_string( addrIndex->filePath, value );
}
+
+/**
+ * Property - Specify file name to address index file.
+ * \param addrIndex Address index.
+ * \param value File name.
+ */
void addrindex_set_file_name( AddressIndex *addrIndex, const gchar *value ) {
g_return_if_fail( addrIndex != NULL );
addrIndex->fileName = mgu_replace_string( addrIndex->fileName, value );
}
+
+/**
+ * Property - Specify file path to be used.
+ * \param addrIndex Address index.
+ * \param value Path to JPilot file.
+ */
void addrindex_set_dirty( AddressIndex *addrIndex, const gboolean value ) {
g_return_if_fail( addrIndex != NULL );
addrIndex->dirtyFlag = value;
}
-/*
-* Return list of interfaces.
-*/
+/**
+ * Property - get loaded flag. Note that this flag is set after reading data
+ * from the address books.
+ * \param addrIndex Address index.
+ * \return <i>TRUE</i> if address index data was loaded.
+ */
+gboolean addrindex_get_loaded( AddressIndex *addrIndex ) {
+ g_return_val_if_fail( addrIndex != NULL, FALSE );
+ return addrIndex->loadedFlag;
+}
+
+/**
+ * Return list of address interfaces.
+ * \param addrIndex Address index.
+ * \return List of address interfaces.
+ */
GList *addrindex_get_interface_list( AddressIndex *addrIndex ) {
g_return_val_if_fail( addrIndex != NULL, NULL );
return addrIndex->interfaceList;
}
-/*
-* Free up object.
-*/
+/**
+ * Perform any other initialization of address index.
+ * \param addrIndex Address index.
+ */
+void addrindex_initialize( AddressIndex *addrIndex ) {
+ addrcompl_initialize( addrIndex );
+}
+
+/**
+ * Perform any other teardown of address index.
+ * \param addrIndex Address index.
+ */
+void addrindex_teardown( AddressIndex *addrIndex ) {
+ addrcompl_teardown();
+}
+
+/**
+ * Free up address index.
+ * \param addrIndex Address index.
+ */
void addrindex_free_index( AddressIndex *addrIndex ) {
GList *node;
g_return_if_fail( addrIndex != NULL );
+ /* Search stuff */
+ g_list_free( addrIndex->searchOrder );
+ addrIndex->searchOrder = NULL;
+
+ /* Free internal storage */
g_free( ADDRITEM_ID(addrIndex) );
g_free( ADDRITEM_NAME(addrIndex) );
g_free( addrIndex->filePath );
g_free( addrIndex->fileName );
+
+ /* Clear pointers */
ADDRITEM_TYPE(addrIndex) = ITEMTYPE_NONE;
ADDRITEM_ID(addrIndex) = NULL;
ADDRITEM_NAME(addrIndex) = NULL;
addrIndex->conversionError = FALSE;
addrIndex->lastType = ADDR_IF_NONE;
addrIndex->dirtyFlag = FALSE;
+
+ /* Free up interfaces */
node = addrIndex->interfaceList;
while( node ) {
AddressInterface *iface = node->data;
}
g_list_free( addrIndex->interfaceList );
addrIndex->interfaceList = NULL;
+
+ /* Free up hash cache */
addrindex_free_cache_hash( addrIndex->hashCache );
addrIndex->hashCache = NULL;
+
+ addrIndex->loadedFlag = FALSE;
+
g_free( addrIndex );
}
-/*
-* Print address index.
+/**
+ * Print address index.
+ * \param addrIndex Address index.
+ * \parem stream Stream to print.
*/
void addrindex_print_index( AddressIndex *addrIndex, FILE *stream ) {
g_return_if_fail( addrIndex != NULL );
fprintf( stream, "AddressIndex:\n" );
fprintf( stream, "\tfile path: '%s'\n", addrIndex->filePath );
fprintf( stream, "\tfile name: '%s'\n", addrIndex->fileName );
- fprintf( stream, "\t status: %d\n", addrIndex->retVal );
- fprintf( stream, "\tconverted: '%s'\n", addrIndex->wasConverted ? "yes" : "no" );
- fprintf( stream, "\tcvt error: '%s'\n", addrIndex->conversionError ? "yes" : "no" );
+ fprintf( stream, "\t status: %d\n", addrIndex->retVal );
+ fprintf( stream, "\tconverted: '%s'\n",
+ addrIndex->wasConverted ? "yes" : "no" );
+ fprintf( stream, "\tcvt error: '%s'\n",
+ addrIndex->conversionError ? "yes" : "no" );
fprintf( stream, "\t---\n" );
}
-/*
-* Retrieve specified interface from index.
-*/
+/**
+ * Retrieve reference to address interface for specified interface type.
+ * \param addrIndex Address index.
+ * \param ifType Interface type.
+ * \return Address interface, or NULL if not found.
+ */
AddressInterface *addrindex_get_interface(
AddressIndex *addrIndex, AddressIfType ifType )
{
return retVal;
}
-/*
-* Add data source to index.
-* Enter: addrIndex Address index object.
-* ifType Interface type to add.
-* dataSource Actual data source to add.
-* Return: TRUE if data source was added.
-* Note: The raw data object (for example, AddressBookFile or VCardFile object) should be
-* supplied as the dataSource argument.
-*/
+/**
+ * Add raw data source to index. The raw data object (an AddressBookFile or
+ * VCardFile object, for example) should be supplied as the raw dataSource
+ * argument.
+ *
+ * \param addrIndex Address index.
+ * \param ifType Interface type to add.
+ * \param dataSource Actual raw data source to add.
+ * \return Data source added, or NULL if invalid interface type.
+ */
AddressDataSource *addrindex_index_add_datasource(
AddressIndex *addrIndex, AddressIfType ifType, gpointer dataSource )
{
return ds;
}
-/*
-* Remove data source from index.
-* Enter: addrIndex Address index object.
-* dataSource Data source to remove.
-* Return: Data source if removed, or NULL if data source was not found in
-* index. Note the this object must still be freed.
-*/
+/**
+ * Remove specified data source from index.
+ * \param addrIndex Address index.
+ * \param dataSource Data source to add.
+ * \return Reference to data source if removed, or NULL if data source was not
+ * found in index. Note the this object must still be freed.
+ */
AddressDataSource *addrindex_index_remove_datasource(
AddressIndex *addrIndex, AddressDataSource *dataSource )
{
return retVal;
}
+/**
+ * Retrieve a reference to address interface for specified interface type and
+ * XML interface tag name.
+ * \param addrIndex Address index.
+ * \param tag XML interface tag name to match.
+ * \param ifType Interface type to match.
+ * \return Reference to address index, or NULL if not found in index.
+ */
static AddressInterface *addrindex_tag_get_interface(
AddressIndex *addrIndex, gchar *tag, AddressIfType ifType )
{
return retVal;
}
+/**
+ * Retrieve a reference to address interface for specified interface type and
+ * XML datasource tag name.
+ * \param addrIndex Address index.
+ * \param ifType Interface type to match.
+ * \param tag XML datasource tag name to match.
+ * \return Reference to address index, or NULL if not found in index.
+ */
static AddressInterface *addrindex_tag_get_datasource(
AddressIndex *addrIndex, AddressIfType ifType, gchar *tag )
{
* Interface XML parsing functions.
* ***********************************************************************
*/
-/*
-static void show_attribs( GList *attr ) {
- while( attr ) {
- gchar *name = ((XMLAttr *)attr->data)->name;
- gchar *value = ((XMLAttr *)attr->data)->value;
- printf( "\tattr value : %s :%s:\n", name, value );
- attr = g_list_next( attr );
- }
- printf( "\t---\n" );
-}
-*/
-static void addrindex_write_elem_s( FILE *fp, gint lvl, gchar *name ) {
+/**
+ * Write start of XML element to file.
+ * \param fp File.
+ * \param lvl Indentation level.
+ * \param name Element name.
+ */
+static void addrindex_write_elem_s( FILE *fp, const gint lvl, const gchar *name ) {
gint i;
for( i = 0; i < lvl; i++ ) fputs( " ", fp );
fputs( "<", fp );
fputs( name, fp );
}
-static void addrindex_write_elem_e( FILE *fp, gint lvl, gchar *name ) {
+/**
+ * Write end of XML element to file.
+ * \param fp File.
+ * \param lvl Indentation level.
+ * \param name Element name.
+ */
+static void addrindex_write_elem_e( FILE *fp, const gint lvl, const gchar *name ) {
gint i;
for( i = 0; i < lvl; i++ ) fputs( " ", fp );
fputs( "</", fp );
fputs( ">\n", fp );
}
-static void addrindex_write_attr( FILE *fp, gchar *name, gchar *value ) {
+/**
+ * Write XML attribute to file.
+ * \param fp File.
+ * \param name Attribute name.
+ * \param value Attribute value.
+ */
+static void addrindex_write_attr( FILE *fp, const gchar *name, const gchar *value ) {
fputs( " ", fp );
fputs( name, fp );
fputs( "=\"", fp );
fputs( "\"", fp );
}
-/*
-* Return list of name-value pairs.
-*/
-static GList *addrindex_read_attributes( XMLFile *file ) {
- GList *list = NULL;
+/**
+ * Return DOM fragment for current XML tag from file.
+ * \param file XML file being processed.
+ * \return Fragment representing DOM fragment for configuration element.
+ */
+static AddressIfFragment *addrindex_read_fragment( XMLFile *file ) {
+ AddressIfFragment *fragment;
+ AddressIfFragment *child;
AddressIfAttrib *nv;
+ XMLTag *xtag;
+ GList *list;
GList *attr;
gchar *name;
gchar *value;
+ guint prevLevel;
+ gint rc;
+
+ /* printf( "addrindex_read_fragment\n" ); */
+
+ prevLevel = file->level;
+
+ /* Get current tag name */
+ xtag = xml_get_current_tag( file );
+ /* Create new fragment */
+ fragment = g_new0( AddressIfFragment, 1 );
+ fragment->name = g_strdup( xtag->tag );
+ fragment->children = NULL;
+ fragment->attributes = NULL;
+
+ /* Read attributes */
+ list = NULL;
attr = xml_get_current_tag_attr( file );
while( attr ) {
name = ((XMLAttr *)attr->data)->name;
list = g_list_append( list, nv );
attr = g_list_next( attr );
}
- return list;
+ fragment->attributes = list;
+
+ /* Now read the children */
+ while( TRUE ) {
+ rc = xml_parse_next_tag( file );
+ if( rc != 0 ) {
+ /* End of file? */
+ break;
+ }
+ if( file->level < prevLevel ) {
+ /* We must be above level we start at */
+ break;
+ }
+ child = addrindex_read_fragment( file );
+ fragment->children = g_list_append( fragment->children, child );
+ }
+
+ return fragment;
}
-/*
-* Output name-value pairs.
-*/
-static void addrindex_write_attributes( FILE *fp, gchar *tag, GList *list, gint lvl ) {
+/**
+ * Write DOM fragment to file.
+ * \param fp File to write.
+ * \param fragment DOM fragment for configuration element.
+ * \param lvl Indent level.
+ */
+static void addrindex_write_fragment(
+ FILE *fp, const AddressIfFragment *fragment, const gint lvl )
+{
GList *node;
- AddressIfAttrib *nv;
- if( list ) {
- addrindex_write_elem_s( fp, lvl, tag );
- node = list;
+
+ if( fragment ) {
+ addrindex_write_elem_s( fp, lvl, fragment->name );
+ node = fragment->attributes;
while( node ) {
- nv = node->data;
+ AddressIfAttrib *nv = node->data;
addrindex_write_attr( fp, nv->name, nv->value );
node = g_list_next( node );
}
- fputs(" />\n", fp);
+ if( fragment->children ) {
+ fputs(" >\n", fp);
+
+ /* Output children */
+ node = fragment->children;
+ while( node ) {
+ AddressIfFragment *child = node->data;
+ addrindex_write_fragment( fp, child, 1+lvl );
+ node = g_list_next( node );
+ }
+
+ /* Output closing tag */
+ addrindex_write_elem_e( fp, lvl, fragment->name );
+ }
+ else {
+ fputs(" />\n", fp);
+ }
}
}
/*
-static void addrindex_print_attributes( GList *list, FILE *stream ) {
- GList *node = list;
+static void addrindex_print_fragment_r(
+ const AddressIfFragment *fragment, FILE *stream, gint lvl )
+{
+ GList *node;
+ gint i;
+
+ for( i = 0; i < lvl; i++ )
+ fprintf( stream, " " );
+ fprintf( stream, "Element:%s:\n", fragment->name );
+ node = fragment->attributes;
while( node ) {
AddressIfAttrib *nv = node->data;
- fprintf( stream, "%s : %s\n", nv->name, nv->value );
+ for( i = 0; i < lvl; i++ )
+ fprintf( stream, " " );
+ fprintf( stream, " %s : %s\n", nv->name, nv->value );
+ node = g_list_next( node );
+ }
+ node = fragment->children;
+ while( node ) {
+ AddressIfFragment *child = node->data;
+ addrindex_print_fragment_r( child, stream, 1+lvl );
node = g_list_next( node );
}
}
+
+static void addrindex_print_fragment( const AddressIfFragment *fragment, FILE *stream ) {
+ addrindex_print_fragment_r( fragment, stream, 0 );
+}
*/
+/**
+ * Read/parse address index file, creating a data source for a regular
+ * intrinsic XML addressbook.
+ * \param file Address index file.
+ * \return Data source.
+ */
static AddressDataSource *addrindex_parse_book( XMLFile *file ) {
AddressDataSource *ds;
AddressBookFile *abf;
fputs( " />\n", fp );
}
}
+
#else
-/* Just read/write name-value pairs (preserve data found in file) */
+/*
+ * Just read/write DOM fragments (preserve data found in file).
+ */
static AddressDataSource *addrindex_parse_jpilot( XMLFile *file ) {
AddressDataSource *ds;
ds = addrindex_create_datasource( ADDR_IF_JPILOT );
- ds->rawDataSource = addrindex_read_attributes( file );
+ ds->rawDataSource = addrindex_read_fragment( file );
return ds;
}
static void addrindex_write_jpilot( FILE *fp, AddressDataSource *ds, gint lvl ) {
- GList *list = ds->rawDataSource;
- if( list ) {
- addrindex_write_attributes( fp, TAG_DS_JPILOT, list, lvl );
+ AddressIfFragment *fragment = ds->rawDataSource;
+ if( fragment ) {
+ addrindex_write_fragment( fp, fragment, lvl );
}
}
#endif
#ifdef USE_LDAP
+/**
+ * Parse LDAP criteria attribute data from XML file.
+ * \param file Index file.
+ * \param ctl LDAP control object to populate.
+ */
+static void addrindex_parse_ldap_attrlist( XMLFile *file, LdapControl *ctl ) {
+ guint prevLevel;
+ XMLTag *xtag;
+ XMLTag *xtagPrev;
+ gint rc;
+ GList *attr;
+ GList *list;
+ GList *node;
+
+ if( file == NULL ) {
+ return;
+ }
+
+ list = NULL;
+ prevLevel = file->level;
+ xtagPrev = xml_get_current_tag( file );
+ while( TRUE ) {
+ rc = xml_parse_next_tag( file );
+ if( rc != 0 ) {
+ /* Terminate prematurely */
+ mgu_free_dlist( list );
+ list = NULL;
+ return;
+ }
+ if( file->level < prevLevel ) {
+ /* We must be above level we start at */
+ break;
+ }
+
+ /* Get a tag (element) */
+ xtag = xml_get_current_tag( file );
+ if( strcmp( xtag->tag, ELTAG_LDAP_ATTR_SRCH ) == 0 ) {
+ /* LDAP criteria attribute */
+ attr = xml_get_current_tag_attr( file );
+ while( attr ) {
+ gchar *name = ((XMLAttr *)attr->data)->name;
+ gchar *value = ((XMLAttr *)attr->data)->value;
+ if( strcmp( name, ATTAG_LDAP_ATTR_NAME ) == 0 ) {
+ if( value && strlen( value ) > 0 ) {
+ list = g_list_append(
+ list, g_strdup( value ) );
+ }
+ }
+ attr = g_list_next( attr );
+ }
+ }
+ else {
+ if( xtag != xtagPrev ) {
+ /* Found a new tag */
+ break;
+ }
+ }
+ xtag = xtagPrev;
+ }
+
+ /* Build list of search attributes */
+ ldapctl_criteria_list_clear( ctl );
+ node = list;
+ while( node ) {
+ ldapctl_criteria_list_add( ctl, node->data );
+ g_free( node->data );
+ node->data = NULL;
+ node = g_list_next( node );
+ }
+ g_list_free( list );
+ list = NULL;
+
+}
+
static AddressDataSource *addrindex_parse_ldap( XMLFile *file ) {
AddressDataSource *ds;
- SyldapServer *server;
+ LdapServer *server;
+ LdapControl *ctl;
GList *attr;
+ gchar *serverName = NULL;
+ gchar *criteria = NULL;
+ gboolean bSearch = FALSE;
+ gboolean cvtFlag = TRUE;
+
+ /* printf( "addrindex_parse_ldap\n" ); */
ds = addrindex_create_datasource( ADDR_IF_LDAP );
- server = syldap_create();
+ ctl = ldapctl_create();
attr = xml_get_current_tag_attr( file );
while( attr ) {
gchar *name = ((XMLAttr *)attr->data)->name;
gchar *value = ((XMLAttr *)attr->data)->value;
gint ivalue = atoi( value );
+
if( strcmp( name, ATTAG_LDAP_NAME ) == 0 ) {
- syldap_set_name( server, value );
+ if( serverName ) g_free( serverName );
+ serverName = g_strdup( value );
}
else if( strcmp( name, ATTAG_LDAP_HOST ) == 0 ) {
- syldap_set_host( server, value );
+ ldapctl_set_host( ctl, value );
}
else if( strcmp( name, ATTAG_LDAP_PORT ) == 0 ) {
- syldap_set_port( server, ivalue );
+ ldapctl_set_port( ctl, ivalue );
}
else if( strcmp( name, ATTAG_LDAP_BASE_DN ) == 0 ) {
- syldap_set_base_dn( server, value );
+ ldapctl_set_base_dn( ctl, value );
}
else if( strcmp( name, ATTAG_LDAP_BIND_DN ) == 0 ) {
- syldap_set_bind_dn( server, value );
+ ldapctl_set_bind_dn( ctl, value );
}
else if( strcmp( name, ATTAG_LDAP_BIND_PASS ) == 0 ) {
- syldap_set_bind_password( server, value );
+ ldapctl_set_bind_password( ctl, value );
}
else if( strcmp( name, ATTAG_LDAP_CRITERIA ) == 0 ) {
- syldap_set_search_criteria( server, value );
+ if( criteria ) g_free( criteria );
+ criteria = g_strdup( value );
}
else if( strcmp( name, ATTAG_LDAP_MAX_ENTRY ) == 0 ) {
- syldap_set_max_entries( server, ivalue );
+ ldapctl_set_max_entries( ctl, ivalue );
}
else if( strcmp( name, ATTAG_LDAP_TIMEOUT ) == 0 ) {
- syldap_set_timeout( server, ivalue );
+ ldapctl_set_timeout( ctl, ivalue );
+ }
+ else if( strcmp( name, ATTAG_LDAP_MAX_AGE ) == 0 ) {
+ ldapctl_set_max_query_age( ctl, ivalue );
+ }
+ else if( strcmp( name, ATTAG_LDAP_DYN_SEARCH ) == 0 ) {
+ bSearch = FALSE;
+ cvtFlag = FALSE;
+ if( strcmp( value, "yes" ) == 0 ) {
+ bSearch = TRUE;
+ }
}
attr = g_list_next( attr );
}
+ server = ldapsvr_create_noctl();
+ ldapsvr_set_name( server, serverName );
+ ldapsvr_set_search_flag( server, bSearch );
+ g_free( serverName );
+ ldapsvr_set_control( server, ctl );
ds->rawDataSource = server;
+
+ addrindex_parse_ldap_attrlist( file, ctl );
+ /*
+ * If criteria have been specified and no attributes were listed, then
+ * convert old style criteria into an attribute list. Any criteria will
+ * be dropped when saving data.
+ */
+ if( criteria ) {
+ if( ! ldapctl_get_criteria_list( ctl ) ) {
+ ldapctl_parse_ldap_search( ctl, criteria );
+ }
+ g_free( criteria );
+ }
+ /*
+ * If no search flag was found, then we are converting from old format
+ * server data to new format.
+ */
+ if( cvtFlag ) {
+ ldapsvr_set_search_flag( server, TRUE );
+ }
+ /* ldapsvr_print_data( server, stdout ); */
+
return ds;
}
static void addrindex_write_ldap( FILE *fp, AddressDataSource *ds, gint lvl ) {
- SyldapServer *server = ds->rawDataSource;
+ LdapServer *server = ds->rawDataSource;
+ LdapControl *ctl = NULL;
+ GList *node;
+ gchar value[256];
+
if( server ) {
- gchar value[256];
+ ctl = server->control;
+ }
+ if( ctl == NULL ) return;
+
+ /* Output start element with attributes */
+ addrindex_write_elem_s( fp, lvl, TAG_DS_LDAP );
+ addrindex_write_attr( fp, ATTAG_LDAP_NAME, ldapsvr_get_name( server ) );
+ addrindex_write_attr( fp, ATTAG_LDAP_HOST, ctl->hostName );
- addrindex_write_elem_s( fp, lvl, TAG_DS_LDAP );
- addrindex_write_attr( fp, ATTAG_LDAP_NAME, syldap_get_name( server ) );
- addrindex_write_attr( fp, ATTAG_LDAP_HOST, server->hostName );
+ sprintf( value, "%d", ctl->port );
+ addrindex_write_attr( fp, ATTAG_LDAP_PORT, value );
- sprintf( value, "%d", server->port );
- addrindex_write_attr( fp, ATTAG_LDAP_PORT, value );
+ addrindex_write_attr( fp, ATTAG_LDAP_BASE_DN, ctl->baseDN );
+ addrindex_write_attr( fp, ATTAG_LDAP_BIND_DN, ctl->bindDN );
+ addrindex_write_attr( fp, ATTAG_LDAP_BIND_PASS, ctl->bindPass );
- addrindex_write_attr( fp, ATTAG_LDAP_BASE_DN, server->baseDN );
- addrindex_write_attr( fp, ATTAG_LDAP_BIND_DN, server->bindDN );
- addrindex_write_attr( fp, ATTAG_LDAP_BIND_PASS, server->bindPass );
- addrindex_write_attr( fp, ATTAG_LDAP_CRITERIA, server->searchCriteria );
+ sprintf( value, "%d", ctl->maxEntries );
+ addrindex_write_attr( fp, ATTAG_LDAP_MAX_ENTRY, value );
+ sprintf( value, "%d", ctl->timeOut );
+ addrindex_write_attr( fp, ATTAG_LDAP_TIMEOUT, value );
+ sprintf( value, "%d", ctl->maxQueryAge );
+ addrindex_write_attr( fp, ATTAG_LDAP_MAX_AGE, value );
- sprintf( value, "%d", server->maxEntries );
- addrindex_write_attr( fp, ATTAG_LDAP_MAX_ENTRY, value );
- sprintf( value, "%d", server->timeOut );
- addrindex_write_attr( fp, ATTAG_LDAP_TIMEOUT, value );
+ addrindex_write_attr( fp, ATTAG_LDAP_DYN_SEARCH,
+ server->searchFlag ? "yes" : "no" );
+ fputs(" >\n", fp);
+
+ /* Output attributes */
+ node = ldapctl_get_criteria_list( ctl );
+ while( node ) {
+ addrindex_write_elem_s( fp, 1+lvl, ELTAG_LDAP_ATTR_SRCH );
+ addrindex_write_attr( fp, ATTAG_LDAP_ATTR_NAME, node->data );
fputs(" />\n", fp);
+ node = g_list_next( node );
}
+
+ /* End of element */
+ addrindex_write_elem_e( fp, lvl, TAG_DS_LDAP );
+
}
+
#else
-/* Just read/write name-value pairs (preserve data found in file) */
+/*
+ * Just read/write DOM fragments (preserve data found in file).
+ */
static AddressDataSource *addrindex_parse_ldap( XMLFile *file ) {
AddressDataSource *ds;
ds = addrindex_create_datasource( ADDR_IF_LDAP );
- ds->rawDataSource = addrindex_read_attributes( file );
+ ds->rawDataSource = addrindex_read_fragment( file );
return ds;
}
static void addrindex_write_ldap( FILE *fp, AddressDataSource *ds, gint lvl ) {
- GList *list = ds->rawDataSource;
- if( list ) {
- addrindex_write_attributes( fp, TAG_DS_LDAP, list, lvl );
+ AddressIfFragment *fragment = ds->rawDataSource;
+ if( fragment ) {
+ addrindex_write_fragment( fp, fragment, lvl );
}
}
#endif
* Address index I/O functions.
* ***********************************************************************
*/
+/**
+ * Read address index file, creating appropriate data sources for each address
+ * index file entry.
+ *
+ * \param addrIndex Address index.
+ * \param file Address index file.
+ */
static void addrindex_read_index( AddressIndex *addrIndex, XMLFile *file ) {
guint prev_level;
XMLTag *xtag;
AddressInterface *iface = NULL, *dsIFace = NULL;
AddressDataSource *ds;
+ gint rc;
+ addrIndex->loadedFlag = FALSE;
for (;;) {
prev_level = file->level;
- xml_parse_next_tag( file );
- if( file->level < prev_level ) return;
+ rc = xml_parse_next_tag( file );
+ if( file->level == 0 ) return;
xtag = xml_get_current_tag( file );
}
}
}
- addrindex_read_index( addrIndex, file );
+ }
+}
+
+/*
+ * Search order sorting comparison function for building search order list.
+ */
+static gint addrindex_search_order_compare( gconstpointer ptrA, gconstpointer ptrB ) {
+ AddressInterface *ifaceA = ( AddressInterface * ) ptrA;
+ AddressInterface *ifaceB = ( AddressInterface * ) ptrB;
+
+ return ifaceA->searchOrder - ifaceB->searchOrder;
+}
+
+/**
+ * Build list of data sources to process.
+ * \param addrIndex Address index object.
+ */
+static void addrindex_build_search_order( AddressIndex *addrIndex ) {
+ AddressInterface *iface;
+ GList *nodeIf;
+
+ /* Clear existing list */
+ g_list_free( addrIndex->searchOrder );
+ addrIndex->searchOrder = NULL;
+
+ /* Build new list */
+ nodeIf = addrIndex->interfaceList;
+ while( nodeIf ) {
+ AddressInterface *iface = nodeIf->data;
+ if( iface->useInterface ) {
+ if( iface->searchOrder > 0 ) {
+ /* Add to search order list */
+ addrIndex->searchOrder = g_list_insert_sorted(
+ addrIndex->searchOrder, iface,
+ addrindex_search_order_compare );
+ }
+ }
+ nodeIf = g_list_next( nodeIf );
}
}
g_free( fileSpec );
if( file == NULL ) {
- /* fprintf( stdout, " file '%s' does not exist.\n", addrIndex->fileName ); */
+ /*
+ fprintf( stdout, " file '%s' does not exist.\n", addrIndex->fileName );
+ */
return addrIndex->retVal;
}
}
xml_close_file( file );
+ addrindex_build_search_order( addrIndex );
+
return addrIndex->retVal;
}
iface = ds->interface;
if( iface == NULL ) return retVal;
if( iface->getReadData ) {
+ gchar *name = ( iface->getName ) ( ds->rawDataSource );
+ /* printf( "addrindex_ds_read_data...reading:::%s:::\n", name ); */
retVal = ( iface->getReadData ) ( ds->rawDataSource );
}
return retVal;
return retVal;
}
-/*
-* End of Source.
+/* **********************************************************************
+* Address search stuff.
+* ***********************************************************************
*/
+
+/**
+ * Current query ID. This is incremented for each query created.
+ */
+static gint _currentQueryID_ = 0;
+
+/*
+ * Variables for the search that is being performed.
+ */
+static gchar *_searchTerm_ = NULL;
+static gpointer _searchTarget_ = NULL;
+static AddrSearchCallbackFunc *_searchCallback_ = NULL;
+
+/**
+ * Setup or register the search that will be performed.
+ * \param addrIndex Address index object.
+ * \param searchTerm Search term. A private copy will be made.
+ * \param target Target object that will receive data.
+ * \param callBack Callback function.
+ * \return ID allocated to query that will be executed.
+ */
+gint addrindex_setup_search(
+ AddressIndex *addrIndex, const gchar *searchTerm,
+ const gpointer target, AddrSearchCallbackFunc callBack )
+{
+ gint queryID;
+
+ /* printf( "search term ::%s::\n", searchTerm ); */
+ g_free( _searchTerm_ );
+ _searchTerm_ = g_strdup( searchTerm );
+
+ queryID = ++_currentQueryID_;
+ _searchTarget_ = target;
+ _searchCallback_ = callBack;
+ /* printf( "query ID ::%d::\n", queryID ); */
+ return queryID;
+}
+
+#ifdef USE_LDAP
+/**
+ * LDAP callback entry point for each address entry found.
+ * \param qry LDAP query.
+ * \param listEMail List of Item EMail objects found.
+ */
+static void addrindex_ldap_entry_cb( LdapQuery *qry, GList *listEMail ) {
+ /*
+ GList *node;
+
+ printf( "\naddrindex::addrindex_ldap_entry_cb ::%s::\n", qry->queryName );
+ node = listEMail;
+ while( node ) {
+ ItemEMail *email = node->data;
+ printf( "\temail ::%s::\n", email->address );
+ node = g_list_next( node );
+ }
+ */
+ if( _searchCallback_ ) {
+ ( _searchCallback_ ) ( qry->queryID, listEMail, _searchTarget_ );
+ }
+ g_list_free( listEMail );
+}
+
+/**
+ * LDAP callback entry point for completion of search.
+ * \param qry LDAP query.
+ */
+static void addrindex_ldap_end_cb( LdapQuery *qry ) {
+ /* printf( "\naddrindex::addrindex_ldap_end_cb ::%s::\n", qry->queryName ); */
+}
+
+/**
+ * Return results of previous query.
+ * \param folder.
+ * \return List of ItemEMail objects.
+ */
+static void addrindex_ldap_use_previous( const ItemFolder *folder, const gint queryID )
+{
+ GList *listEMail;
+ GList *node;
+ GList *nodeEM;
+
+ listEMail = NULL;
+ if( _searchCallback_ ) {
+ node = folder->listPerson;
+ while( node ) {
+ AddrItemObject *aio = node->data;
+ if( aio && aio->type == ITEMTYPE_PERSON ) {
+ ItemPerson *person = node->data;
+ nodeEM = person->listEMail;
+ while( nodeEM ) {
+ ItemEMail *email = nodeEM->data;
+ nodeEM = g_list_next( nodeEM );
+ listEMail = g_list_append( listEMail, email );
+ }
+ }
+ node = g_list_next( node );
+ }
+ ( _searchCallback_ ) ( queryID, listEMail, _searchTarget_ );
+ g_list_free( listEMail );
+ }
+}
+
+LdapQuery *ldapsvr_locate_query( LdapServer *server, const gchar *searchTerm );
+
+/**
+ * Construct an LDAP query and initiate an LDAP search.
+ * \param server LDAP server object.
+ * \param queryID ID of search query to be executed.
+ */
+static void addrindex_search_ldap( LdapServer *server, const gint queryID ) {
+ LdapQuery *qry;
+ gchar *name;
+
+ if( ! server->searchFlag ) return;
+
+ /* Retire any aged queries */
+ ldapsvr_retire_query( server );
+
+ /* Test whether any queries for the same term exist */
+ qry = ldapsvr_locate_query( server, _searchTerm_ );
+ if( qry ) {
+ ItemFolder *folder = qry->folder;
+
+ /* Touch query to ensure it hangs around for a bit longer */
+ ldapqry_touch( qry );
+ if( folder ) {
+ addrindex_ldap_use_previous( folder, queryID );
+ return;
+ }
+ }
+
+ /* Construct a query */
+ qry = ldapqry_create();
+ ldapqry_set_query_id( qry, queryID );
+ ldapqry_set_search_value( qry, _searchTerm_ );
+ ldapqry_set_query_type( qry, LDAPQUERY_DYNAMIC );
+ ldapqry_set_callback_entry( qry, addrindex_ldap_entry_cb );
+ ldapqry_set_callback_end( qry, addrindex_ldap_end_cb );
+
+ /* Name the query */
+ name = g_strdup_printf( "Search for '%s'", _searchTerm_ );
+ ldapqry_set_name( qry, name );
+ g_free( name );
+
+ ldapsvr_add_query( server, qry );
+ ldapsvr_execute_query( server, qry );
+}
+
+/**
+ * Construct an LDAP query and initiate an LDAP search.
+ * \param server LDAP server object to search.
+ * \param searchTerm Search term to locate.
+ * \param callbackEnd Function to call when search has terminated.
+ *
+ */
+void addrindex_search_ldap_noid(
+ LdapServer *server, const gchar *searchTerm, void * callbackEnd )
+{
+ LdapQuery *qry;
+ gchar *name;
+
+ /* Construct a query */
+ qry = ldapqry_create();
+ ldapqry_set_search_value( qry, searchTerm );
+ ldapqry_set_query_type( qry, LDAPQUERY_STATIC );
+ ldapqry_set_callback_end( qry, callbackEnd );
+
+ /* Name the query */
+ name = g_strdup_printf( "Static Search for '%s'", searchTerm );
+ ldapqry_set_name( qry, name );
+ g_free( name );
+
+ ldapsvr_add_query( server, qry );
+ /* printf( "addrindex_search_ldap_noid::executing static search...\n" ); */
+ ldapsvr_execute_query( server, qry );
+}
+#endif
+
+/**
+ * Perform the previously registered search.
+ * \param addrIndex Address index object.
+ * \param queryID ID of search query to be executed.
+ * \return <i>TRUE</i> if search started successfully, or <i>FALSE</i> if
+ * failed.
+ */
+gboolean addrindex_start_search( AddressIndex *addrIndex, const gint queryID ) {
+ AddressInterface *iface;
+ AddressDataSource *ds;
+ GList *nodeIf;
+ GList *nodeDS;
+ gint type;
+
+ /* printf( "addrindex_start_search::%d::\n", queryID ); */
+ nodeIf = addrIndex->searchOrder;
+ while( nodeIf ) {
+ iface = nodeIf->data;
+ nodeIf = g_list_next( nodeIf );
+
+ if( ! iface->useInterface ) {
+ continue;
+ }
+
+ if( ! iface->externalQuery ) {
+ continue;
+ }
+
+ type = iface->type;
+ nodeDS = iface->listSource;
+ while( nodeDS ) {
+ ds = nodeDS->data;
+ nodeDS = g_list_next( nodeDS );
+#ifdef USE_LDAP
+ if( type == ADDR_IF_LDAP ) {
+ LdapServer *server = ds->rawDataSource;
+ addrindex_search_ldap( server, queryID );
+ }
+#endif
+ }
+ }
+ return TRUE;
+}
+
+/**
+ * Stop the previously registered search.
+ * \param addrIndex Address index object.
+ * \param queryID ID of search query to stop.
+ */
+void addrindex_stop_search( AddressIndex *addrIndex, const gint queryID ){
+#ifdef USE_LDAP
+ AddressInterface *iface;
+ AddressDataSource *ds;
+ GList *nodeIf;
+ GList *nodeDS;
+ gint type;
+
+ /* If query ID does not match, search has not been setup */
+ /* if( queryID != _queryID_ ) return; */
+
+ /* printf( "addrindex_stop_search::%d::\n", queryID ); */
+ nodeIf = addrIndex->searchOrder;
+ while( nodeIf ) {
+ iface = nodeIf->data;
+ nodeIf = g_list_next( nodeIf );
+
+ if( ! iface->useInterface ) {
+ continue;
+ }
+
+ type = iface->type;
+ nodeDS = iface->listSource;
+ while( nodeDS ) {
+ ds = nodeDS->data;
+ nodeDS = g_list_next( nodeDS );
+ if( type == ADDR_IF_LDAP ) {
+ LdapServer *server = ds->rawDataSource;
+ ldapsvr_stop_all_query( server );
+ }
+ }
+ }
+#endif
+}
+
+/**
+ * Read all address books that do not support dynamic queries.
+ * \param addrIndex Address index object.
+ */
+void addrindex_read_all( AddressIndex *addrIndex ) {
+ AddressInterface *iface;
+ AddressDataSource *ds;
+ GList *nodeIf;
+ GList *nodeDS;
+
+ nodeIf = addrIndex->searchOrder;
+ while( nodeIf ) {
+ iface = nodeIf->data;
+ nodeIf = g_list_next( nodeIf );
+
+ if( ! iface->useInterface ) {
+ continue;
+ }
+ if( iface->externalQuery ) {
+ continue;
+ }
+ nodeDS = iface->listSource;
+ while( nodeDS ) {
+ ds = nodeDS->data;
+ nodeDS = g_list_next( nodeDS );
+
+ /* Read address book */
+ if( addrindex_ds_get_modify_flag( ds ) ) {
+ addrindex_ds_read_data( ds );
+ continue;
+ }
+
+ if( ! addrindex_ds_get_read_flag( ds ) ) {
+ addrindex_ds_read_data( ds );
+ continue;
+ }
+ }
+ }
+ addrIndex->loadedFlag = TRUE;
+}
+
+/**
+ * This function is used by the address completion function to load
+ * addresses for all non-external address book interfaces.
+ *
+ * \param addrIndex Address index object.
+ * \param callBackFunc Function to be called when an address is
+ * to be loaded.
+ * \return <i>TRUE</i> if data loaded, <i>FALSE</i> if address index not loaded.
+ */
+gboolean addrindex_load_completion(
+ AddressIndex *addrIndex,
+ gint (*callBackFunc) ( const gchar *, const gchar *, const gchar * ) )
+{
+ AddressDataSource *ds;
+ AddressInterface *iface;
+ GList *nodeIf, *nodeDS;
+ GList *listP, *nodeP;
+ GList *nodeM;
+ gchar *sName, *sAddress, *sAlias, *sFriendly;
+
+ if( addrIndex == NULL ) return FALSE;
+
+ nodeIf = addrindex_get_interface_list( addrIndex );
+ while( nodeIf ) {
+ AddressInterface *iface = nodeIf->data;
+
+ nodeIf = g_list_next( nodeIf );
+ if( ! iface->useInterface ) {
+ continue;
+ }
+ if( iface->externalQuery ) {
+ continue;
+ }
+ nodeDS = iface->listSource;
+ while( nodeDS ) {
+ ds = nodeDS->data;
+
+ /* Read address book */
+ if( addrindex_ds_get_modify_flag( ds ) ) {
+ addrindex_ds_read_data( ds );
+ }
+
+ if( ! addrindex_ds_get_read_flag( ds ) ) {
+ addrindex_ds_read_data( ds );
+ }
+
+ /* Get all persons */
+ listP = addrindex_ds_get_all_persons( ds );
+ nodeP = listP;
+ while( nodeP ) {
+ ItemPerson *person = nodeP->data;
+ nodeM = person->listEMail;
+
+ /* Figure out name to use */
+ sName = person->nickName;
+ if( sName == NULL || *sName == '\0' ) {
+ sName = ADDRITEM_NAME(person);
+ }
+
+ /* Process each E-Mail address */
+ while( nodeM ) {
+ ItemEMail *email = nodeM->data;
+ /* Have mail */
+ sFriendly = sName;
+ sAddress = email->address;
+ if( sAddress || *sAddress != '\0' ) {
+ sAlias = ADDRITEM_NAME(email);
+ if( sAlias && *sAlias != '\0' ) {
+ sFriendly = sAlias;
+ }
+ ( callBackFunc ) ( sFriendly, sAddress, sName );
+ }
+
+ nodeM = g_list_next( nodeM );
+ }
+ nodeP = g_list_next( nodeP );
+ }
+ /* Free up the list */
+ g_list_free( listP );
+
+ nodeDS = g_list_next( nodeDS );
+ }
+ }
+
+ return TRUE;
+}
+
+/*
+ * End of Source.
+ */
+
+
/*
* Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 2001-2002 Match Grun
+ * Copyright (C) 2001-2003 Match Grun
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include <glib.h>
#include "addritem.h"
#include "addrcache.h"
+#include "addrquery.h"
#define ADDRESSBOOK_MAX_IFACE 4
#define ADDRESSBOOK_INDEX_FILE "addrbook--index.xml"
gboolean dirtyFlag;
GList *interfaceList;
GHashTable *hashCache;
+ gboolean loadedFlag;
+ GList *searchOrder;
};
typedef struct _AddressInterface AddressInterface;
GList *(*getAllGroups)( void * );
gchar *(*getName)( void * );
void (*setAccessFlag)( void *, void * );
+ gboolean externalQuery;
+ gint searchOrder;
+ void (*startSearch)( void * );
+ void (*stopSearch)( void * );
};
typedef struct _AddressDataSource AddressDataSource;
const gchar *value );
void addrindex_set_dirty ( AddressIndex *addrIndex,
const gboolean value );
+gboolean addrindex_get_loaded ( AddressIndex *addrIndex );
+
GList *addrindex_get_interface_list ( AddressIndex *addrIndex );
void addrindex_free_index ( AddressIndex *addrIndex );
void addrindex_print_index ( AddressIndex *addrIndex, FILE *stream );
GList *addrindex_ds_get_all_persons ( AddressDataSource *ds );
GList *addrindex_ds_get_all_groups ( AddressDataSource *ds );
+/* Search support */
+gint addrindex_setup_search ( AddressIndex *addrIndex,
+ const gchar *searchTerm,
+ const gpointer target,
+ AddrSearchCallbackFunc callBack );
+gboolean addrindex_start_search ( AddressIndex *addrIndex,
+ const gint queryID );
+void addrindex_stop_search ( AddressIndex *addrIndex,
+ const gint queryID );
+
+void addrindex_read_all ( AddressIndex *addrIndex );
+gboolean addrindex_load_completion(
+ AddressIndex *addrIndex,
+ gint (*callBackFunc)
+ ( const gchar *, const gchar *, const gchar * ) );
+
#endif /* __ADDRINDEX_H__ */
/*
/*
* Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 2001-2002 Match Grun
+ * Copyright (C) 2001-2003 Match Grun
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
fprintf( stream, "\t***\n" );
}
-/*
-* Create new address folder.
-*/
+/**
+ * Create new address folder.
+ * \return Initialized address folder object.
+ */
ItemFolder *addritem_create_item_folder( void ) {
ItemFolder *folder;
folder = g_new0( ItemFolder, 1 );
folder->listFolder = NULL;
folder->listPerson = NULL;
folder->listGroup = NULL;
+ folder->folderType = ADDRFOLDER_NONE;
+ folder->folderData = NULL;
return folder;
}
-/*
-* Copy address book folder.
-* Enter: item Folder to copy.
-* Return: A copy of the folder.
-*/
+/**
+ * Copy address book folder. Note that only the folder and not its contents are
+ * copied.
+ * \param item Folder to copy.
+ * \return A copy of the folder, or <i>NULL</i> if null argument supplied.
+ */
ItemFolder *addritem_copy_item_folder( ItemFolder *item ) {
ItemFolder *itemNew;
if( item ) {
itemNew = addritem_create_item_folder();
ADDRITEM_NAME(itemNew) = g_strdup( ADDRITEM_NAME(item) );
+ itemNew->folderType = item->folderType;
}
return itemNew;
}
folder->remarks = mgu_replace_string( folder->remarks, value );
}
-/*
-* Free address folder. Note: this does not free up the lists of children
-* (folders, groups and person). This should be done prior to calling this
-* function.
-*/
+/**
+ * Free address folder. Note: this does not free up the lists of children
+ * (folders, groups and person). This should be done prior to calling this
+ * function.
+ * \param folder Folder to free.
+ */
void addritem_free_item_folder( ItemFolder *folder ) {
g_return_if_fail( folder != NULL );
folder->listFolder = NULL;
folder->listGroup = NULL;
folder->listPerson = NULL;
+ folder->folderType = ADDRFOLDER_NONE;
+ folder->folderData = NULL;
g_free( folder );
}
fprintf( stream, "\tsub: %d\n", ADDRITEM_SUBTYPE(folder) );
fprintf( stream, "\tnam: '%s'\n", ADDRITEM_NAME(folder) );
fprintf( stream, "\trem: '%s'\n", folder->remarks );
+ fprintf( stream, "\ttyp: %d\n", folder->folderType );
fprintf( stream, "\t---\n" );
parent = ( ItemFolder * ) ADDRITEM_PARENT(folder);
if( parent ) {
return list;
}
+/**
+ * Format E-Mail address.
+ * \param email EMail item to format.
+ * \return Formatted string. Should be freed after use.
+ */
+gchar *addritem_format_email( ItemEMail *email ) {
+ gchar *address;
+ gchar *name;
+ ItemPerson *person;
+
+ address = NULL;
+ name = NULL;
+ if( ADDRITEM_NAME( email ) ) {
+ if( strlen( ADDRITEM_NAME( email ) ) ) {
+ name = ADDRITEM_NAME( email );
+ }
+ }
+ if( ! name ) {
+ person = ( ItemPerson * ) ADDRITEM_PARENT( email );
+ name = ADDRITEM_NAME( person );
+ }
+
+ if( name ) {
+ if( strchr_with_skip_quote( name, '"', ',' ) ) {
+ address = g_strdup_printf( "\"%s\" <%s>", name, email->address );
+ }
+ else {
+ address = g_strdup_printf( "%s <%s>", name, email->address );
+ }
+ }
+ else {
+ address = g_strdup_printf( "%s", email->address );
+ }
+ return address;
+}
+
/*
* End of Source.
*/
/*
* Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2002 Hiroyuki Yamamoto
+ * Copyright (C) 2001-2003 Match Grun
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
ITEMTYPE_DATASOURCE
} ItemObjectType;
+typedef enum {
+ ADDRFOLDER_NONE,
+ ADDRFOLDER_ROOT,
+ ADDRFOLDER_REGULAR,
+ ADDRFOLDER_CATEGORY,
+ ADDRFOLDER_LDAP_QUERY
+} AddressFolderType;
+
typedef struct _AddrItemObject AddrItemObject;
struct _AddrItemObject {
ItemObjectType type;
GList *listFolder; /* List of contained (child) folders */
GList *listPerson; /* List of contained persons */
GList *listGroup; /* List of contained (child) groups */
+ AddressFolderType folderType; /* Folder type */
+ gpointer *folderData; /* Pointer to folder's data */
};
typedef struct _ItemGroup ItemGroup;
void addritem_parse_first_last ( ItemPerson *person );
GList *addritem_folder_path ( const ItemFolder *folder,
const gboolean seq );
+gchar *addritem_format_email ( ItemEMail *email );
#endif /* __ADDRITEM_H__ */
/*
* Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2002 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2003 Hiroyuki Yamamoto
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
/*
* Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999,2000 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2003 Hiroyuki Yamamoto
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
/*
* Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2002 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2003 Hiroyuki Yamamoto
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
/*
* Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 2001 Match Grun
+ * Copyright (C) 2001-2003 Match Grun
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
/*
* Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 2001-2002 Match Grun
+ * Copyright (C) 2001-2003 Match Grun
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include "prefs_common.h"
#include "addressitem.h"
#include "mgutils.h"
-#include "syldap.h"
+#include "ldapserver.h"
+#include "ldapctrl.h"
+#include "ldaputil.h"
#include "editldap_basedn.h"
#include "manage_window.h"
#include "gtkutils.h"
+#define PAGE_BASIC 0
+#define PAGE_SEARCH 1
+#define PAGE_EXTENDED 2
+
#define ADDRESSBOOK_GUESS_LDAP_NAME "MyServer"
#define ADDRESSBOOK_GUESS_LDAP_SERVER "localhost"
GtkWidget *spinbtn_timeout;
GtkWidget *entry_bindDN;
GtkWidget *entry_bindPW;
- GtkWidget *entry_criteria;
GtkWidget *spinbtn_maxentry;
+ GtkWidget *entry_criteria;
+ GtkWidget *spinbtn_queryage;
+ GtkWidget *check_dynsearch;
} ldapedit;
+/**
+ * Parse out individual attribute names from criteria string.
+ * \param criteria Criteria string.
+ * \ctl Control object.
+ */
+static gboolean editldap_validate_criteria( gchar *criteria ) {
+ gchar *ptr;
+ gchar **splitStr;
+ gint i;
+ gboolean errorFlag;
+
+ errorFlag = TRUE;
+
+ /* Replace delimiters with spaces */
+ ptr = criteria;
+ while( *ptr ) {
+ if( *ptr == ',' || *ptr == ';' || *ptr == '|' )
+ *ptr = ' ';
+ ptr++;
+ }
+
+ /* Parse string */
+ splitStr = g_strsplit( criteria, " ", 0 );
+ i = 0;
+ while( TRUE ) {
+ if( splitStr[i] ) {
+ if( *splitStr[i] ) {
+ errorFlag = FALSE;
+ break;
+ }
+ }
+ else {
+ break;
+ }
+ i++;
+ }
+ g_strfreev( splitStr );
+ return errorFlag;
+}
+
/*
* Edit functions.
*/
if( ldapedit.statusbar != NULL ) {
gtk_statusbar_pop( GTK_STATUSBAR(ldapedit.statusbar), ldapedit.status_cid );
if( msg ) {
- gtk_statusbar_push( GTK_STATUSBAR(ldapedit.statusbar), ldapedit.status_cid, msg );
+ gtk_statusbar_push( GTK_STATUSBAR(ldapedit.statusbar),
+ ldapedit.status_cid, msg );
+ }
+ }
+}
+
+static gboolean edit_ldap_validate( void ) {
+ gchar *str;
+ gboolean errorFlag;
+ gint page;
+
+ errorFlag = FALSE;
+ str = gtk_editable_get_chars(
+ GTK_EDITABLE(ldapedit.entry_name), 0, -1 );
+ if( *str == '\0' ) {
+ page = PAGE_BASIC;
+ gtk_widget_grab_focus( ldapedit.entry_name );
+ edit_ldap_status_show( _( "A Name must be supplied." ) );
+ errorFlag = TRUE;
+ }
+ g_free( str );
+
+ if( ! errorFlag ) {
+ str = gtk_editable_get_chars(
+ GTK_EDITABLE(ldapedit.entry_server), 0, -1 );
+ if( *str == '\0' ) {
+ page = PAGE_BASIC;
+ gtk_widget_grab_focus( ldapedit.entry_server );
+ edit_ldap_status_show(
+ _( "A Hostname must be supplied for the server." ) );
+ errorFlag = TRUE;
+ }
+ g_free( str );
+ }
+
+ if( ! errorFlag ) {
+ str = gtk_editable_get_chars(
+ GTK_EDITABLE(ldapedit.entry_criteria), 0, -1 );
+ if( editldap_validate_criteria( str ) ) {
+ page = PAGE_SEARCH;
+ gtk_widget_grab_focus( ldapedit.entry_criteria );
+ edit_ldap_status_show(
+ _( "At least one LDAP search attribute should be supplied." ) );
+ errorFlag = TRUE;
}
+ g_free( str );
+ }
+
+ /* Switch to page with error */
+ if( errorFlag ) {
+ gtk_notebook_set_page( GTK_NOTEBOOK(ldapedit.notebook), page );
}
+
+ return errorFlag;
}
static void edit_ldap_ok( GtkWidget *widget, gboolean *cancelled ) {
- *cancelled = FALSE;
- gtk_main_quit();
+ if( ! edit_ldap_validate() ) {
+ *cancelled = FALSE;
+ gtk_main_quit();
+ }
}
static void edit_ldap_cancel( GtkWidget *widget, gboolean *cancelled ) {
}
}
-static void edit_ldap_switch_page( GtkWidget *widget ) {
- edit_ldap_status_show( "" );
-}
-
static void edit_ldap_server_check( void ) {
gchar *sHost, *sBind, *sPass;
gint iPort, iTime;
gchar *sBaseDN = NULL;
gint iBaseDN = 0;
gboolean flg;
+ GList *baseDN = NULL;
edit_ldap_status_show( "" );
flg = FALSE;
g_strchomp( sPass ); g_strchug( sPass );
if( *sHost != '\0' ) {
/* Test connection to server */
- if( syldap_test_connect_s( sHost, iPort ) ) {
+ if( ldaputil_test_connect( sHost, iPort ) ) {
/* Attempt to read base DN */
- GList *baseDN = syldap_read_basedn_s( sHost, iPort, sBind, sPass, iTime );
+ baseDN = ldaputil_read_basedn( sHost, iPort, sBind, sPass, iTime );
if( baseDN ) {
GList *node = baseDN;
while( node ) {
}
static void edit_ldap_search_reset( void ) {
- gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_criteria), SYLDAP_DFL_CRITERIA );
+ gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_criteria), LDAPCTL_DFL_ATTR_LIST );
}
static void addressbook_edit_ldap_dialog_create( gboolean *cancelled ) {
cancelled);
vbox = gtk_vbox_new( FALSE, 6 );
- /* gtk_container_set_border_width(GTK_CONTAINER(vbox), BORDER_WIDTH); */
gtk_widget_show( vbox );
gtk_container_add( GTK_CONTAINER( window ), vbox );
GTK_SIGNAL_FUNC(edit_ldap_ok), cancelled);
gtk_signal_connect(GTK_OBJECT(cancel_btn), "clicked",
GTK_SIGNAL_FUNC(edit_ldap_cancel), cancelled);
- gtk_signal_connect(GTK_OBJECT(notebook), "switch_page",
- GTK_SIGNAL_FUNC(edit_ldap_switch_page), NULL );
gtk_widget_show_all(vbox);
ldapedit.ok_btn = ok_btn;
ldapedit.cancel_btn = cancel_btn;
ldapedit.statusbar = statusbar;
- ldapedit.status_cid = gtk_statusbar_get_context_id( GTK_STATUSBAR(statusbar), "Edit LDAP Server Dialog" );
+ ldapedit.status_cid =
+ gtk_statusbar_get_context_id(
+ GTK_STATUSBAR(statusbar), "Edit LDAP Server Dialog" );
}
-void addressbook_edit_ldap_page_basic( gint pageNum, gchar *pageLbl ) {
+static void addressbook_edit_ldap_page_basic( gint pageNum, gchar *pageLbl ) {
GtkWidget *vbox;
GtkWidget *table;
GtkWidget *label;
vbox = gtk_vbox_new( FALSE, 8 );
gtk_widget_show( vbox );
gtk_container_add( GTK_CONTAINER( ldapedit.notebook ), vbox );
- /* gtk_container_set_border_width( GTK_CONTAINER (vbox), BORDER_WIDTH ); */
label = gtk_label_new( pageLbl );
gtk_widget_show( label );
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
entry_name = gtk_entry_new();
- gtk_table_attach(GTK_TABLE(table), entry_name, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
+ gtk_table_attach(GTK_TABLE(table), entry_name, 1, 2, top, (top + 1),
+ GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
/* Next row */
++top;
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
entry_server = gtk_entry_new();
- gtk_table_attach(GTK_TABLE(table), entry_server, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
+ gtk_table_attach(GTK_TABLE(table), entry_server, 1, 2, top, (top + 1),
+ GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
/* Next row */
++top;
gtk_box_pack_start (GTK_BOX (hbox_spin), spinbtn_port, FALSE, FALSE, 0);
gtk_widget_set_usize (spinbtn_port, 64, -1);
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbtn_port), TRUE);
- gtk_table_attach(GTK_TABLE(table), hbox_spin, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
+ gtk_table_attach(GTK_TABLE(table), hbox_spin, 1, 2, top, (top + 1),
+ GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
check_btn = gtk_button_new_with_label( _(" Check Server "));
gtk_table_attach(GTK_TABLE(table), check_btn, 2, 3, top, (top + 1), GTK_FILL, 0, 3, 0);
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
entry_baseDN = gtk_entry_new();
- gtk_table_attach(GTK_TABLE(table), entry_baseDN, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
+ gtk_table_attach(GTK_TABLE(table), entry_baseDN, 1, 2, top, (top + 1),
+ GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
lookdn_btn = gtk_button_new_with_label( _(" ... "));
gtk_table_attach(GTK_TABLE(table), lookdn_btn, 2, 3, top, (top + 1), GTK_FILL, 0, 3, 0);
+ /* Signal handlers */
gtk_signal_connect(GTK_OBJECT(check_btn), "clicked",
GTK_SIGNAL_FUNC(edit_ldap_server_check), NULL);
gtk_signal_connect(GTK_OBJECT(lookdn_btn), "clicked",
GTK_SIGNAL_FUNC(edit_ldap_basedn_select), NULL);
+ /* Done */
gtk_widget_show_all(vbox);
ldapedit.entry_name = entry_name;
ldapedit.entry_baseDN = entry_baseDN;
}
-void addressbook_edit_ldap_page_extended( gint pageNum, gchar *pageLbl ) {
+static void addressbook_edit_ldap_page_search( gint pageNum, gchar *pageLbl ) {
GtkWidget *vbox;
GtkWidget *table;
GtkWidget *label;
- GtkWidget *entry_bindDN;
- GtkWidget *entry_bindPW;
GtkWidget *entry_criteria;
GtkWidget *hbox_spin;
- GtkObject *spinbtn_timeout_adj;
- GtkWidget *spinbtn_timeout;
- GtkObject *spinbtn_maxentry_adj;
- GtkWidget *spinbtn_maxentry;
+ GtkObject *spinbtn_queryage_adj;
+ GtkWidget *spinbtn_queryage;
+ GtkWidget *check_dynsearch;
GtkWidget *reset_btn;
gint top;
vbox = gtk_vbox_new( FALSE, 8 );
gtk_widget_show( vbox );
gtk_container_add( GTK_CONTAINER( ldapedit.notebook ), vbox );
- /* gtk_container_set_border_width( GTK_CONTAINER (vbox), BORDER_WIDTH ); */
label = gtk_label_new( pageLbl );
gtk_widget_show( label );
/* First row */
top = 0;
- label = gtk_label_new(_("Search Criteria"));
+ label = gtk_label_new(_("Search Attributes"));
gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
entry_criteria = gtk_entry_new();
- gtk_table_attach(GTK_TABLE(table), entry_criteria, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
+ gtk_table_attach(GTK_TABLE(table), entry_criteria, 1, 2, top, (top + 1),
+ GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
- reset_btn = gtk_button_new_with_label( _(" Reset "));
+ reset_btn = gtk_button_new_with_label( _(" Defaults "));
gtk_table_attach(GTK_TABLE(table), reset_btn, 2, 3, top, (top + 1), GTK_FILL, 0, 3, 0);
/* Next row */
++top;
+ label = gtk_label_new(_("Max Query Age (secs)"));
+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+
+ hbox_spin = gtk_hbox_new (FALSE, 8);
+ spinbtn_queryage_adj = gtk_adjustment_new(
+ LDAPCTL_DFL_QUERY_AGE, 1, LDAPCTL_MAX_QUERY_AGE, 10, 1000, 1000 );
+ spinbtn_queryage = gtk_spin_button_new(GTK_ADJUSTMENT (spinbtn_queryage_adj), 1, 0);
+ gtk_box_pack_start (GTK_BOX (hbox_spin), spinbtn_queryage, FALSE, FALSE, 0);
+ gtk_widget_set_usize (spinbtn_queryage, 64, -1);
+ gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbtn_queryage), TRUE);
+ gtk_table_attach(GTK_TABLE(table), hbox_spin, 1, 2, top, (top + 1),
+ GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
+
+ /* Next row */
+ ++top;
+ check_dynsearch = gtk_check_button_new_with_label(
+ _("Include server in dynamic search") );
+ gtk_table_attach(GTK_TABLE(table), check_dynsearch, 1, 3, top, (top + 1),
+ GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
+
+ /* Signal handlers */
+ gtk_signal_connect(GTK_OBJECT(reset_btn), "clicked",
+ GTK_SIGNAL_FUNC(edit_ldap_search_reset), NULL);
+
+ /* Done */
+ gtk_widget_show_all(vbox);
+
+ ldapedit.entry_criteria = entry_criteria;
+ ldapedit.spinbtn_queryage = spinbtn_queryage;
+ ldapedit.check_dynsearch = check_dynsearch;
+}
+
+static void addressbook_edit_ldap_page_extended( gint pageNum, gchar *pageLbl ) {
+ GtkWidget *vbox;
+ GtkWidget *table;
+ GtkWidget *label;
+ GtkWidget *entry_bindDN;
+ GtkWidget *entry_bindPW;
+ GtkWidget *hbox_spin;
+ GtkObject *spinbtn_timeout_adj;
+ GtkWidget *spinbtn_timeout;
+ GtkObject *spinbtn_maxentry_adj;
+ GtkWidget *spinbtn_maxentry;
+ gint top;
+
+ vbox = gtk_vbox_new( FALSE, 8 );
+ gtk_widget_show( vbox );
+ gtk_container_add( GTK_CONTAINER( ldapedit.notebook ), vbox );
+
+ label = gtk_label_new( pageLbl );
+ gtk_widget_show( label );
+ gtk_notebook_set_tab_label(
+ GTK_NOTEBOOK( ldapedit.notebook ),
+ gtk_notebook_get_nth_page( GTK_NOTEBOOK( ldapedit.notebook ), pageNum ), label );
+
+ table = gtk_table_new( LDAPEDIT_TABLE_ROWS, LDAPEDIT_TABLE_COLS, FALSE);
+ gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
+ gtk_container_set_border_width( GTK_CONTAINER(table), 8 );
+ gtk_table_set_row_spacings(GTK_TABLE(table), 8);
+ gtk_table_set_col_spacings(GTK_TABLE(table), 8);
+
+ /* Next row */
+ top = 0;
label = gtk_label_new(_("Bind DN"));
gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
entry_bindDN = gtk_entry_new();
- gtk_table_attach(GTK_TABLE(table), entry_bindDN, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
+ gtk_table_attach(GTK_TABLE(table), entry_bindDN, 1, 2, top, (top + 1),
+ GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
/* Next row */
++top;
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
entry_bindPW = gtk_entry_new();
- gtk_table_attach(GTK_TABLE(table), entry_bindPW, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
+ gtk_table_attach(GTK_TABLE(table), entry_bindPW, 1, 2, top, (top + 1),
+ GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
/* Next row */
++top;
gtk_box_pack_start (GTK_BOX (hbox_spin), spinbtn_timeout, FALSE, FALSE, 0);
gtk_widget_set_usize (spinbtn_timeout, 64, -1);
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbtn_timeout), TRUE);
- gtk_table_attach(GTK_TABLE(table), hbox_spin, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
+ gtk_table_attach(GTK_TABLE(table), hbox_spin, 1, 2, top, (top + 1),
+ GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
/* Next row */
++top;
gtk_box_pack_start (GTK_BOX (hbox_spin), spinbtn_maxentry, FALSE, FALSE, 0);
gtk_widget_set_usize (spinbtn_maxentry, 64, -1);
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbtn_maxentry), TRUE);
- gtk_table_attach(GTK_TABLE(table), hbox_spin, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
-
- gtk_signal_connect(GTK_OBJECT(reset_btn), "clicked",
- GTK_SIGNAL_FUNC(edit_ldap_search_reset), NULL);
+ gtk_table_attach(GTK_TABLE(table), hbox_spin, 1, 2, top, (top + 1),
+ GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
+ /* Done */
gtk_widget_show_all(vbox);
- ldapedit.entry_criteria = entry_criteria;
ldapedit.entry_bindDN = entry_bindDN;
ldapedit.entry_bindPW = entry_bindPW;
ldapedit.spinbtn_timeout = spinbtn_timeout;
gint page = 0;
addressbook_edit_ldap_dialog_create( cancelled );
addressbook_edit_ldap_page_basic( page++, _( "Basic" ) );
+ addressbook_edit_ldap_page_search( page++, _( "Search" ) );
addressbook_edit_ldap_page_extended( page++, _( "Extended" ) );
gtk_widget_show_all( ldapedit.window );
}
return GPOINTER_TO_INT(gtk_object_get_user_data(GTK_OBJECT(menuitem)));
}
+/**
+ * Format criteria list for display.
+ * \param ctl Control object.
+ * \return Formatted string, or <i>NULL</i> if no attributes found.
+ */
+static gchar *editldap_build_criteria_list( const LdapControl *ctl ) {
+ gchar *str = NULL;
+ gchar *tmp = NULL;
+ GList *node;
+
+ node = ldapctl_get_criteria_list( ctl );
+ while( node ) {
+ gchar *attr = node->data;
+ if( str ) {
+ tmp = g_strdup_printf( "%s, %s", str, attr );
+ g_free( str );
+ str = tmp;
+ tmp = NULL;
+ }
+ else {
+ str = g_strdup( attr );
+ }
+ node = g_list_next( node );
+ }
+
+ return str;
+}
+
+/**
+ * Parse out individual attribute names from criteria string.
+ * \param criteria Criteria string.
+ * \ctl Control object.
+ */
+static void editldap_parse_criteria( gchar *criteria, LdapControl *ctl ) {
+ gchar *ptr;
+ gchar **splitStr;
+ gint i;
+
+ /* Replace delimiters with spaces */
+ ptr = criteria;
+ while( *ptr ) {
+ if( *ptr == ',' || *ptr == ';' || *ptr == '|' )
+ *ptr = ' ';
+ ptr++;
+ }
+
+ /* Parse string */
+ ldapctl_criteria_list_clear( ctl );
+ splitStr = g_strsplit( criteria, " ", 0 );
+ i = 0;
+ while( TRUE ) {
+ if( splitStr[i] ) {
+ if( *splitStr[i] ) {
+ ldapctl_criteria_list_add( ctl, splitStr[i] );
+ }
+ }
+ else {
+ break;
+ }
+ i++;
+ }
+ g_strfreev( splitStr );
+}
+
+/**
+ * Clear entry fields to reasonable defaults (for a new server entry).
+ */
+static void edit_ldap_clear_fields( void ) {
+ gtk_entry_set_text(
+ GTK_ENTRY(ldapedit.entry_name), ADDRESSBOOK_GUESS_LDAP_NAME );
+ gtk_entry_set_text(
+ GTK_ENTRY(ldapedit.entry_server), ADDRESSBOOK_GUESS_LDAP_SERVER );
+ gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_baseDN), "");
+ gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_bindDN), "");
+ gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_bindPW), "");
+ gtk_spin_button_set_value(
+ GTK_SPIN_BUTTON( ldapedit.spinbtn_port ), LDAPCTL_DFL_PORT );
+ gtk_spin_button_set_value(
+ GTK_SPIN_BUTTON( ldapedit.spinbtn_timeout ), LDAPCTL_DFL_TIMEOUT );
+ gtk_spin_button_set_value(
+ GTK_SPIN_BUTTON( ldapedit.spinbtn_maxentry ), LDAPCTL_DFL_TIMEOUT );
+ gtk_entry_set_text(
+ GTK_ENTRY(ldapedit.entry_criteria), LDAPCTL_DFL_ATTR_LIST );
+ gtk_spin_button_set_value(
+ GTK_SPIN_BUTTON(ldapedit.spinbtn_queryage), LDAPCTL_DFL_QUERY_AGE );
+ gtk_toggle_button_set_active(
+ GTK_TOGGLE_BUTTON( ldapedit.check_dynsearch), TRUE );
+}
+
+/**
+ * Load entry fields from server control data.
+ * \param server Server object.
+ */
+static void edit_ldap_set_fields( LdapServer *server ) {
+ LdapControl *ctl;
+ gchar *crit;
+
+ if( ldapsvr_get_name( server ) )
+ gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_name),
+ ldapsvr_get_name( server ) );
+
+ ctl = server->control;
+ if( ctl->hostName )
+ gtk_entry_set_text(
+ GTK_ENTRY(ldapedit.entry_server), ctl->hostName);
+ if( ctl->baseDN )
+ gtk_entry_set_text(
+ GTK_ENTRY(ldapedit.entry_baseDN), ctl->baseDN );
+ if( ctl->bindDN )
+ gtk_entry_set_text(
+ GTK_ENTRY(ldapedit.entry_bindDN), ctl->bindDN );
+ if( ctl->bindPass )
+ gtk_entry_set_text(
+ GTK_ENTRY(ldapedit.entry_bindPW), ctl->bindPass );
+ gtk_spin_button_set_value(
+ GTK_SPIN_BUTTON(ldapedit.spinbtn_port), ctl->port );
+ gtk_spin_button_set_value(
+ GTK_SPIN_BUTTON(ldapedit.spinbtn_timeout), ctl->timeOut );
+ gtk_spin_button_set_value(
+ GTK_SPIN_BUTTON(ldapedit.spinbtn_maxentry), ctl->maxEntries );
+
+ /* Format criteria */
+ crit = editldap_build_criteria_list( ctl );
+ if( crit ) {
+ gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_criteria), crit );
+ g_free( crit );
+ }
+ else {
+ gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_criteria), "" );
+ }
+ gtk_spin_button_set_value(
+ GTK_SPIN_BUTTON(ldapedit.spinbtn_queryage), ctl->maxQueryAge );
+ gtk_toggle_button_set_active(
+ GTK_TOGGLE_BUTTON( ldapedit.check_dynsearch), server->searchFlag );
+}
+
AdapterDSource *addressbook_edit_ldap( AddressIndex *addrIndex, AdapterDSource *ads ) {
static gboolean cancelled;
gchar *sName, *sHost, *sBase, *sBind, *sPass, *sCrit;
- gint iPort, iMaxE, iTime;
+ gint iPort, iMaxE, iTime, iAge;
+ gboolean bSrch;
AddressDataSource *ds = NULL;
- SyldapServer *server = NULL;
+ LdapServer *server = NULL;
+ LdapControl *ctl = NULL;
gboolean fin;
if (!ldapedit.window)
addressbook_edit_ldap_create(&cancelled);
- gtk_notebook_set_page( GTK_NOTEBOOK(ldapedit.notebook), 0 );
+ gtk_notebook_set_page( GTK_NOTEBOOK(ldapedit.notebook), PAGE_BASIC );
gtk_widget_grab_focus(ldapedit.ok_btn);
gtk_widget_grab_focus(ldapedit.entry_name);
gtk_widget_show(ldapedit.window);
if( ads ) {
ds = ads->dataSource;
server = ds->rawDataSource;
- if ( syldap_get_name( server ) )
- gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_name),
- syldap_get_name( server ) );
- if (server->hostName)
- gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_server), server->hostName);
- gtk_spin_button_set_value( GTK_SPIN_BUTTON( ldapedit.spinbtn_port ), server->port );
- gtk_spin_button_set_value( GTK_SPIN_BUTTON( ldapedit.spinbtn_timeout ), server->timeOut );
- if (server->baseDN)
- gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_baseDN), server->baseDN);
- if (server->searchCriteria)
- gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_criteria), server->searchCriteria);
- if (server->bindDN)
- gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_bindDN), server->bindDN);
- if (server->bindPass)
- gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_bindPW), server->bindPass);
- gtk_spin_button_set_value( GTK_SPIN_BUTTON( ldapedit.spinbtn_maxentry ), server->maxEntries );
- gtk_window_set_title( GTK_WINDOW(ldapedit.window), _("Edit LDAP Server"));
+ edit_ldap_set_fields( server );
+ gtk_window_set_title(
+ GTK_WINDOW(ldapedit.window), _("Edit LDAP Server"));
}
else {
- gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_name), ADDRESSBOOK_GUESS_LDAP_NAME );
- gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_server), ADDRESSBOOK_GUESS_LDAP_SERVER );
- gtk_spin_button_set_value( GTK_SPIN_BUTTON( ldapedit.spinbtn_port ), SYLDAP_DFL_PORT );
- gtk_spin_button_set_value( GTK_SPIN_BUTTON( ldapedit.spinbtn_timeout ), SYLDAP_DFL_TIMEOUT );
- gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_baseDN), "");
- gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_criteria), SYLDAP_DFL_CRITERIA );
- gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_bindDN), "");
- gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_bindPW), "");
- gtk_spin_button_set_value( GTK_SPIN_BUTTON( ldapedit.spinbtn_maxentry ), SYLDAP_MAX_ENTRIES );
- gtk_window_set_title( GTK_WINDOW(ldapedit.window), _("Add New LDAP Server"));
+ edit_ldap_clear_fields();
+ gtk_window_set_title(
+ GTK_WINDOW(ldapedit.window), _("Add New LDAP Server"));
}
gtk_main();
gtk_widget_hide(ldapedit.window);
if (cancelled == TRUE) return NULL;
- fin = FALSE;
sName = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_name), 0, -1 );
sHost = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_server), 0, -1 );
- iPort = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( ldapedit.spinbtn_port ) );
- iTime = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( ldapedit.spinbtn_timeout ) );
sBase = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_baseDN), 0, -1 );
sCrit = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_criteria), 0, -1 );
sBind = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_bindDN), 0, -1 );
sPass = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_bindPW), 0, -1 );
+ iPort = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( ldapedit.spinbtn_port ) );
+ iTime = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( ldapedit.spinbtn_timeout ) );
iMaxE = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( ldapedit.spinbtn_maxentry ) );
+ iAge = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( ldapedit.spinbtn_queryage ) );
+ bSrch = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( ldapedit.check_dynsearch ) );
+ fin = FALSE;
if( *sName == '\0' ) fin = TRUE;
if( *sHost == '\0' ) fin = TRUE;
- if( *sBase == '\0' ) fin = TRUE;
if( ! fin ) {
+ /* Save changes */
if( ! ads ) {
- server = syldap_create();
+ /* New server */
+ server = ldapsvr_create();
ds = addrindex_index_add_datasource( addrIndex, ADDR_IF_LDAP, server );
ads = addressbook_create_ds_adapter( ds, ADDR_LDAP, NULL );
}
+ ctl = server->control;
addressbook_ads_set_name( ads, sName );
- syldap_set_name( server, sName );
- syldap_set_host( server, sHost );
- syldap_set_port( server, iPort );
- syldap_set_base_dn( server, sBase );
- syldap_set_bind_dn( server, sBind );
- syldap_set_bind_password( server, sPass );
- syldap_set_search_criteria( server, sCrit );
- syldap_set_max_entries( server, iMaxE );
- syldap_set_timeout( server, iTime );
+ ldapsvr_set_name( server, sName );
+ ldapsvr_set_search_flag( server, bSrch );
+ ldapctl_set_host( ctl, sHost );
+ ldapctl_set_base_dn( ctl, sBase );
+ ldapctl_set_bind_dn( ctl, sBind );
+ ldapctl_set_bind_password( ctl, sPass );
+ ldapctl_set_port( ctl, iPort );
+ ldapctl_set_max_entries( ctl, iMaxE );
+ ldapctl_set_timeout( ctl, iTime );
+ ldapctl_set_max_query_age( ctl, iAge );
+
+ /* Save attributes */
+ editldap_parse_criteria( sCrit, ctl );
+
}
g_free( sName );
g_free( sHost );
/*
* Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 2001 Match Grun
+ * Copyright (C) 2001-2003 Match Grun
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
/*
* Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 2001 Match Grun
+ * Copyright (C) 2001-2003 Match Grun
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include "intl.h"
#include "prefs_common.h"
-#include "syldap.h"
+#include "ldaputil.h"
#include "mgutils.h"
#include "gtkutils.h"
#include "manage_window.h"
ldapedit_basedn.ok_btn = ok_btn;
ldapedit_basedn.cancel_btn = cancel_btn;
ldapedit_basedn.statusbar = statusbar;
- ldapedit_basedn.status_cid = gtk_statusbar_get_context_id( GTK_STATUSBAR(statusbar), "Edit LDAP Select Base DN" );
+ ldapedit_basedn.status_cid =
+ gtk_statusbar_get_context_id(
+ GTK_STATUSBAR(statusbar), "Edit LDAP Select Base DN" );
}
-void edit_ldap_bdn_load_data( const gchar *hostName, const gint iPort, const gint tov, const gchar* bindDN,
- const gchar *bindPW ) {
+void edit_ldap_bdn_load_data(
+ const gchar *hostName, const gint iPort, const gint tov,
+ const gchar* bindDN, const gchar *bindPW )
+{
gchar *sHost;
gchar *sMsg = NULL;
gchar sPort[20];
gboolean flgConn;
gboolean flgDN;
+ GList *baseDN = NULL;
edit_ldap_bdn_status_show( "" );
gtk_clist_clear(GTK_CLIST(ldapedit_basedn.basedn_list));
gtk_label_set_text(GTK_LABEL(ldapedit_basedn.port_label), sPort);
if( *sHost != '\0' ) {
/* Test connection to server */
- if( syldap_test_connect_s( sHost, iPort ) ) {
+ if( ldaputil_test_connect( sHost, iPort ) ) {
/* Attempt to read base DN */
- GList *baseDN = syldap_read_basedn_s( sHost, iPort, bindDN, bindPW, tov );
+ baseDN = ldaputil_read_basedn( sHost, iPort, bindDN, bindPW, tov );
if( baseDN ) {
GList *node = baseDN;
gchar *text[2] = { NULL, NULL };
/*
* Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 2001 Match Grun
+ * Copyright (C) 2001-2003 Match Grun
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
void (*callBackEnd)( void * );
ItemFolder *folder; /* Reference to folder in cache */
LdapServer *server; /* Reference to (parent) LDAP server */
- /* SyldapServer *server; */ /* Reference to (parent) LDAP server */
};
/* Function prototypes */