\fBshow_cursor\fP=[true|false]
Defines if the cursor is visible in main display. Default is false.
+.TP
+\fBuse_mouse\fP=[true|false]
+Defines if navigation via the mouse is activated. Default is false.
+
.TP
\fBuse_colors\fP=[true|false]
Defines if the output of abook is colorized. Default is false.
static void
edit_field(int tab, char c, int item_number)
{
+ ui_enable_mouse(FALSE);
int i = 0, number, idx;
char *msg;
abook_field_list *f;
list_item item;
if((number = key_to_field_number(c)) < 0)
- return;
+ goto detachfield;
edit_undo(item_number, BACKUP_ITEM);
while(1) {
if(!f)
- return;
+ goto detachfield;
if(i == number)
break;
break;
case FIELD_DATE:
edit_date(item_number, idx);
- return;
+ goto detachfield;
default:
assert(0);
}
+
+ detachfield:
+ if(opt_get_bool(BOOL_USE_MOUSE))
+ ui_enable_mouse(TRUE);
}
static int
return item;
}
+ if(c == KEY_MOUSE) {
+ MEVENT event;
+ if(getmouse(&event) == OK) {
+ if(event.bstate & BUTTON1_CLICKED
+ || event.bstate & BUTTON1_DOUBLE_CLICKED) {
+ int window_y, window_x;
+ getbegyx(editw, window_y, window_x);
+ if(event.y == 0) {
+ /* if first row is selected, then go back to list */
+ return -1;
+ } else if(event.y == window_y + TABLINE
+ || event.y == window_y + TABLINE + 1) {
+ char* tab_name;
+ int mouse_x = event.x;
+ int xpos = 2 + 1; /* look at editor_tab() and try out */
+ int clicked_tab = 0;
+ while(clicked_tab < views_count) {
+ view_info(clicked_tab, &tab_name, NULL);
+ xpos += strwidth(tab_name) + 5;
+ /* fprintf(stderr, "trying tab %d\n", clicked_tab); */
+ if(xpos >= mouse_x) {
+ break; /* clicked tab was found */
+ } else {
+ /* try next tab */
+ clicked_tab++;
+ }
+ }
+ if(clicked_tab < views_count) {
+ tab = clicked_tab;
+ }
+ } else if(event.y >= window_y + FIELDS_START_Y) {
+ /* is mouse in field area? */
+ int j = 1 + event.y - window_y - FIELDS_START_Y;
+ /* field numbers start with 1, but if j='0', then char='0' */
+ /* so fix this, by adding 1 to j */
+ int field_char = (j < 10) ? '0' + j : 'A' + j - 10;
+ edit_field(tab, field_char, item);
+ }
+ } else if(event.bstate & BUTTON4_PRESSED) {
+ tab = tab == 0 ? views_count - 1 : tab - 1;
+ }
+ else if(event.bstate & BUTTON5_PRESSED) {
+ tab = tab == views_count - 1 ? 0 : tab + 1;
+ }
+ return item;
+ }
+ }
/* No uppercase nor numeric key should be used in this menu,
* as they are reserved for field selection */
return curitem;
}
+int
+list_get_firstitem()
+{
+ return first_list_item;
+}
+
void
list_set_curitem(int i)
{
void invert_selection();
int list_is_empty();
int list_get_curitem();
+int list_get_firstitem();
void list_set_curitem(int i);
int duplicate_item();
{ "preserve_fields", OT_STR, STR_PRESERVE_FIELDS, UL "standard" },
{ "sort_field", OT_STR, STR_SORT_FIELD, UL "nick" },
{ "show_cursor", OT_BOOL, BOOL_SHOW_CURSOR, FALSE },
+ { "use_mouse", OT_BOOL, BOOL_USE_MOUSE, FALSE },
{ "use_colors", OT_BOOL, BOOL_USE_COLORS, FALSE },
{ "color_header_fg", OT_STR, STR_COLOR_HEADER_FG, UL "blue" },
{ "color_header_fg", OT_STR, STR_COLOR_HEADER_FG, UL "blue" },
BOOL_ADD_EMAIL_PREVENT_DUPLICATES,
BOOL_SHOW_CURSOR,
BOOL_USE_COLORS,
+ BOOL_USE_MOUSE,
BOOL_MAX
};
#include "filter.h"
#include "xmalloc.h"
#include "color.h"
+#include <sys/time.h>
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
static bool should_resize = FALSE;
static bool can_resize = FALSE;
+static struct timeval last_click_time;
+static int double_click_interval = 200; /* maximum time in milliseconds */
static WINDOW *top = NULL, *bottom = NULL;
noecho();
nonl();
intrflush(stdscr, FALSE);
+ if(opt_get_bool(BOOL_USE_MOUSE)) {
+ mouseinterval(0);
+ timerclear(&last_click_time);
+ ui_enable_mouse(TRUE);
+ }
keypad(stdscr, TRUE);
if(opt_get_bool(BOOL_USE_COLORS)) {
start_color();
}
}
+void
+ui_enable_mouse(bool enabled)
+{
+ mmask_t mask;
+ if(enabled) {
+ mask = BUTTON1_CLICKED | BUTTON4_PRESSED;
+#if NCURSES_MOUSE_VERSION == 2
+ mask |= BUTTON5_PRESSED;
+#endif
+ } else {
+ mask = 0;
+ }
+ mousemask(mask, NULL);
+}
+
+/** Check the time elapsed since last click and tell if it should be
+ * interpreted as a double click
+ */
+static bool
+was_double_click() {
+ struct timeval click_time, click_diff, maxdiff;
+ maxdiff.tv_sec = double_click_interval / 1000;
+ maxdiff.tv_usec = (double_click_interval % 1000)*1000;
+ gettimeofday(&click_time, NULL);
+
+ timersub(&click_time, &last_click_time, &click_diff);
+ last_click_time = click_time;
+ return !timercmp(&click_diff, &maxdiff, >);
+}
#define CHECK_COLOR_NAME(value, name, DEFNAME) \
if(!strcmp((name), (value))){ \
if(!opt_get_bool(BOOL_SHOW_CURSOR))
show_cursor();
can_resize = FALSE; /* it's not safe to resize anymore */
+ if(ch == KEY_MOUSE) {
+ MEVENT event;
+ bool double_clicked = was_double_click();
+ if(getmouse(&event) == OK) {
+ if(event.bstate & BUTTON1_CLICKED
+ || event.bstate & BUTTON1_DOUBLE_CLICKED) {
+ if(event.y == 0) {
+ return;
+ }
+ list_set_curitem(event.y + list_get_firstitem() - LIST_TOP);
+ if(double_clicked) {
+ edit_item(-1);
+ } else {
+ refresh_list();
+ }
+ } else if(event.bstate & BUTTON4_PRESSED) {
+ scroll_up();
+ } else if(event.bstate & BUTTON5_PRESSED) {
+ scroll_down();
+ }
+ }
+ }
switch(ch) {
case 'q': return;
case 'Q': quit_abook(QUIT_DONTSAVE); break;
int is_ui_initialized();
void ui_init_curses();
void ui_init_color_pairs_user();
+void ui_enable_mouse(bool enabled);
int init_ui();
void close_ui();
void headerline(const char *str);
void ui_print_database();
void ui_open_datafile();
+#if NCURSES_MOUSE_VERSION != 2
+#define BUTTON5_PRESSED (0x80 | 0x8000000)
+#endif
#include "options.h" /* needed for options_get_bool */