/* elmo - ELectronic Mail Operator Copyright (C) 2003 rzyjontko 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 the Free Software Foundation; version 2. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ---------------------------------------------------------------------- mail box selection */ /**************************************************************************** * IMPLEMENTATION HEADERS ****************************************************************************/ #include #include #include #include #include #include "select.h" #include "rstring.h" #include "xmalloc.h" #include "gettext.h" #include "ask.h" #include "cmd.h" #include "folder.h" #include "mybox.h" #include "error.h" #include "hook.h" #include "exec.h" #include "box_selection.h" #include "file.h" #include "wrapbox.h" #include "color.h" #include "label.h" #include "interface.h" #include "str.h" #include "eprintf.h" #include "frames.h" #include "search.h" /**************************************************************************** * IMPLEMENTATION PRIVATE DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS ****************************************************************************/ #define PREAMBLE do { if (box_select == NULL) return; } while (0) /**************************************************************************** * IMPLEMENTATION PRIVATE CLASS PROTOTYPES / EXTERNAL CLASS REFERENCES ****************************************************************************/ /**************************************************************************** * IMPLEMENTATION PRIVATE STRUCTURES / UTILITY CLASSES ****************************************************************************/ /**************************************************************************** * IMPLEMENTATION REQUIRED EXTERNAL REFERENCES (AVOID) ****************************************************************************/ /**************************************************************************** * IMPLEMENTATION PRIVATE DATA ****************************************************************************/ /* This holds an array of directory names. */ static rstring_t *true_items = NULL; /* Box selection window consists of select_t object and an optional label. */ static elabel_t *label = NULL; static select_t *box_select = NULL; /* Colors used in box_selection window. */ static chtype text_color; static chtype tree_color; static chtype tree_bar_color; static chtype root_color; static chtype hilight_color; /* This string is used to eprintf the box information. */ static str_t *str_line = NULL; /* This string is a format to the eprintf_box function, and controls how are boxes displayed. */ static char *box_fmt = " %010n (%u/%t)"; /**************************************************************************** * INTERFACE DATA ****************************************************************************/ /**************************************************************************** * IMPLEMENTATION PRIVATE FUNCTION PROTOTYPES ****************************************************************************/ /**************************************************************************** * IMPLEMENTATION PRIVATE FUNCTIONS ****************************************************************************/ static void goto_this_box (const char *path) { int i; const char *short_path = strrchr (path, '/'); if (short_path == NULL) short_path = path; else short_path++; for (i = 0; i < true_items->count; i++){ if (strcmp (short_path, true_items->array[i]) == 0) break; } if (i < true_items->count) select_goto (box_select, i + 1); } static void draw_top (WINDOW *win, int maxlen) { if (win == box_select->win){ wattrset (win, root_color); } else { wattrset (win, select_bar_color ()); } maxlen -= window_addnstr (win, mybox_dir, maxlen); while (maxlen-- > 0) window_addch (win, ' '); } static void draw_tree (WINDOW *win, int last) { if (win == box_select->win){ wattrset (win, text_color); window_addch (win, ' '); wattrset (win, tree_color); } else { wattrset (win, select_bar_color ()); window_addch (win, ' '); wattrset (win, tree_bar_color); } if (last) window_addch (win, frames_ch (ACS_LLCORNER)); else window_addch (win, frames_ch (ACS_LTEE)); window_addch (win, frames_ch (ACS_HLINE)); } static void set_hilight_color (WINDOW *win) { if (win == box_select->win) wattrset (win, hilight_color); else wattrset (win, select_hilight_color ()); } static void unset_hilight_color (WINDOW *win) { if (win == box_select->win) wattrset (win, text_color); else wattrset (win, select_bar_color ()); } static int add_string (WINDOW *win, char *str, int maxlen, search_t *search) { int pos = -1; int len = 1; if (maxlen <= 0) return 0; if (search) pos = search_perform (search, str); if (pos != -1){ len = search->pattern->len; pos -= len - 1; if (pos < 0) pos = 0; window_addnstr (win, str, pos); set_hilight_color (win); window_addnstr (win, str + pos, len); unset_hilight_color (win); maxlen -= pos + len; } return pos + len + window_addnstr (win, str + pos + len, maxlen - 1); } static void draw_item (WINDOW *win, int maxlen, char *str, search_t *search) { if (str_line == NULL) str_line = str_create (); if (win == box_select->win) wattrset (win, text_color); else wattrset (win, select_bar_color ()); str_clear (str_line); if (str) eprintf_box_str (box_fmt, str, str_line); maxlen -= add_string (win, str_line->str, maxlen, search); while (maxlen-- > 0) window_addch (win, ' '); } static void draw_line (WINDOW *win, int maxlen, int index, search_t *search) { char *box = NULL; if (index == 0){ draw_top (win, maxlen); return; } if (index <= true_items->count){ box = true_items->array[index - 1]; draw_tree (win, index == true_items->count); } draw_item (win, maxlen, box, search); } static int match_box (search_t *search, int index) { char *box; char *seek; if (index <= 0 || index > true_items->count) return 0; box = true_items->array[index - 1]; seek = strrchr (box, '/'); if (seek == NULL) seek = box; else seek++; return search_perform (search, seek) != -1; } static int count (select_t *nothing) { if (true_items) return true_items->count + 1; return 0; } /* This file is generated by interface.pl script from interface.desc, and inc.in. */ static WINDOW *interface_init (void); #include "box_selection.inc" /**************************************************************************** * DISPLAY FUNCTIONS ****************************************************************************/ void box_selection_init (void) { WINDOW *window; true_items = mybox_subdirs (); if (true_items == NULL) return; window = interface_init (); box_select = select_open (window, 0, draw_line, count); window_set_functions (window, box_selection_refresh, box_selection_redraw, box_selection_set_focus, box_selection_unset_focus); window_show (window); if (box_select && wrapbox_marray){ goto_this_box (wrapbox_marray->path); } box_selection_redraw (); } void box_selection_free_resources (void) { if (box_select){ select_close (box_select); } box_select = NULL; if (true_items) rstring_delete (true_items); true_items = NULL; if (label) label_destroy (label); label = NULL; if (str_line) str_destroy (str_line); str_line = NULL; } void box_selection_redraw (void) { PREAMBLE; select_redraw (box_select); label_redraw (label); } void box_selection_refresh (void) { PREAMBLE; select_show (box_select); label_show (label); } void box_selection_set_focus (void) { PREAMBLE; label_set_focus (label); cmd_state_push (CMD_SELECT_BOX); box_selection_redraw (); } void box_selection_unset_focus (void) { PREAMBLE; label_unset_focus (label); label_redraw (label); cmd_state_pop (); } /**************************************************************************** * INTERFACE FUNCTIONS ****************************************************************************/ void box_selection_next (void) { PREAMBLE; select_next (box_select); } void box_selection_prev (void) { PREAMBLE; select_prev (box_select); } void box_selection_next_page (void) { PREAMBLE; select_next_page (box_select); } void box_selection_prev_page (void) { PREAMBLE; select_prev_page (box_select); } void box_selection_first (void) { PREAMBLE; select_first (box_select); } void box_selection_last (void) { PREAMBLE; select_last (box_select); } void box_selection_hit (void) { int index; char *newbox; PREAMBLE; if (box_select->bar_pos == 0) return; folder_at_leave (); index = box_select->bar_pos - 1; newbox = file_with_dir (mybox_dir, true_items->array[index]); mybox_switching_to (newbox); if (folder_read_box (newbox)){ mybox_switching_to (wrapbox_marray->path); box_selection_re_read (); } box_selection_redraw (); box_selection_refresh (); xfree (newbox); interface_focus (1); } void box_selection_re_read (void) { PREAMBLE; if (true_items) rstring_delete (true_items); true_items = mybox_subdirs (); if (true_items == NULL) return; } void box_selection_search_backward (void) { select_search_setup_backward (box_select, match_box); } void box_selection_search_forward (void) { select_search_setup_forward (box_select, match_box); } /**************************************************************************** * INTERFACE CLASS BODIES ****************************************************************************/ /**************************************************************************** * * END MODULE box_selection.c * ****************************************************************************/