/* addresses.c */
#include "ml.h"
Menu address_file_menu[] = {
{ NULL, "add", NUL_TERM,
address_add, NULL, 0, NULL, NULL, BTN_SELECTION },
{ NULL, "remove", NUL_TERM,
address_remove, NULL, 0, NULL, NULL, BTN_NOSELECTION },
{ NULL, "modify", NUL_TERM,
address_modify, NULL, 0, NULL, NULL, BTN_NOSELECTION },
{ NULL, "close_window", NUL_TERM,
address_close_window, NULL, 0, NULL, NULL, BTN_ON },
};
Menu address_book_menu[] = {
{ NULL, "file_menu", NUL_TERM,
NULL, address_file_menu, XtNumber(address_file_menu),
NULL, NULL, BTN_ON },
{ NULL, "search", NUL_TERM,
address_search, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "reset", NUL_TERM,
address_reset, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "HELP", NUL_TERM,
address_help, NULL, 0, NULL, NULL, BTN_ON },
};
#ifdef __STDC__
Address_Book_Info *new_address_book_info(void)
#else
Address_Book_Info *new_address_book_info()
#endif
{
Address_Book_Info *address_book_info =
(Address_Book_Info *) fs_get(sizeof(Address_Book_Info));
address_book_info->name = NULL;
address_book_info->address = NULL;
address_book_info->comment = NULL;
address_book_info->groups = NULL;
address_book_info->next = NULL;
address_book_info->prev = NULL;
return(address_book_info);
}
#ifdef __STDC__
void free_address_book_info(Address_Book_Info *address_book_info)
#else
void free_address_book_info(address_book_info)
Address_Book_Info *address_book_info;
#endif
{
if(address_book_info != NULL) {
if(address_book_info->name != NULL)
fs_give((void **) &address_book_info->name);
if(address_book_info->address != NULL)
fs_give((void **) &address_book_info->address);
if(address_book_info->comment != NULL)
fs_give((void **) &address_book_info->comment);
if(address_book_info->groups != NULL)
fs_give((void **) &address_book_info->groups);
fs_give((void **) &address_book_info);
}
return;
}
#ifdef __STDC__
void create_address_book_window(Tool w)
#else
void create_address_book_window(w)
Tool w;
#endif
{
Arg args[ARGLISTSIZE];
int n = 0;
XtTranslations translations;
Address_Book *address_book;
Tool form, menubar;
if(session->address_book != NULL) {
if(session->address_book->is_realized == TRUE)
de_iconify(session->address_book->shell);
else {
XtPopup(session->address_book->shell, XtGrabNone);
session->address_book->is_realized = TRUE;
}
return;
}
address_book = (Address_Book *) fs_get(sizeof(Address_Book));
address_book->is_realized = FALSE;
session->address_book = address_book;
address_book->current = NULL;
address_book->button_state = BTN_ON | BTN_NOSELECTION;
XtSetArg (args[n], XmNdeleteResponse, XmDO_NOTHING); n++;
address_book->shell = XtCreatePopupShell("address",topLevelShellWidgetClass,
session->shell, args, n);
AddDestroyCallback (address_book->shell);
n = 0;
setup_editres(address_book->shell);
if(addr_icon != (Pixmap) None)
XtVaSetValues(address_book->shell,
XmNiconPixmap,addr_icon,
NULL);
form = XmCreateForm(address_book->shell, "form", args, n ); n = 0;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n ++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n ++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n ++;
menubar = XmCreateMenuBar(form, "menubar", args, n); n = 0;
XtManageChild(menubar);
create_buttons(NULL, menubar, address_book_menu,
XtNumber(address_book_menu),
address_book->button_state,
(XtPointer) address_book,
ROOTMENULEVEL);
address_book->name =
create_text_field(form, menubar,
"name", NULL, 0, NULL, NULL);
address_book->address =
create_text_field(form, address_book->name,
"addr", NULL, 0, NULL, NULL);
address_book->groups =
create_text_field(form, address_book->address,
"grps", NULL, 0, NULL, NULL);
address_book->comment =
create_text_field(form, address_book->groups,
"cmmt", NULL, 0, NULL, NULL);
XtSetArg(args[n], XmNscrollBarDisplayPolicy, XmSTATIC); n ++;
XtSetArg(args[n], XmNlistSizePolicy, XmCONSTANT); n ++;
XtSetArg(args[n], XmNselectionPolicy, XmSINGLE_SELECT); n ++;
address_book->list = XmCreateScrolledList(form,"list",args,n); n = 0;
XtAddCallback(address_book->list, XmNsingleSelectionCallback,
(XtCallbackProc) address_book_select, address_book);
XtAddCallback(address_book->list, XmNdefaultActionCallback,
(XtCallbackProc) address_book_select, address_book);
translations = XtParseTranslationTable(GLOBAL_addresses_pop_translations);
XtOverrideTranslations(address_book->list, translations);
XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n ++;
XtSetArg(args[n], XmNtopWidget, address_book->comment); n ++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n ++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n ++;
XtSetArg(args[n], XmNrightPosition, 50); n ++;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n ++;
XtSetValues(XtParent(address_book->list), args, n); n = 0;
XtSetArg(args[n], XmNscrollBarDisplayPolicy, XmSTATIC); n ++;
XtSetArg(args[n], XmNlistSizePolicy, XmCONSTANT); n ++;
XtSetArg(args[n], XmNselectionPolicy, XmSINGLE_SELECT); n ++;
address_book->search_list =
XmCreateScrolledList(form,"slist",args,n); n = 0;
XtAddCallback(address_book->search_list, XmNsingleSelectionCallback,
(XtCallbackProc) address_book_select, address_book);
XtAddCallback(address_book->search_list, XmNdefaultActionCallback,
(XtCallbackProc) address_book_select, address_book);
translations = XtParseTranslationTable(GLOBAL_addresses_pop_translations);
XtOverrideTranslations(address_book->search_list, translations);
XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n ++;
XtSetArg(args[n], XmNtopWidget, address_book->comment); n ++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n ++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n ++;
XtSetArg(args[n], XmNleftPosition, 50); n ++;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n ++;
XtSetValues(XtParent(address_book->search_list), args, n); n = 0;
XtAddCallback(address_book->shell, XmNpopdownCallback,
(XtCallbackProc) address_book_popdown, address_book);
XtAddCallback(address_book->shell, XmNdestroyCallback,
(XtCallbackProc) address_book_destroy, address_book);
address_sort(address_book);
stuff_address_book(address_book);
XtManageChild(address_book->search_list);
XtManageChild(address_book->list);
XtManageChild(form);
XtManageChild(address_book->shell);
XtPopup(address_book->shell,XtGrabNone);
address_book->is_realized = TRUE;
return;
}
#ifdef __STDC__
void address_close_window(Tool w,Address_Book *address_book,XtPointer xp)
#else
void address_close_window(w,address_book,xp)
Tool w;
Address_Book *address_book;
XtPointer xp;
#endif
{
XtPopdown(address_book->shell);
address_book->is_realized = FALSE;
return;
}
#ifdef __STDC__
void address_book_popdown(Tool w,Address_Book *address_book,XtPointer xp)
#else
void address_book_popdown(w,address_book,xp)
Tool w;
Address_Book *address_book;
XtPointer xp;
#endif
{
address_book->is_realized = FALSE;
return;
}
#ifdef __STDC__
void address_book_destroy(Tool w,Address_Book *address_book,XtPointer xp)
#else
void address_book_destroy(w,address_book,xp)
Tool w;
Address_Book *address_book;
XtPointer xp;
#endif
{
XtDestroyWidget(address_book->shell);
fs_give((void **) &session->address_book);
session->address_book = NULL;
return;
}
#ifdef __STDC__
void address_book_select(Tool w, Address_Book *address_book,
XmListCallbackStruct *cb)
#else
void address_book_select(w,address_book,cb)
Tool w;
Address_Book *address_book;
XmListCallbackStruct *cb;
#endif
{
unsigned char *str;
Address_Book_Info *info;
Tool other;
if(w == address_book->list)
other = address_book->search_list;
else
other = address_book->list;
XmListDeselectAllItems(other);
XmStringGetLtoR(cb->item,XmSTRING_DEFAULT_CHARSET,(char **)&str);
if((address_book->current != NULL) &&
(ml_strcoll(str,address_book->current->name) == STRMATCH) &&
(address_book->current_list == w)) {
address_book_context_switch(address_book,address_book->current,NULL);
address_book->button_state |= BTN_NOSELECTION;
address_book->button_state &= ~BTN_SELECTION;
}
else {
for(info = session->addresses; info ; info = info->prev ) {
if((ml_strcoll(info->name,str)) == STRMATCH) {
address_book_context_switch(address_book,address_book->current, info);
address_book->button_state |= BTN_SELECTION;
address_book->button_state &= ~BTN_NOSELECTION;
}
}
}
fs_give((void **) &str);
address_book->current_list = w;
check_buttons(address_book_menu, XtNumber(address_book_menu),
NULL, address_book->button_state);
return;
}
#ifdef __STDC__
void address_book_context_switch(Address_Book *address_book,
Address_Book_Info *old,
Address_Book_Info *new)
#else
void address_book_context_switch(address_book,old,new)
Address_Book *address_book;
Address_Book_Info *old;
Address_Book_Info *new;
#endif
{
if(old != NULL) {
if(old->name != NULL)
fs_give((void **) &old->name);
old->name = GetUnTextField(address_book->name);
if(old->address != NULL)
fs_give((void **) &old->address);
old->address = GetUnTextField(address_book->address);
if(old->groups != NULL)
fs_give((void **) &old->groups);
old->groups = GetUnTextField(address_book->groups);
if(old->comment != NULL)
fs_give((void **) &old->comment);
old->comment = GetUnTextField(address_book->comment);
}
if(new != NULL) {
TextSetString(address_book->name,
(new->name != NULL)
? new->name
: (unsigned char *) EMPTYSTR);
TextSetString(address_book->address,
(new->address != NULL)
? new->address
: (unsigned char *) EMPTYSTR);
TextSetString(address_book->groups,
(new->groups != NULL)
? new->groups
: (unsigned char *) EMPTYSTR);
TextSetString(address_book->comment,
(new->comment != NULL)
? new->comment
: (unsigned char *) EMPTYSTR);
}
else {
TextSetString(address_book->name, (unsigned char *) EMPTYSTR);
TextSetString(address_book->address,(unsigned char *) EMPTYSTR);
TextSetString(address_book->groups, (unsigned char *) EMPTYSTR);
TextSetString(address_book->comment,(unsigned char *) EMPTYSTR);
}
address_book->current = new;
return;
}
#ifdef __STDC__
void stuff_address_book(Address_Book *address_book)
#else
void stuff_address_book(address_book)
Address_Book *address_book;
#endif
{
Address_Book_Info *info;
XmString xstr;
for(info = session->addresses; info ; info = info->prev) {
xstr = XmStringCreateSimple((char *) info->name);
XmListAddItemUnselected(address_book->list,xstr,0);
XmStringFree(xstr);
}
return;
}
#ifdef __STDC__
void address_search(Tool w, Address_Book *address_book, XtPointer xp)
#else
void address_search(w,address_book,xp)
Tool w;
Address_Book *address_book;
XtPointer xp;
#endif
{
Address_Book_Info *info;
XmString xstr;
Boolean found = FALSE;
/* Search on the current window contents */
unsigned char *name = GetUnTextField(address_book->name);
unsigned char *address = GetUnTextField(address_book->address);
unsigned char *groups = GetUnTextField(address_book->groups);
unsigned char *comment = GetUnTextField(address_book->comment);
/* Nothing to search for. */
if((*name == NUL_TERM) && (*address == NUL_TERM)
&& (*groups == NUL_TERM) && (*comment == NUL_TERM))
return;
/* Let 'em know we're busy. */
push_cursor(WATCH_CURSOR);
address_book->current = NULL;
XmListDeleteAllItems(address_book->search_list);
/*
* Find a match on any field in our internal list, and
* put it in the search list widget
*/
for(info = session->addresses; info; info = info->prev) {
if((address_searchit(info->name,name))
|| (address_searchit(info->address,address))
|| (address_searchit(info->groups,groups))
|| (address_searchit(info->comment,comment))) {
found = TRUE;
xstr = XmStringCreateSimple((char *) info->name);
XmListAddItemUnselected(address_book->search_list,xstr,0);
XmStringFree(xstr);
}
}
/*
* Popup the first one in the list. This will call our selection
* callback before it's done, so we don't have to tweak anything.
*/
if(found) {
XmListSelectPos(address_book->search_list,1,TRUE);
}
pop_cursor();
return;
}
/*
* This isn't the best search algorithm, but it doesn't have to be.
* We're looking for any substring match, case insensitive.
* Empty strings or null strings don't count.
*/
/* i18n-broken */
#ifdef __STDC__
Boolean address_searchit(unsigned char *str,unsigned char *pat)
#else
Boolean address_searchit(str,pat)
unsigned char *str;
unsigned char *pat;
#endif
{
register unsigned char *ptr;
if((str == NULL) || (pat == NULL) || (*pat == NUL_TERM))
return(FALSE);
for(ptr = str; *ptr; ptr ++ )
if(strncasecmp((char *) ptr,(char *) pat,strlen((char *)pat)) == STRMATCH)
return(TRUE);
return(FALSE);
}
#ifdef __STDC__
void address_remove(Tool w, Address_Book *address_book, XtPointer xp)
#else
void address_remove(w,address_book,xp)
Tool w;
Address_Book *address_book;
XtPointer xp;
#endif
{
Address_Book_Info *info = address_book->current;
if(! info)
return;
if(preferences.confirmDestroy == TRUE)
if((ml_confirm(address_book->shell,
MLGetLocalized(XtNmsgDestroyAddress,
MsgDestroyAddress),
CONFIRM_OK_CANCEL)) == FALSE)
return;
if(info->prev)
info->prev->next = info->next;
if(info->next)
info->next->prev = info->prev;
else
session->addresses = info->prev;
if(address_book->current == info)
address_book->current = NULL;
free_address_book_info(info);
push_cursor(WATCH_CURSOR);
save_defaults();
address_reset(w,address_book, NULL);
pop_cursor();
return;
}
#ifdef __STDC__
void address_add(Tool w, Address_Book *address_book, XtPointer xp)
#else
void address_add(w,address_book,xp)
Tool w;
Address_Book *address_book;
XtPointer xp;
#endif
{
Address_Book_Info *info;
Address_Book_Info *curr;
info = new_address_book_info();
info->name = GetUnTextField(address_book->name);
if((info->name == NULL) || (*info->name == NUL_TERM)) {
free_address_book_info(info);
return;
}
for(curr = session->addresses; curr; curr = curr->prev) {
if(ml_strcoll(curr->name,info->name) == STRMATCH) {
free_address_book_info(info);
return;
}
}
push_cursor(WATCH_CURSOR);
info->address = GetUnTextField(address_book->address);
info->groups = GetUnTextField(address_book->groups);
info->comment = GetUnTextField(address_book->comment);
info->next = NULL;
info->prev = session->addresses;
if(info->prev)
info->prev->next = info;
session->addresses = info;
address_sort(address_book);
save_defaults();
address_reset(w,address_book, NULL);
pop_cursor();
return;
}
#ifdef __STDC__
void address_modify(Tool w, Address_Book *address_book, XtPointer xp)
#else
void address_modify(w,address_book,xp)
Tool w;
Address_Book *address_book;
XtPointer xp;
#endif
{
Address_Book_Info *info;
unsigned char *name = GetUnTextField(address_book->name);
info = address_book->current;
if((! info) || (*name == NUL_TERM))
return;
push_cursor(WATCH_CURSOR);
if(info->name)
fs_give((void **) &info->name);
info->name = name;
if(info->address)
fs_give((void **) &info->address);
info->address = GetUnTextField(address_book->address);
if(info->groups)
fs_give((void **) &info->groups);
info->groups = GetUnTextField(address_book->groups);
if(info->comment)
fs_give((void **) &info->comment);
info->comment = GetUnTextField(address_book->comment);
address_sort(address_book);
save_defaults();
address_reset(w,address_book, NULL);
pop_cursor();
return;
}
#ifdef __STDC__
void address_reset(Tool w, Address_Book *address_book, XtPointer xp)
#else
void address_reset(w,address_book,xp)
Tool w;
Address_Book *address_book;
XtPointer xp;
#endif
{
if(address_book == NULL)
return;
XmListDeleteAllItems(address_book->search_list);
XmListDeselectAllItems(address_book->search_list);
XmListDeselectAllItems(address_book->list);
XmListDeleteAllItems(address_book->list);
address_book->button_state |= BTN_NOSELECTION;
address_book->button_state &= ~BTN_SELECTION;
address_book_context_switch(address_book,address_book->current, NULL);
stuff_address_book(address_book);
check_buttons(address_book_menu, XtNumber(address_book_menu),
NULL, address_book->button_state);
return;
}
#ifdef __STDC__
int address_compare(const void *adr1, const void *adr2)
#else
int address_compare(adr1,adr2)
const void *adr1;
const void *adr2;
#endif
{
Address_Book_Info **a1 = (Address_Book_Info **) adr1;
Address_Book_Info **a2 = (Address_Book_Info **) adr2;
return(ml_strcoll((*(a1))->name,(*(a2))->name));
}
#ifdef __STDC__
void address_sort(Address_Book *address_book)
#else
void address_sort(address_book)
Address_Book *address_book;
#endif
{
Address_Book_Info **sort;
Address_Book_Info *info;
int n = 0;
int total = 0;
if(session->addresses == NULL)
return;
for(info = session->addresses; info; info = info->prev)
total ++;
if(total < 2)
return;
sort = (Address_Book_Info **) fs_get(total * sizeof(Address_Book_Info *));
for(info = session->addresses; info; info = info->prev) {
sort[n] = info;
n ++;
}
qsort((char *) sort,total,sizeof(Address_Book_Info **),address_compare);
for(n = 0; n < total; n ++) {
info = sort[n];
if(n == 0) {
session->addresses = info;
info->next = NULL;
info->prev = sort[n + 1];
}
else {
info->next = sort[n - 1];
if(n == (total - 1))
info->prev = NULL;
else
info->prev = sort[n + 1];
}
}
fs_give((void **) &sort);
return;
}
#ifdef __STDC__
void address_help(Tool w, Address_Book *address_book, XtPointer xp)
#else
void address_help(w,address_book,xp)
Tool w;
Address_Book *address_book;
XtPointer xp;
#endif
{
help(address_book->shell, ADDRESSBOOKHELPFILE);
return;
}
#ifdef __STDC__
ADDRESS *text_to_address(char *text,char *host)
#else
ADDRESS *text_to_address(text,host)
char *text;
char *host;
#endif
{
ADDRESS *address = NULL;
if(host == NULL)
host = EMPTYSTR;
if((text != NULL) && (*text != NUL_TERM))
rfc822_parse_adrlist(&address,text,host);
return(address);
}
#ifdef __STDC__
ADDRESS *copy_address(ADDRESS *src_address)
#else
ADDRESS *copy_address(src_address)
ADDRESS *src_address;
#endif
{
ADDRESS *new_address = (ADDRESS*) NULL;
new_address = mail_newaddr();
if ((new_address != NULL) && (src_address != NULL)) {
new_address->personal =
((src_address->personal) ? cpystr(src_address->personal) : NULL);
new_address->adl =
((src_address->adl) ? cpystr(src_address->adl) : NULL);
new_address->mailbox =
((src_address->mailbox) ? cpystr(src_address->mailbox) : NULL);
new_address->host =
((src_address->host) ? cpystr(src_address->host) : NULL );
new_address->error =
((src_address->error) ? cpystr(src_address->error) : NULL);
if (src_address->next)
new_address->next = copy_address( src_address->next );
}
return(new_address);
}
#ifdef __STDC__
void local_make_addr_str(ADDRESS *adr, char *obuf)
#else
void local_make_addr_str(adr, obuf)
ADDRESS *adr;
char *obuf;
#endif
{
if ((!adr) || (adr->mailbox == NULL)) {
sprintf(obuf, SPACESTR);
return;
}
if ((adr->personal != NULL) && (adr->host != NULL))
sprintf(obuf, "\"%s\" <%s@%s>", adr->personal, adr->mailbox, adr->host);
else {
if(adr->host != NULL)
sprintf(obuf, "%s@%s", adr->mailbox, adr->host);
else
sprintf(obuf,"%s",adr->mailbox);
}
return;
}
#ifdef __STDC__
int save_address_book(FILE *fp)
#else
int save_address_book(fp)
FILE *fp;
#endif
{
Address_Book_Info *info;
if(session->addresses == NULL)
return(0);
fprintf(fp,"\n%s\n",BEGIN_ADDRESS_STR);
for(info = session->addresses; info ; info = info->prev) {
fprintf(fp,"*%s\n",(info->name != NULL)
? (char *) info->name
: EMPTYSTR);
fprintf(fp,"%s\n",(info->address != NULL)
? (char *) info->address
: EMPTYSTR);
fprintf(fp,"%s\n",(info->groups != NULL)
? (char *) info->groups
: EMPTYSTR);
fprintf(fp,"%s\n",(info->comment != NULL)
? (char *) info->comment
: EMPTYSTR);
}
fprintf(fp,"%s\n",END_ADDRESS_STR);
return(0);
}
#ifdef __STDC__
int load_address_book(FILE *fp)
#else
int load_address_book(fp)
FILE *fp;
#endif
{
char buffer[FILEBUFFLEN];
Boolean new_style = FALSE;
Address_Book_Info *info;
char *ptr;
while((fgets(buffer,sizeof(buffer),fp)) != NULL) {
buffer[strlen(buffer)-1] = '\0';
if((strcmp(buffer,END_ADDRESS_STR)) == STRMATCH)
return(0);
info = new_address_book_info();
ptr = buffer;
if(*ptr == '*') {
ptr ++;
new_style = TRUE;
}
info->name = (unsigned char *) cpystr(ptr);
if(fgets(buffer,sizeof(buffer),fp)) {
buffer[strlen(buffer)-1] = '\0';
info->address = (unsigned char *) cpystr(buffer);
}
else
info->address = (unsigned char *) cpystr(EMPTYSTR);
if(new_style == TRUE) {
if(fgets(buffer,sizeof(buffer),fp)) {
buffer[strlen(buffer)-1] = '\0';
info->groups = (unsigned char *) cpystr(buffer);
}
else
info->groups = (unsigned char *) cpystr(EMPTYSTR);
}
if(fgets(buffer,sizeof(buffer),fp)) {
buffer[strlen(buffer)-1] = '\0';
info->comment = (unsigned char *) cpystr(buffer);
}
else
info->comment = (unsigned char *) cpystr(EMPTYSTR);
if(session->addresses == NULL)
session->addresses = info;
else {
info->prev = session->addresses;
session->addresses->next = info;
session->addresses = info;
}
}
return(0);
}
#ifdef __STDC__
void addresses_pop(Widget w, XtPointer xp)
#else
void addresses_pop(w,xp)
Widget w;
XtPointer xp;
#endif
{
address_close_window(w,session->address_book,NULL);
return;
}
syntax highlighted by Code2HTML, v. 0.9.1