about summary refs log tree commit diff stats
path: root/src/config
diff options
context:
space:
mode:
authorWill Song <incertia9474@gmail.com>2015-05-29 19:53:37 -0500
committerWill Song <incertia9474@gmail.com>2015-05-29 19:53:37 -0500
commit9463c6719036957c8468e1363a48afbfe751fd3e (patch)
treeaed6ccd050fc182a0d4d111bef6f743d28a42a73 /src/config
parent7f436d614b11d72893d856f1c3d817ab34b0b9eb (diff)
parent304e08a9c0bfa27ed84dc1ff0a2e2d32b36529f8 (diff)
downloadprofani-tty-9463c6719036957c8468e1363a48afbfe751fd3e.tar.gz
fix conflicts
Diffstat (limited to 'src/config')
-rw-r--r--src/config/account.c58
-rw-r--r--src/config/account.h5
-rw-r--r--src/config/accounts.c38
-rw-r--r--src/config/accounts.h2
-rw-r--r--src/config/preferences.c76
-rw-r--r--src/config/preferences.h7
-rw-r--r--src/config/theme.c172
-rw-r--r--src/config/theme.h3
8 files changed, 213 insertions, 148 deletions
diff --git a/src/config/account.c b/src/config/account.c
index 6df00382..857d049b 100644
--- a/src/config/account.c
+++ b/src/config/account.c
@@ -1,7 +1,7 @@
 /*
  * account.c
  *
- * Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com>
+ * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com>
  *
  * This file is part of Profanity.
  *
@@ -34,12 +34,14 @@
 
 #include <stdlib.h>
 #include <string.h>
+#include <assert.h>
 
 #include <glib.h>
 
 #include "jid.h"
 #include "config/account.h"
 #include "common.h"
+#include "log.h"
 
 ProfAccount*
 account_new(const gchar * const name, const gchar * const jid,
@@ -55,19 +57,19 @@ account_new(const gchar * const name, const gchar * const jid,
 
     new_account->name = strdup(name);
 
-    if (jid != NULL) {
+    if (jid) {
         new_account->jid = strdup(jid);
     } else {
         new_account->jid = strdup(name);
     }
 
-    if (password != NULL) {
+    if (password) {
         new_account->password = strdup(password);
     } else {
         new_account->password = NULL;
     }
 
-    if (eval_password != NULL) {
+    if (eval_password) {
         new_account->eval_password = strdup(eval_password);
     } else {
         new_account->eval_password = NULL;
@@ -75,13 +77,13 @@ account_new(const gchar * const name, const gchar * const jid,
 
     new_account->enabled = enabled;
 
-    if (server != NULL) {
+    if (server) {
         new_account->server = strdup(server);
     } else {
         new_account->server = NULL;
     }
 
-    if (resource != NULL) {
+    if (resource) {
         new_account->resource = strdup(resource);
     } else {
         new_account->resource = NULL;
@@ -132,7 +134,7 @@ account_new(const gchar * const name, const gchar * const jid,
         new_account->muc_nick = strdup(muc_nick);
     }
 
-    if (otr_policy != NULL) {
+    if (otr_policy) {
         new_account->otr_policy = strdup(otr_policy);
     } else {
         new_account->otr_policy = NULL;
@@ -148,17 +150,55 @@ account_new(const gchar * const name, const gchar * const jid,
 char *
 account_create_full_jid(ProfAccount *account)
 {
-    if (account->resource != NULL) {
+    if (account->resource) {
         return create_fulljid(account->jid, account->resource);
     } else {
         return strdup(account->jid);
     }
 }
 
+gboolean
+account_eval_password(ProfAccount *account)
+{
+    assert(account != NULL);
+    assert(account->eval_password != NULL);
+
+    // Evaluate as shell command to retrieve password
+    GString *cmd = g_string_new("");
+    g_string_append_printf(cmd, "%s 2>/dev/null", account->eval_password);
+
+    FILE *stream = popen(cmd->str, "r");
+    g_string_free(cmd, TRUE);
+    if (stream) {
+        // Limit to READ_BUF_SIZE bytes to prevent overflows in the case of a poorly chosen command
+        account->password = g_malloc(READ_BUF_SIZE);
+        if (!account->password) {
+            log_error("Failed to allocate enough memory to read eval_password output");
+            return FALSE;
+        }
+        account->password = fgets(account->password, READ_BUF_SIZE, stream);
+        pclose(stream);
+        if (!account->password) {
+            log_error("No result from eval_password.");
+            return FALSE;
+        }
+
+        // strip trailing newline
+        if (g_str_has_suffix(account->password, "\n")) {
+            account->password[strlen(account->password)-1] = '\0';
+        }
+    } else {
+        log_error("popen failed when running eval_password.");
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
 void
 account_free(ProfAccount *account)
 {
-    if (account != NULL) {
+    if (account) {
         free(account->name);
         free(account->jid);
         free(account->password);
diff --git a/src/config/account.h b/src/config/account.h
index ab43234d..218f8ce7 100644
--- a/src/config/account.h
+++ b/src/config/account.h
@@ -1,7 +1,7 @@
 /*
  * account.h
  *
- * Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com>
+ * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com>
  *
  * This file is part of Profanity.
  *
@@ -69,9 +69,8 @@ ProfAccount* account_new(const gchar * const name, const gchar * const jid,
     const gchar * const muc_service, const gchar * const muc_nick,
     const gchar * const otr_policy, GList *otr_manual, GList *otr_opportunistic,
     GList *otr_always);
-
 char* account_create_full_jid(ProfAccount *account);
-
+gboolean account_eval_password(ProfAccount *account);
 void account_free(ProfAccount *account);
 
 #endif
diff --git a/src/config/accounts.c b/src/config/accounts.c
index 4d4d47d0..d68f3a55 100644
--- a/src/config/accounts.c
+++ b/src/config/accounts.c
@@ -1,7 +1,7 @@
 /*
  * accounts.c
  *
- * Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com>
+ * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com>
  *
  * This file is part of Profanity.
  *
@@ -147,9 +147,9 @@ accounts_add(const char *account_name, const char *altdomain, const int port)
     const char *barejid = account_name;
     const char *resource = "profanity";
     Jid *jid = jid_create(account_name);
-    if (jid != NULL) {
+    if (jid) {
         barejid = jid->barejid;
-        if (jid->resourcepart != NULL) {
+        if (jid->resourcepart) {
             resource = jid->resourcepart;
         }
     }
@@ -159,7 +159,7 @@ accounts_add(const char *account_name, const char *altdomain, const int port)
         g_key_file_set_boolean(accounts, account_name, "enabled", TRUE);
         g_key_file_set_string(accounts, account_name, "jid", barejid);
         g_key_file_set_string(accounts, account_name, "resource", resource);
-        if (altdomain != NULL) {
+        if (altdomain) {
             g_key_file_set_string(accounts, account_name, "server", altdomain);
         }
         if (port != 0) {
@@ -252,7 +252,7 @@ accounts_get_account(const char * const name)
         gsize length;
         GList *otr_manual = NULL;
         gchar **manual = g_key_file_get_string_list(accounts, name, "otr.manual", &length, NULL);
-        if (manual != NULL) {
+        if (manual) {
             int i = 0;
             for (i = 0; i < length; i++) {
                 otr_manual = g_list_append(otr_manual, strdup(manual[i]));
@@ -262,7 +262,7 @@ accounts_get_account(const char * const name)
 
         GList *otr_opportunistic = NULL;
         gchar **opportunistic = g_key_file_get_string_list(accounts, name, "otr.opportunistic", &length, NULL);
-        if (opportunistic != NULL) {
+        if (opportunistic) {
             int i = 0;
             for (i = 0; i < length; i++) {
                 otr_opportunistic = g_list_append(otr_opportunistic, strdup(opportunistic[i]));
@@ -272,7 +272,7 @@ accounts_get_account(const char * const name)
 
         GList *otr_always = NULL;
         gchar **always = g_key_file_get_string_list(accounts, name, "otr.always", &length, NULL);
-        if (always != NULL) {
+        if (always) {
             int i = 0;
             for (i = 0; i < length; i++) {
                 otr_always = g_list_append(otr_always, strdup(always[i]));
@@ -356,7 +356,7 @@ accounts_rename(const char * const account_name, const char * const new_name)
     int i;
     for (i = 0; i < ARRAY_SIZE(string_keys); i++) {
         char *value = g_key_file_get_string(accounts, account_name, string_keys[i], NULL);
-        if (value != NULL) {
+        if (value) {
             g_key_file_set_string(accounts, new_name, string_keys[i], value);
             g_free(value);
         }
@@ -386,10 +386,10 @@ void
 accounts_set_jid(const char * const account_name, const char * const value)
 {
     Jid *jid = jid_create(value);
-    if (jid != NULL) {
+    if (jid) {
         if (accounts_account_exists(account_name)) {
             g_key_file_set_string(accounts, account_name, "jid", jid->barejid);
-            if (jid->resourcepart != NULL) {
+            if (jid->resourcepart) {
                 g_key_file_set_string(accounts, account_name, "resource", jid->resourcepart);
             }
 
@@ -509,7 +509,7 @@ accounts_add_otr_policy(const char * const account_name, const char * const cont
         GList *glist = NULL;
 
         // list found
-        if (list != NULL) {
+        if (list) {
             int i = 0;
             for (i = 0; i < length; i++) {
                 // item already in list, exit function
@@ -529,7 +529,7 @@ accounts_add_otr_policy(const char * const account_name, const char * const cont
             const gchar* new_list[g_list_length(glist)+1];
             GList *curr = glist;
             i = 0;
-            while (curr != NULL) {
+            while (curr) {
                 new_list[i++] = strdup(curr->data);
                 curr = g_list_next(curr);
             }
@@ -572,7 +572,7 @@ _remove_from_list(GKeyFile *accounts, const char * const account_name, const cha
     gsize length;
     gchar **list = g_key_file_get_string_list(accounts, account_name, key, &length, NULL);
 
-    if (list != NULL) {
+    if (list) {
         int i = 0;
         GList *glist = NULL;
         gboolean deleted = FALSE;
@@ -595,7 +595,7 @@ _remove_from_list(GKeyFile *accounts, const char * const account_name, const cha
                 const gchar* new_list[g_list_length(glist)+1];
                 GList *curr = glist;
                 i = 0;
-                while (curr != NULL) {
+                while (curr) {
                     new_list[i++] = strdup(curr->data);
                     curr = g_list_next(curr);
                 }
@@ -766,7 +766,7 @@ accounts_get_last_presence(const char * const account_name)
         result = RESOURCE_ONLINE;
     }
 
-    if (setting != NULL) {
+    if (setting) {
         g_free(setting);
     }
     return result;
@@ -796,7 +796,7 @@ accounts_get_login_presence(const char * const account_name)
         result = RESOURCE_ONLINE;
     }
 
-    if (setting != NULL) {
+    if (setting) {
         g_free(setting);
     }
     return result;
@@ -809,9 +809,9 @@ _fix_legacy_accounts(const char * const account_name)
     const char *barejid = account_name;
     const char *resource = "profanity";
     Jid *jid = jid_create(account_name);
-    if (jid != NULL) {
+    if (jid) {
         barejid = jid->barejid;
-        if (jid->resourcepart != NULL) {
+        if (jid->resourcepart) {
             resource = jid->resourcepart;
         }
     }
@@ -828,7 +828,7 @@ _fix_legacy_accounts(const char * const account_name)
         _save_accounts();
     }
 
-    // acounts with no muc service or nick
+    // accounts with no muc service or nick
     if (!g_key_file_has_key(accounts, account_name, "muc.service", NULL)) {
         gchar *account_jid = g_key_file_get_string(accounts, account_name, "jid", NULL);
         Jid *jidp = jid_create(account_jid);
diff --git a/src/config/accounts.h b/src/config/accounts.h
index cbbe88e6..50307b5b 100644
--- a/src/config/accounts.h
+++ b/src/config/accounts.h
@@ -1,7 +1,7 @@
 /*
  * accounts.h
  *
- * Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com>
+ * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com>
  *
  * This file is part of Profanity.
  *
diff --git a/src/config/preferences.c b/src/config/preferences.c
index 652d4ed9..c0d6f6e5 100644
--- a/src/config/preferences.c
+++ b/src/config/preferences.c
@@ -1,7 +1,7 @@
 /*
  * preferences.c
  *
- * Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com>
+ * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com>
  *
  * This file is part of Profanity.
  *
@@ -62,7 +62,7 @@
 #define PREF_GROUP_ALIAS "alias"
 #define PREF_GROUP_OTR "otr"
 
-#define INPBLOCK_DEFAULT 20
+#define INPBLOCK_DEFAULT 1000
 
 static gchar *prefs_loc;
 static GKeyFile *prefs;
@@ -95,35 +95,17 @@ prefs_load(void)
 
     err = NULL;
     log_maxsize = g_key_file_get_integer(prefs, PREF_GROUP_LOGGING, "maxsize", &err);
-    if (err != NULL) {
+    if (err) {
         log_maxsize = 0;
         g_error_free(err);
     }
 
-    // move pre 0.4.1 OTR preferences to [otr] group
+    // move pre 0.4.6 OTR warn preferences to [ui] group
     err = NULL;
-    gboolean ui_otr_warn = g_key_file_get_boolean(prefs, PREF_GROUP_UI, "otr.warn", &err);
+    gboolean otr_warn = g_key_file_get_boolean(prefs, PREF_GROUP_OTR, "warn", &err);
     if (err == NULL) {
-        g_key_file_set_boolean(prefs, PREF_GROUP_OTR, _get_key(PREF_OTR_WARN), ui_otr_warn);
-        g_key_file_remove_key(prefs, PREF_GROUP_UI, "otr.warn", NULL);
-    } else {
-        g_error_free(err);
-    }
-
-    err = NULL;
-    gchar *ui_otr_log = g_key_file_get_string(prefs, PREF_GROUP_LOGGING, "otr", &err);
-    if (err == NULL) {
-        g_key_file_set_string(prefs, PREF_GROUP_OTR, _get_key(PREF_OTR_LOG), ui_otr_log);
-        g_key_file_remove_key(prefs, PREF_GROUP_LOGGING, "otr", NULL);
-    } else {
-        g_error_free(err);
-    }
-
-    err = NULL;
-    gchar *ui_otr_policy = g_key_file_get_string(prefs, "policy", "otr.policy", &err);
-    if (err == NULL) {
-        g_key_file_set_string(prefs, PREF_GROUP_OTR, _get_key(PREF_OTR_POLICY), ui_otr_policy);
-        g_key_file_remove_group(prefs, "policy", NULL);
+        g_key_file_set_boolean(prefs, PREF_GROUP_UI, _get_key(PREF_OTR_WARN), otr_warn);
+        g_key_file_remove_key(prefs, PREF_GROUP_OTR, "warn", NULL);
     } else {
         g_error_free(err);
     }
@@ -198,7 +180,7 @@ prefs_get_string(preference_t pref)
     char *result = g_key_file_get_string(prefs, group, key, NULL);
 
     if (result == NULL) {
-        if (def != NULL) {
+        if (def) {
             return strdup(def);
         } else {
             return NULL;
@@ -211,7 +193,7 @@ prefs_get_string(preference_t pref)
 void
 prefs_free_string(char *pref)
 {
-    if (pref != NULL) {
+    if (pref) {
         free(pref);
     }
     pref = NULL;
@@ -358,7 +340,7 @@ prefs_get_occupants_size(void)
     gint result = g_key_file_get_integer(prefs, PREF_GROUP_UI, "occupants.size", NULL);
 
     if (result > 99 || result < 1) {
-        return 20;
+        return 15;
     } else {
         return result;
     }
@@ -377,7 +359,7 @@ prefs_get_roster_size(void)
     gint result = g_key_file_get_integer(prefs, PREF_GROUP_UI, "roster.size", NULL);
 
     if (result > 99 || result < 1) {
-        return 20;
+        return 25;
     } else {
         return result;
     }
@@ -437,7 +419,7 @@ prefs_get_aliases(void)
             char *name = keys[i];
             char *value = g_key_file_get_string(prefs, PREF_GROUP_ALIAS, name, NULL);
 
-            if (value != NULL) {
+            if (value) {
                 ProfAlias *alias = malloc(sizeof(struct prof_alias_t));
                 alias->name = strdup(name);
                 alias->value = strdup(value);
@@ -517,6 +499,7 @@ _get_group(preference_t pref)
         case PREF_HISTORY:
         case PREF_MOUSE:
         case PREF_OCCUPANTS:
+        case PREF_OCCUPANTS_JID:
         case PREF_STATUSES:
         case PREF_STATUSES_CONSOLE:
         case PREF_STATUSES_CHAT:
@@ -525,12 +508,14 @@ _get_group(preference_t pref)
         case PREF_PRESENCE:
         case PREF_WRAP:
         case PREF_TIME:
+        case PREF_TIME_STATUSBAR:
         case PREF_ROSTER:
         case PREF_ROSTER_OFFLINE:
         case PREF_ROSTER_RESOURCE:
         case PREF_ROSTER_BY:
         case PREF_RESOURCE_TITLE:
         case PREF_RESOURCE_MESSAGE:
+        case PREF_OTR_WARN:
         case PREF_INPBLOCK_DYNAMIC:
             return PREF_GROUP_UI;
         case PREF_STATES:
@@ -558,8 +543,10 @@ _get_group(preference_t pref)
             return PREF_GROUP_PRESENCE;
         case PREF_CONNECT_ACCOUNT:
         case PREF_DEFAULT_ACCOUNT:
+        case PREF_CARBONS:
+        case PREF_RECEIPTS_SEND:
+        case PREF_RECEIPTS_REQUEST:
             return PREF_GROUP_CONNECTION;
-        case PREF_OTR_WARN:
         case PREF_OTR_LOG:
         case PREF_OTR_POLICY:
             return PREF_GROUP_OTR;
@@ -593,10 +580,18 @@ _get_key(preference_t pref)
             return "intype";
         case PREF_HISTORY:
             return "history";
+        case PREF_CARBONS:
+            return "carbons";
+        case PREF_RECEIPTS_SEND:
+            return "receipts.send";
+        case PREF_RECEIPTS_REQUEST:
+            return "receipts.request";
         case PREF_MOUSE:
             return "mouse";
         case PREF_OCCUPANTS:
             return "occupants";
+        case PREF_OCCUPANTS_JID:
+            return "occupants.jid";
         case PREF_MUC_PRIVILEGES:
             return "privileges";
         case PREF_STATUSES:
@@ -648,7 +643,7 @@ _get_key(preference_t pref)
         case PREF_OTR_LOG:
             return "log";
         case PREF_OTR_WARN:
-            return "warn";
+            return "otr.warn";
         case PREF_OTR_POLICY:
             return "policy";
         case PREF_LOG_ROTATE:
@@ -661,6 +656,8 @@ _get_key(preference_t pref)
             return "wrap";
         case PREF_TIME:
             return "time";
+        case PREF_TIME_STATUSBAR:
+            return "time.statusbar";
         case PREF_ROSTER:
             return "roster";
         case PREF_ROSTER_OFFLINE:
@@ -691,15 +688,24 @@ _get_default_boolean(preference_t pref)
         case PREF_AUTOAWAY_CHECK:
         case PREF_LOG_ROTATE:
         case PREF_LOG_SHARED:
+        case PREF_NOTIFY_MESSAGE:
         case PREF_NOTIFY_MESSAGE_CURRENT:
         case PREF_NOTIFY_ROOM_CURRENT:
+        case PREF_NOTIFY_TYPING:
         case PREF_NOTIFY_TYPING_CURRENT:
+        case PREF_NOTIFY_SUB:
+        case PREF_NOTIFY_INVITE:
         case PREF_SPLASH:
         case PREF_OCCUPANTS:
         case PREF_MUC_PRIVILEGES:
         case PREF_PRESENCE:
         case PREF_WRAP:
         case PREF_INPBLOCK_DYNAMIC:
+        case PREF_RESOURCE_TITLE:
+        case PREF_RESOURCE_MESSAGE:
+        case PREF_ROSTER:
+        case PREF_ROSTER_OFFLINE:
+        case PREF_ROSTER_RESOURCE:
             return TRUE;
         default:
             return FALSE;
@@ -715,7 +721,7 @@ _get_default_string(preference_t pref)
     {
         case PREF_AUTOAWAY_MODE:
         case PREF_NOTIFY_ROOM:
-            return "off";
+            return "on";
         case PREF_OTR_LOG:
             return "redact";
         case PREF_OTR_POLICY:
@@ -725,9 +731,11 @@ _get_default_string(preference_t pref)
         case PREF_STATUSES_MUC:
             return "all";
         case PREF_ROSTER_BY:
-            return "none";
+            return "presence";
         case PREF_TIME:
             return "%H:%M:%S";
+        case PREF_TIME_STATUSBAR:
+            return "%H:%M";
         default:
             return NULL;
     }
diff --git a/src/config/preferences.h b/src/config/preferences.h
index 68286f09..4455eca1 100644
--- a/src/config/preferences.h
+++ b/src/config/preferences.h
@@ -1,7 +1,7 @@
 /*
  * preferences.h
  *
- * Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com>
+ * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com>
  *
  * This file is part of Profanity.
  *
@@ -59,9 +59,13 @@ typedef enum {
     PREF_FLASH,
     PREF_INTYPE,
     PREF_HISTORY,
+    PREF_CARBONS,
+    PREF_RECEIPTS_SEND,
+    PREF_RECEIPTS_REQUEST,
     PREF_MOUSE,
     PREF_OCCUPANTS,
     PREF_OCCUPANTS_SIZE,
+    PREF_OCCUPANTS_JID,
     PREF_ROSTER,
     PREF_ROSTER_SIZE,
     PREF_ROSTER_OFFLINE,
@@ -71,6 +75,7 @@ typedef enum {
     PREF_PRESENCE,
     PREF_WRAP,
     PREF_TIME,
+    PREF_TIME_STATUSBAR,
     PREF_STATUSES,
     PREF_STATUSES_CONSOLE,
     PREF_STATUSES_CHAT,
diff --git a/src/config/theme.c b/src/config/theme.c
index 6d3c5938..f73dee19 100644
--- a/src/config/theme.c
+++ b/src/config/theme.c
@@ -1,7 +1,7 @@
 /*
  * theme.c
  *
- * Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com>
+ * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com>
  *
  * This file is part of Profanity.
  *
@@ -121,6 +121,7 @@ static struct colours_t {
         NCURSES_COLOR_T otruntrusted;
         NCURSES_COLOR_T rosterheader;
         NCURSES_COLOR_T occupantsheader;
+        NCURSES_COLOR_T receiptsent;
 } colour_prefs;
 
 static NCURSES_COLOR_T _lookup_colour(const char * const colour);
@@ -159,7 +160,7 @@ _theme_load_file(const char * const theme_name)
 {
     // use default theme
     if (theme_name == NULL || strcmp(theme_name, "default") == 0) {
-        if (theme != NULL) {
+        if (theme) {
             g_key_file_free(theme);
         }
         theme = g_key_file_new();
@@ -172,12 +173,12 @@ _theme_load_file(const char * const theme_name)
             return FALSE;
         }
 
-        if (theme_loc != NULL) {
+        if (theme_loc) {
             g_string_free(theme_loc, TRUE);
         }
         theme_loc = new_theme_file;
         log_info("Loading theme \"%s\"", theme_name);
-        if (theme != NULL) {
+        if (theme) {
             g_key_file_free(theme);
         }
         theme = g_key_file_new();
@@ -192,7 +193,9 @@ GSList *
 theme_list(void)
 {
     GSList *result = NULL;
-    _theme_list_dir(_get_themes_dir(), &result);
+    char *themes_dir = _get_themes_dir();
+    _theme_list_dir(themes_dir, &result);
+    free(themes_dir);
 #ifdef THEMES_PATH
     _theme_list_dir(THEMES_PATH, &result);
 #endif
@@ -202,10 +205,10 @@ theme_list(void)
 void
 theme_close(void)
 {
-    if (theme != NULL) {
+    if (theme) {
         g_key_file_free(theme);
     }
-    if (theme_loc != NULL) {
+    if (theme_loc) {
         g_string_free(theme_loc, TRUE);
     }
     if (bold_items) {
@@ -249,47 +252,48 @@ theme_init_colours(void)
     // chat
     init_pair(25, colour_prefs.me, colour_prefs.bkgnd);
     init_pair(26, colour_prefs.them, colour_prefs.bkgnd);
+    init_pair(27, colour_prefs.receiptsent, colour_prefs.bkgnd);
 
     // room chat
-    init_pair(27, colour_prefs.roominfo, colour_prefs.bkgnd);
-    init_pair(28, colour_prefs.roommention, colour_prefs.bkgnd);
+    init_pair(28, colour_prefs.roominfo, colour_prefs.bkgnd);
+    init_pair(29, colour_prefs.roommention, colour_prefs.bkgnd);
 
     // statuses
-    init_pair(29, colour_prefs.online, colour_prefs.bkgnd);
-    init_pair(30, colour_prefs.offline, colour_prefs.bkgnd);
-    init_pair(31, colour_prefs.away, colour_prefs.bkgnd);
-    init_pair(32, colour_prefs.chat, colour_prefs.bkgnd);
-    init_pair(33, colour_prefs.dnd, colour_prefs.bkgnd);
-    init_pair(34, colour_prefs.xa, colour_prefs.bkgnd);
+    init_pair(30, colour_prefs.online, colour_prefs.bkgnd);
+    init_pair(31, colour_prefs.offline, colour_prefs.bkgnd);
+    init_pair(32, colour_prefs.away, colour_prefs.bkgnd);
+    init_pair(33, colour_prefs.chat, colour_prefs.bkgnd);
+    init_pair(34, colour_prefs.dnd, colour_prefs.bkgnd);
+    init_pair(35, colour_prefs.xa, colour_prefs.bkgnd);
 
     // states
-    init_pair(35, colour_prefs.typing, colour_prefs.bkgnd);
-    init_pair(36, colour_prefs.gone, colour_prefs.bkgnd);
+    init_pair(36, colour_prefs.typing, colour_prefs.bkgnd);
+    init_pair(37, colour_prefs.gone, colour_prefs.bkgnd);
 
     // subscription status
-    init_pair(37, colour_prefs.subscribed, colour_prefs.bkgnd);
-    init_pair(38, colour_prefs.unsubscribed, colour_prefs.bkgnd);
+    init_pair(38, colour_prefs.subscribed, colour_prefs.bkgnd);
+    init_pair(39, colour_prefs.unsubscribed, colour_prefs.bkgnd);
 
     // otr messages
-    init_pair(39, colour_prefs.otrstartedtrusted, colour_prefs.bkgnd);
-    init_pair(40, colour_prefs.otrstarteduntrusted, colour_prefs.bkgnd);
-    init_pair(41, colour_prefs.otrended, colour_prefs.bkgnd);
-    init_pair(42, colour_prefs.otrtrusted, colour_prefs.bkgnd);
-    init_pair(43, colour_prefs.otruntrusted, colour_prefs.bkgnd);
+    init_pair(40, colour_prefs.otrstartedtrusted, colour_prefs.bkgnd);
+    init_pair(41, colour_prefs.otrstarteduntrusted, colour_prefs.bkgnd);
+    init_pair(42, colour_prefs.otrended, colour_prefs.bkgnd);
+    init_pair(43, colour_prefs.otrtrusted, colour_prefs.bkgnd);
+    init_pair(44, colour_prefs.otruntrusted, colour_prefs.bkgnd);
 
     // subwin headers
-    init_pair(44, colour_prefs.rosterheader, colour_prefs.bkgnd);
-    init_pair(45, colour_prefs.occupantsheader, colour_prefs.bkgnd);
+    init_pair(45, colour_prefs.rosterheader, colour_prefs.bkgnd);
+    init_pair(46, colour_prefs.occupantsheader, colour_prefs.bkgnd);
 
     // raw
-    init_pair(46, COLOR_WHITE, colour_prefs.bkgnd);
-    init_pair(47, COLOR_GREEN, colour_prefs.bkgnd);
-    init_pair(48, COLOR_RED, colour_prefs.bkgnd);
-    init_pair(49, COLOR_YELLOW, colour_prefs.bkgnd);
-    init_pair(50, COLOR_BLUE, colour_prefs.bkgnd);
-    init_pair(51, COLOR_CYAN, colour_prefs.bkgnd);
-    init_pair(52, COLOR_BLACK, colour_prefs.bkgnd);
-    init_pair(53, COLOR_MAGENTA, colour_prefs.bkgnd);
+    init_pair(47, COLOR_WHITE, colour_prefs.bkgnd);
+    init_pair(48, COLOR_GREEN, colour_prefs.bkgnd);
+    init_pair(49, COLOR_RED, colour_prefs.bkgnd);
+    init_pair(50, COLOR_YELLOW, colour_prefs.bkgnd);
+    init_pair(51, COLOR_BLUE, colour_prefs.bkgnd);
+    init_pair(52, COLOR_CYAN, colour_prefs.bkgnd);
+    init_pair(53, COLOR_BLACK, colour_prefs.bkgnd);
+    init_pair(54, COLOR_MAGENTA, colour_prefs.bkgnd);
 }
 
 static NCURSES_COLOR_T
@@ -395,6 +399,7 @@ _load_colours(void)
     _set_colour("them",                     &colour_prefs.them,                 COLOR_GREEN,    THEME_THEM);
     _set_colour("roster.header",            &colour_prefs.rosterheader,         COLOR_YELLOW,   THEME_ROSTER_HEADER);
     _set_colour("occupants.header",         &colour_prefs.occupantsheader,      COLOR_YELLOW,   THEME_OCCUPANTS_HEADER);
+    _set_colour("receipt.sent",             &colour_prefs.receiptsent,          COLOR_RED,      THEME_RECEIPT_SENT);
 }
 
 static void
@@ -419,20 +424,22 @@ _set_boolean_preference(char *prefstr, preference_t pref)
 static void
 _load_preferences(void)
 {
-    _set_boolean_preference("intype", PREF_INTYPE);
     _set_boolean_preference("beep", PREF_BEEP);
     _set_boolean_preference("flash", PREF_FLASH);
-    _set_boolean_preference("privileges", PREF_MUC_PRIVILEGES);
-    _set_boolean_preference("presence", PREF_PRESENCE);
+    _set_boolean_preference("splash", PREF_SPLASH);
     _set_boolean_preference("wrap", PREF_WRAP);
-
     _set_string_preference("time", PREF_TIME);
-    _set_string_preference("statuses.muc", PREF_STATUSES_MUC);
+    _set_string_preference("time.statusbar", PREF_TIME_STATUSBAR);
+
+    _set_boolean_preference("resource.title", PREF_RESOURCE_TITLE);
+    _set_boolean_preference("resource.message", PREF_RESOURCE_MESSAGE);
+
     _set_string_preference("statuses.console", PREF_STATUSES_CONSOLE);
     _set_string_preference("statuses.chat", PREF_STATUSES_CHAT);
+    _set_string_preference("statuses.muc", PREF_STATUSES_MUC);
 
     _set_boolean_preference("occupants", PREF_OCCUPANTS);
-
+    _set_boolean_preference("occupants.jid", PREF_OCCUPANTS_JID);
     if (g_key_file_has_key(theme, "ui", "occupants.size", NULL)) {
         gint occupants_size = g_key_file_get_integer(theme, "ui", "occupants.size", NULL);
         prefs_set_occupants_size(occupants_size);
@@ -442,12 +449,16 @@ _load_preferences(void)
     _set_boolean_preference("roster.offline", PREF_ROSTER_OFFLINE);
     _set_boolean_preference("roster.resource", PREF_ROSTER_RESOURCE);
     _set_string_preference("roster.by", PREF_ROSTER_BY);
-
     if (g_key_file_has_key(theme, "ui", "roster.size", NULL)) {
         gint roster_size = g_key_file_get_integer(theme, "ui", "roster.size", NULL);
         prefs_set_roster_size(roster_size);
     }
 
+    _set_boolean_preference("privileges", PREF_MUC_PRIVILEGES);
+
+    _set_boolean_preference("presence", PREF_PRESENCE);
+    _set_boolean_preference("intype", PREF_INTYPE);
+
     _set_boolean_preference("otr.warn", PREF_OTR_WARN);
 }
 
@@ -465,9 +476,9 @@ void
 _theme_list_dir(const gchar * const dir, GSList **result)
 {
     GDir *themes = g_dir_open(dir, 0, NULL);
-    if (themes != NULL) {
+    if (themes) {
         const gchar *theme = g_dir_read_name(themes);
-        while (theme != NULL) {
+        while (theme) {
             *result = g_slist_append(*result, strdup(theme));
             theme = g_dir_read_name(themes);
         }
@@ -481,7 +492,7 @@ _theme_find(const char * const theme_name)
     GString *path = NULL;
     gchar *themes_dir = _get_themes_dir();
 
-    if (themes_dir != NULL) {
+    if (themes_dir) {
         path = g_string_new(themes_dir);
         g_free(themes_dir);
         g_string_append(path, "/");
@@ -557,42 +568,43 @@ theme_attrs(theme_item_t attrs)
     case THEME_STATUS_NEW:              result = COLOR_PAIR(24); break;
     case THEME_ME:                      result = COLOR_PAIR(25); break;
     case THEME_THEM:                    result = COLOR_PAIR(26); break;
-    case THEME_ROOMINFO:                result = COLOR_PAIR(27); break;
-    case THEME_ROOMMENTION:             result = COLOR_PAIR(28); break;
-    case THEME_ONLINE:                  result = COLOR_PAIR(29); break;
-    case THEME_OFFLINE:                 result = COLOR_PAIR(30); break;
-    case THEME_AWAY:                    result = COLOR_PAIR(31); break;
-    case THEME_CHAT:                    result = COLOR_PAIR(32); break;
-    case THEME_DND:                     result = COLOR_PAIR(33); break;
-    case THEME_XA:                      result = COLOR_PAIR(34); break;
-    case THEME_TYPING:                  result = COLOR_PAIR(35); break;
-    case THEME_GONE:                    result = COLOR_PAIR(36); break;
-    case THEME_SUBSCRIBED:              result = COLOR_PAIR(37); break;
-    case THEME_UNSUBSCRIBED:            result = COLOR_PAIR(38); break;
-    case THEME_OTR_STARTED_TRUSTED:     result = COLOR_PAIR(39); break;
-    case THEME_OTR_STARTED_UNTRUSTED:   result = COLOR_PAIR(40); break;
-    case THEME_OTR_ENDED:               result = COLOR_PAIR(41); break;
-    case THEME_OTR_TRUSTED:             result = COLOR_PAIR(42); break;
-    case THEME_OTR_UNTRUSTED:           result = COLOR_PAIR(43); break;
-    case THEME_ROSTER_HEADER:           result = COLOR_PAIR(44); break;
-    case THEME_OCCUPANTS_HEADER:        result = COLOR_PAIR(45); break;
-    case THEME_WHITE:                   result = COLOR_PAIR(46); break;
-    case THEME_WHITE_BOLD:              result = COLOR_PAIR(46); break;
-    case THEME_GREEN:                   result = COLOR_PAIR(47); break;
-    case THEME_GREEN_BOLD:              result = COLOR_PAIR(47); break;
-    case THEME_RED:                     result = COLOR_PAIR(48); break;
-    case THEME_RED_BOLD:                result = COLOR_PAIR(48); break;
-    case THEME_YELLOW:                  result = COLOR_PAIR(49); break;
-    case THEME_YELLOW_BOLD:             result = COLOR_PAIR(49); break;
-    case THEME_BLUE:                    result = COLOR_PAIR(50); break;
-    case THEME_BLUE_BOLD:               result = COLOR_PAIR(50); break;
-    case THEME_CYAN:                    result = COLOR_PAIR(51); break;
-    case THEME_CYAN_BOLD:               result = COLOR_PAIR(51); break;
-    case THEME_BLACK:                   result = COLOR_PAIR(52); break;
-    case THEME_BLACK_BOLD:              result = COLOR_PAIR(52); break;
-    case THEME_MAGENTA:                 result = COLOR_PAIR(53); break;
-    case THEME_MAGENTA_BOLD:            result = COLOR_PAIR(53); break;
-    default:                           break;
+    case THEME_RECEIPT_SENT:            result = COLOR_PAIR(27); break;
+    case THEME_ROOMINFO:                result = COLOR_PAIR(28); break;
+    case THEME_ROOMMENTION:             result = COLOR_PAIR(29); break;
+    case THEME_ONLINE:                  result = COLOR_PAIR(30); break;
+    case THEME_OFFLINE:                 result = COLOR_PAIR(31); break;
+    case THEME_AWAY:                    result = COLOR_PAIR(32); break;
+    case THEME_CHAT:                    result = COLOR_PAIR(33); break;
+    case THEME_DND:                     result = COLOR_PAIR(34); break;
+    case THEME_XA:                      result = COLOR_PAIR(35); break;
+    case THEME_TYPING:                  result = COLOR_PAIR(36); break;
+    case THEME_GONE:                    result = COLOR_PAIR(37); break;
+    case THEME_SUBSCRIBED:              result = COLOR_PAIR(38); break;
+    case THEME_UNSUBSCRIBED:            result = COLOR_PAIR(39); break;
+    case THEME_OTR_STARTED_TRUSTED:     result = COLOR_PAIR(40); break;
+    case THEME_OTR_STARTED_UNTRUSTED:   result = COLOR_PAIR(41); break;
+    case THEME_OTR_ENDED:               result = COLOR_PAIR(42); break;
+    case THEME_OTR_TRUSTED:             result = COLOR_PAIR(43); break;
+    case THEME_OTR_UNTRUSTED:           result = COLOR_PAIR(44); break;
+    case THEME_ROSTER_HEADER:           result = COLOR_PAIR(45); break;
+    case THEME_OCCUPANTS_HEADER:        result = COLOR_PAIR(46); break;
+    case THEME_WHITE:                   result = COLOR_PAIR(47); break;
+    case THEME_WHITE_BOLD:              result = COLOR_PAIR(47); break;
+    case THEME_GREEN:                   result = COLOR_PAIR(48); break;
+    case THEME_GREEN_BOLD:              result = COLOR_PAIR(48); break;
+    case THEME_RED:                     result = COLOR_PAIR(49); break;
+    case THEME_RED_BOLD:                result = COLOR_PAIR(49); break;
+    case THEME_YELLOW:                  result = COLOR_PAIR(50); break;
+    case THEME_YELLOW_BOLD:             result = COLOR_PAIR(50); break;
+    case THEME_BLUE:                    result = COLOR_PAIR(51); break;
+    case THEME_BLUE_BOLD:               result = COLOR_PAIR(51); break;
+    case THEME_CYAN:                    result = COLOR_PAIR(52); break;
+    case THEME_CYAN_BOLD:               result = COLOR_PAIR(52); break;
+    case THEME_BLACK:                   result = COLOR_PAIR(53); break;
+    case THEME_BLACK_BOLD:              result = COLOR_PAIR(53); break;
+    case THEME_MAGENTA:                 result = COLOR_PAIR(54); break;
+    case THEME_MAGENTA_BOLD:            result = COLOR_PAIR(54); break;
+    default:                            break;
     }
 
     if (g_hash_table_lookup(bold_items, GINT_TO_POINTER(attrs))) {
diff --git a/src/config/theme.h b/src/config/theme.h
index a6a580f8..13099eb4 100644
--- a/src/config/theme.h
+++ b/src/config/theme.h
@@ -1,7 +1,7 @@
 /*
  * theme.h
  *
- * Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com>
+ * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com>
  *
  * This file is part of Profanity.
  *
@@ -90,6 +90,7 @@ typedef enum {
     THEME_OTR_UNTRUSTED,
     THEME_OCCUPANTS_HEADER,
     THEME_ROSTER_HEADER,
+    THEME_RECEIPT_SENT,
     THEME_NONE,
     THEME_WHITE,
     THEME_WHITE_BOLD,