diff --git a/.travis.yml b/.travis.yml index 5c7435fb..3e1b576a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,11 @@ +dist: trusty +sudo: required language: c install: - lsb_release -a - uname -a - sudo apt-get update - - sudo apt-get -y install libssl-dev libexpat1-dev libncursesw5-dev libglib2.0-dev libnotify-dev libcurl3-dev libxss-dev libotr2-dev libgpgme11-dev autoconf-archive expect-dev tcl-dev libtool python-dev + - sudo apt-get -y install libssl-dev libexpat1-dev libncursesw5-dev libglib2.0-dev libnotify-dev libcurl3-dev libxss-dev libotr5-dev libgpgme11-dev autoconf-archive expect-dev tcl-dev libtool python-dev libgtk2.0-dev - git clone git://github.com/boothj5/libmesode.git - cd libmesode - mkdir m4 diff --git a/configure.ac b/configure.ac index 46e7c775..651805cd 100644 --- a/configure.ac +++ b/configure.ac @@ -159,8 +159,8 @@ AS_IF([test "x$ncurses_cv_wget_wch" != xyes], [AC_MSG_ERROR([ncurses does not support wide characters])]) ### Check for other profanity dependencies -PKG_CHECK_MODULES([glib], [glib-2.0 >= 2.26], [], - [AC_MSG_ERROR([glib 2.26 or higher is required for profanity])]) +PKG_CHECK_MODULES([glib], [glib-2.0 >= 2.40], [], + [AC_MSG_ERROR([glib 2.40 or higher is required for profanity])]) PKG_CHECK_MODULES([curl], [libcurl], [], [AC_CHECK_LIB([curl], [main], [], [AC_MSG_ERROR([libcurl is required for profanity])])]) diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c index 6b5eb701..312c4b74 100644 --- a/src/command/cmd_defs.c +++ b/src/command/cmd_defs.c @@ -576,7 +576,7 @@ static struct cmd_t command_defs[] = CMD_SYN( "/leave") CMD_DESC( - "Leave the current chat room.") + "Leave the current chat or room.") CMD_NOARGS CMD_NOEXAMPLES }, diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index 810c2e18..d70d435d 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -4756,24 +4756,14 @@ cmd_clear(ProfWin *window, const char *const command, gchar **args) gboolean cmd_leave(ProfWin *window, const char *const command, gchar **args) { - jabber_conn_status_t conn_status = connection_get_status(); - int index = wins_get_current_num(); - - if (window->type != WIN_MUC) { - cons_show("You can only use the /leave command in a chat room."); + if (window->type != WIN_MUC && window->type != WIN_CHAT && window->type != WIN_PRIVATE) { + cons_show("The /leave command is only valid in chat, or chat room windows."); cons_alert(); return TRUE; } - // handle leaving rooms, or chat - if (conn_status == JABBER_CONNECTED) { - ui_close_connected_win(index); - } - - // close the window - ui_close_win(index); - - return TRUE; + // use /close behaviour + return cmd_close(window, "/leave", args); } gboolean diff --git a/src/common.c b/src/common.c index 898f62fa..d9c7d73f 100644 --- a/src/common.c +++ b/src/common.c @@ -67,54 +67,6 @@ static unsigned long unique_id = 0; static size_t _data_callback(void *ptr, size_t size, size_t nmemb, void *data); -// taken from glib 2.30.3 -gchar* -p_utf8_substring(const gchar *str, glong start_pos, glong end_pos) -{ - gchar *start, *end, *out; - - start = g_utf8_offset_to_pointer (str, start_pos); - end = g_utf8_offset_to_pointer (start, end_pos - start_pos); - - out = g_malloc (end - start + 1); - memcpy (out, start, end - start); - out[end - start] = 0; - - return out; -} - -void -p_slist_free_full(GSList *items, GDestroyNotify free_func) -{ - g_slist_foreach (items, (GFunc) free_func, NULL); - g_slist_free (items); -} - -void -p_list_free_full(GList *items, GDestroyNotify free_func) -{ - g_list_foreach (items, (GFunc) free_func, NULL); - g_list_free (items); -} - -gboolean -p_hash_table_add(GHashTable *hash_table, gpointer key) -{ - // doesn't handle when key exists, but value == NULL - gpointer found = g_hash_table_lookup(hash_table, key); - g_hash_table_replace(hash_table, key, key); - - return (found == NULL); -} - -gboolean -p_hash_table_contains(GHashTable *hash_table, gconstpointer key) -{ - // doesn't handle when key exists, but value == NULL - gpointer found = g_hash_table_lookup(hash_table, key); - return (found != NULL); -} - gboolean create_dir(char *name) { diff --git a/src/common.h b/src/common.h index 8c42ae52..421c56cd 100644 --- a/src/common.h +++ b/src/common.h @@ -40,20 +40,6 @@ #include -#if !GLIB_CHECK_VERSION(2,28,0) -#define g_slist_free_full(items, free_func) p_slist_free_full(items, free_func) -#define g_list_free_full(items, free_func) p_list_free_full(items, free_func) -#endif - -#if !GLIB_CHECK_VERSION(2,30,0) -#define g_utf8_substring(str, start_pos, end_pos) p_utf8_substring(str, start_pos, end_pos) -#endif - -#if !GLIB_CHECK_VERSION(2,32,0) -#define g_hash_table_add(hash_table, key) p_hash_table_add(hash_table, key) -#define g_hash_table_contains(hash_table, key) p_hash_table_contains(hash_table, key) -#endif - #ifndef NOTIFY_CHECK_VERSION #define notify_notification_new(summary, body, icon) notify_notification_new(summary, body, icon, NULL) #endif @@ -94,12 +80,6 @@ typedef enum { RESOURCE_XA } resource_presence_t; -gchar* p_utf8_substring(const gchar *str, glong start_pos, glong end_pos); -void p_slist_free_full(GSList *items, GDestroyNotify free_func); -void p_list_free_full(GList *items, GDestroyNotify free_func); -gboolean p_hash_table_add(GHashTable *hash_table, gpointer key); -gboolean p_hash_table_contains(GHashTable *hash_table, gconstpointer key); - gboolean create_dir(char *name); gboolean mkdir_recursive(const char *dir); gboolean copy_file(const char *const src, const char *const target); diff --git a/src/config/theme.c b/src/config/theme.c index 2d418f73..5a44e370 100644 --- a/src/config/theme.c +++ b/src/config/theme.c @@ -104,6 +104,7 @@ theme_init(const char *const theme_name) g_hash_table_insert(defaults, strdup("statusbar.brackets"), strdup("cyan")); g_hash_table_insert(defaults, strdup("statusbar.active"), strdup("cyan")); g_hash_table_insert(defaults, strdup("statusbar.new"), strdup("white")); + g_hash_table_insert(defaults, strdup("statusbar.time"), strdup("white")); g_hash_table_insert(defaults, strdup("me"), strdup("yellow")); g_hash_table_insert(defaults, strdup("them"), strdup("green")); g_hash_table_insert(defaults, strdup("receipt.sent"), strdup("red")); @@ -755,6 +756,7 @@ theme_attrs(theme_item_t attrs) case THEME_STATUS_BRACKET: _theme_prep_fgnd("statusbar.brackets", lookup_str, &bold); break; case THEME_STATUS_ACTIVE: _theme_prep_fgnd("statusbar.active", lookup_str, &bold); break; case THEME_STATUS_NEW: _theme_prep_fgnd("statusbar.new", lookup_str, &bold); break; + case THEME_STATUS_TIME: _theme_prep_fgnd("statusbar.time", lookup_str, &bold); break; case THEME_ME: _theme_prep_fgnd("me", lookup_str, &bold); break; case THEME_THEM: _theme_prep_fgnd("them", lookup_str, &bold); break; case THEME_RECEIPT_SENT: _theme_prep_fgnd("receipt.sent", lookup_str, &bold); break; @@ -843,6 +845,7 @@ theme_attrs(theme_item_t attrs) case THEME_STATUS_BRACKET: case THEME_STATUS_ACTIVE: case THEME_STATUS_NEW: + case THEME_STATUS_TIME: _theme_prep_bgnd("statusbar", "blue", lookup_str); break; default: diff --git a/src/config/theme.h b/src/config/theme.h index 6e9d13eb..747eace1 100644 --- a/src/config/theme.h +++ b/src/config/theme.h @@ -69,6 +69,7 @@ typedef enum { THEME_STATUS_BRACKET, THEME_STATUS_ACTIVE, THEME_STATUS_NEW, + THEME_STATUS_TIME, THEME_ME, THEME_THEM, THEME_ROOMINFO, diff --git a/src/tools/autocomplete.c b/src/tools/autocomplete.c index b3c49610..b94db481 100644 --- a/src/tools/autocomplete.c +++ b/src/tools/autocomplete.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "common.h" #include "tools/autocomplete.h" @@ -330,10 +331,17 @@ autocomplete_param_no_with_func(const char *const input, char *command, int arg_ static gchar* _search_from(Autocomplete ac, GSList *curr, gboolean quote) { + gchar *search_str_ascii = g_str_to_ascii(ac->search_str, NULL); + gchar *search_str_lower = g_ascii_strdown(search_str_ascii, -1); + g_free(search_str_ascii); + while(curr) { + gchar *curr_ascii = g_str_to_ascii(curr->data, NULL); + gchar *curr_lower = g_ascii_strdown(curr_ascii, -1); + g_free(curr_ascii); // match found - if (strncmp(curr->data, ac->search_str, strlen(ac->search_str)) == 0) { + if (strncmp(curr_lower, search_str_lower, strlen(search_str_lower)) == 0) { // set pointer to last found ac->last_found = curr; @@ -347,16 +355,22 @@ _search_from(Autocomplete ac, GSList *curr, gboolean quote) gchar *result = quoted->str; g_string_free(quoted, FALSE); + g_free(search_str_lower); + g_free(curr_lower); return result; // otherwise just return the string } else { + g_free(search_str_lower); + g_free(curr_lower); return strdup(curr->data); } } + g_free(curr_lower); curr = g_slist_next(curr); } + g_free(search_str_lower); return NULL; } diff --git a/src/ui/console.c b/src/ui/console.c index 64f44c52..4c24b450 100644 --- a/src/ui/console.c +++ b/src/ui/console.c @@ -2224,6 +2224,7 @@ cons_theme_properties(void) _cons_theme_bar_prop(THEME_STATUS_BRACKET, "statusbar.brackets"); _cons_theme_bar_prop(THEME_STATUS_ACTIVE, "statusbar.active"); _cons_theme_bar_prop(THEME_STATUS_NEW, "statusbar.new"); + _cons_theme_bar_prop(THEME_STATUS_TIME, "statusbar.time"); _cons_theme_prop(THEME_TIME, "main.time"); _cons_theme_prop(THEME_TEXT, "main.text"); diff --git a/src/ui/statusbar.c b/src/ui/statusbar.c index d19b5618..7998d7b4 100644 --- a/src/ui/statusbar.c +++ b/src/ui/statusbar.c @@ -459,6 +459,7 @@ _status_bar_draw(void) last_time = g_date_time_new_now(tz); int bracket_attrs = theme_attrs(THEME_STATUS_BRACKET); + int time_attrs = theme_attrs(THEME_STATUS_TIME); char *time_pref = prefs_get_string(PREF_TIME_STATUSBAR); if (g_strcmp0(time_pref, "off") != 0) { @@ -468,7 +469,9 @@ _status_bar_draw(void) wattron(status_bar, bracket_attrs); mvwaddch(status_bar, 0, 1, '['); wattroff(status_bar, bracket_attrs); + wattron(status_bar, time_attrs); mvwprintw(status_bar, 0, 2, date_fmt); + wattroff(status_bar, time_attrs); wattron(status_bar, bracket_attrs); mvwaddch(status_bar, 0, 2 + len, ']'); wattroff(status_bar, bracket_attrs); diff --git a/tests/unittests/test_autocomplete.c b/tests/unittests/test_autocomplete.c index 2fd68b51..755e01c9 100644 --- a/tests/unittests/test_autocomplete.c +++ b/tests/unittests/test_autocomplete.c @@ -117,3 +117,67 @@ void add_two_same_updates(void **state) autocomplete_clear(ac); g_slist_free_full(result, g_free); } + +void complete_accented_with_accented(void **state) +{ + Autocomplete ac = autocomplete_new(); + autocomplete_add(ac, "èâîô"); + + char *result = autocomplete_complete(ac, "èâ", TRUE); + + assert_string_equal("èâîô", result); + + autocomplete_clear(ac); +} + +void complete_accented_with_base(void **state) +{ + Autocomplete ac = autocomplete_new(); + autocomplete_add(ac, "èâîô"); + + char *result = autocomplete_complete(ac, "ea", TRUE); + + assert_string_equal("èâîô", result); + + autocomplete_clear(ac); +} + +void complete_both_with_accented(void **state) +{ + Autocomplete ac = autocomplete_new(); + autocomplete_add(ac, "eaooooo"); + autocomplete_add(ac, "èâîô"); + + char *result1 = autocomplete_complete(ac, "èâ", TRUE); + char *result2 = autocomplete_complete(ac, result1, TRUE); + + assert_string_equal("èâîô", result2); + + autocomplete_clear(ac); +} + +void complete_both_with_base(void **state) +{ + Autocomplete ac = autocomplete_new(); + autocomplete_add(ac, "eaooooo"); + autocomplete_add(ac, "èâîô"); + + char *result1 = autocomplete_complete(ac, "ea", TRUE); + char *result2 = autocomplete_complete(ac, result1, TRUE); + + assert_string_equal("èâîô", result2); + + autocomplete_clear(ac); +} + +void complete_ignores_case(void **state) +{ + Autocomplete ac = autocomplete_new(); + autocomplete_add(ac, "MyBuddy"); + + char *result = autocomplete_complete(ac, "myb", TRUE); + + assert_string_equal("MyBuddy", result); + + autocomplete_clear(ac); +} diff --git a/tests/unittests/test_autocomplete.h b/tests/unittests/test_autocomplete.h index 4ad327c0..a9dd34cb 100644 --- a/tests/unittests/test_autocomplete.h +++ b/tests/unittests/test_autocomplete.h @@ -8,3 +8,8 @@ void add_two_and_complete_returns_second(void **state); void add_two_adds_two(void **state); void add_two_same_adds_one(void **state); void add_two_same_updates(void **state); +void complete_accented_with_accented(void **state); +void complete_accented_with_base(void **state); +void complete_both_with_accented(void **state); +void complete_both_with_base(void **state); +void complete_ignores_case(void **state); diff --git a/tests/unittests/unittests.c b/tests/unittests/unittests.c index 71bdf1b1..5c411ab6 100644 --- a/tests/unittests/unittests.c +++ b/tests/unittests/unittests.c @@ -90,6 +90,11 @@ int main(int argc, char* argv[]) { unit_test(add_two_adds_two), unit_test(add_two_same_adds_one), unit_test(add_two_same_updates), + unit_test(complete_accented_with_accented), + unit_test(complete_accented_with_base), + unit_test(complete_both_with_accented), + unit_test(complete_both_with_base), + unit_test(complete_ignores_case), unit_test(create_jid_from_null_returns_null), unit_test(create_jid_from_empty_string_returns_null),