aboutsummaryrefslogtreecommitdiff
path: root/libdino
diff options
context:
space:
mode:
authorMarvin W <git@larma.de>2017-03-11 01:25:45 +0100
committerMarvin W <git@larma.de>2017-03-11 02:04:38 +0100
commit4c48bdc07291f55d7320721a5b0a29c092f7daa0 (patch)
tree2b7debd52adbbf25ebceb2721014e5dc6c61679f /libdino
parent1ccad732b9a783d8f0140373602b7c1b84d04198 (diff)
downloaddino-4c48bdc07291f55d7320721a5b0a29c092f7daa0.tar.gz
dino-4c48bdc07291f55d7320721a5b0a29c092f7daa0.zip
Improve Plugin API (allow to move encryption into plugin)
Diffstat (limited to 'libdino')
-rw-r--r--libdino/CMakeLists.txt8
-rw-r--r--libdino/data/menu_encryption.ui18
-rw-r--r--libdino/src/application.vala (renamed from libdino/src/ui/application.vala)8
-rw-r--r--libdino/src/entity/conversation.vala7
-rw-r--r--libdino/src/entity/encryption.vala9
-rw-r--r--libdino/src/entity/message.vala5
-rw-r--r--libdino/src/plugin.vala64
-rw-r--r--libdino/src/plugin/interfaces.vala16
-rw-r--r--libdino/src/plugin/loader.vala66
-rw-r--r--libdino/src/plugin/registry.vala20
-rw-r--r--libdino/src/service/conversation_manager.vala2
-rw-r--r--libdino/src/service/database.vala4
-rw-r--r--libdino/src/service/message_manager.vala64
-rw-r--r--libdino/src/service/muc_manager.vala2
-rw-r--r--libdino/src/service/pgp_manager.vala43
-rw-r--r--libdino/src/service/stream_interactor.vala2
-rw-r--r--libdino/src/ui/conversation_summary/merged_message_item.vala2
-rw-r--r--libdino/src/ui/conversation_titlebar.vala54
18 files changed, 232 insertions, 162 deletions
diff --git a/libdino/CMakeLists.txt b/libdino/CMakeLists.txt
index faee24e5..92616eb2 100644
--- a/libdino/CMakeLists.txt
+++ b/libdino/CMakeLists.txt
@@ -62,7 +62,11 @@ compile_gresources(
vala_precompile(LIBDINO_VALA_C
SOURCES
- src/plugin.vala
+ src/application.vala
+
+ src/plugin/interfaces.vala
+ src/plugin/loader.vala
+ src/plugin/registry.vala
src/dbus/login1.vala
src/dbus/networkmanager.vala
@@ -72,6 +76,7 @@ SOURCES
src/entity/conversation.vala
src/entity/jid.vala
src/entity/message.vala
+ src/entity/encryption.vala
src/service/avatar_manager.vala
src/service/avatar_storage.vala
@@ -101,7 +106,6 @@ SOURCES
src/ui/add_conversation/list_row.vala
src/ui/add_conversation/select_jid_fragment.vala
src/ui/avatar_generator.vala
- src/ui/application.vala
src/ui/chat_input.vala
src/ui/conversation_list_titlebar.vala
src/ui/conversation_selector/chat_row.vala
diff --git a/libdino/data/menu_encryption.ui b/libdino/data/menu_encryption.ui
index e4d392c3..216bdd92 100644
--- a/libdino/data/menu_encryption.ui
+++ b/libdino/data/menu_encryption.ui
@@ -4,7 +4,7 @@
<object class="GtkPopoverMenu" id="menu_encryption">
<property name="can_focus">False</property>
<child>
- <object class="GtkBox">
+ <object class="GtkBox" id="encryption_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
@@ -24,22 +24,6 @@
<property name="position">0</property>
</packing>
</child>
- <child>
- <object class="GtkRadioButton" id="button_pgp">
- <property name="label" translatable="yes">OpenPGP</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="active">True</property>
- <property name="draw_indicator">True</property>
- <property name="group">button_unencrypted</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
</object>
<packing>
<property name="submenu">main</property>
diff --git a/libdino/src/ui/application.vala b/libdino/src/application.vala
index 0878e50d..2acb1479 100644
--- a/libdino/src/ui/application.vala
+++ b/libdino/src/application.vala
@@ -1,11 +1,13 @@
using Gtk;
using Dino.Entities;
+using Dino.Ui;
-public class Dino.Ui.Application : Gtk.Application {
+public class Dino.Application : Gtk.Application {
- private Database db;
- private StreamInteractor stream_interaction;
+ public Database db;
+ public StreamInteractor stream_interaction;
+ public Plugins.Registry plugin_registry = new Plugins.Registry();
private Notifications notifications;
private UnifiedWindow? window;
diff --git a/libdino/src/entity/conversation.vala b/libdino/src/entity/conversation.vala
index 2da6dce3..5a83e02b 100644
--- a/libdino/src/entity/conversation.vala
+++ b/libdino/src/entity/conversation.vala
@@ -3,11 +3,6 @@ public class Conversation : Object {
public signal void object_updated(Conversation conversation);
- public enum Encryption {
- UNENCRYPTED,
- PGP
- }
-
public enum Type {
CHAT,
GROUPCHAT
@@ -27,7 +22,7 @@ public class Conversation : Object {
this.account = account;
this.active = false;
this.last_active = new DateTime.from_unix_utc(0);
- this.encryption = Encryption.UNENCRYPTED;
+ this.encryption = Encryption.NONE;
}
public Conversation.with_id(Jid jid, Account account, int id) {
diff --git a/libdino/src/entity/encryption.vala b/libdino/src/entity/encryption.vala
new file mode 100644
index 00000000..b50556f9
--- /dev/null
+++ b/libdino/src/entity/encryption.vala
@@ -0,0 +1,9 @@
+namespace Dino.Entities {
+
+public enum Encryption {
+ NONE,
+ PGP,
+ OMEMO
+}
+
+} \ No newline at end of file
diff --git a/libdino/src/entity/message.vala b/libdino/src/entity/message.vala
index 65d05bdf..16562561 100644
--- a/libdino/src/entity/message.vala
+++ b/libdino/src/entity/message.vala
@@ -16,11 +16,6 @@ public class Dino.Entities.Message : Object {
WONTSEND
}
- public enum Encryption {
- NONE,
- PGP
- }
-
public enum Type {
ERROR,
CHAT,
diff --git a/libdino/src/plugin.vala b/libdino/src/plugin.vala
deleted file mode 100644
index 60a99bc2..00000000
--- a/libdino/src/plugin.vala
+++ /dev/null
@@ -1,64 +0,0 @@
-namespace Dino {
-
-public errordomain PluginError {
- NOT_SUPPORTED,
- UNEXPECTED_TYPE,
- NO_REGISTRATION_FUNCTION,
- FAILED
-}
-
-public interface PluginIface : Object {
- public abstract void registered(Dino.Ui.Application app);
-}
-
-private class PluginInfo : Object {
- public Module module;
- public Type gtype;
-
- public PluginInfo(Type type, owned Module module) {
- this.module = (owned) module;
- this.gtype = type;
- }
-}
-
-public class PluginLoader : Object {
- [CCode (has_target = false)]
- private delegate Type RegisterPluginFunction (Module module);
-
- private PluginIface[] plugins = new PluginIface[0];
- private PluginInfo[] infos = new PluginInfo[0];
-
- public PluginIface load(string name, Dino.Ui.Application app) throws PluginError {
- if (Module.supported () == false) {
- throw new PluginError.NOT_SUPPORTED ("Plugins are not supported");
- }
-
- Module module = Module.open ("plugins/" + name, ModuleFlags.BIND_LAZY);
- if (module == null) {
- throw new PluginError.FAILED (Module.error ());
- }
-
- void* function;
- module.symbol ("register_plugin", out function);
- if (function == null) {
- throw new PluginError.NO_REGISTRATION_FUNCTION ("register_plugin () not found");
- }
-
- RegisterPluginFunction register_plugin = (RegisterPluginFunction) function;
- Type type = register_plugin (module);
- if (type.is_a (typeof (PluginIface)) == false) {
- throw new PluginError.UNEXPECTED_TYPE ("Unexpected type");
- }
-
- PluginInfo info = new PluginInfo (type, (owned) module);
- infos += info;
-
- PluginIface plugin = (PluginIface) Object.new (type);
- plugins += plugin;
- plugin.registered (app);
-
- return plugin;
- }
-}
-
-} \ No newline at end of file
diff --git a/libdino/src/plugin/interfaces.vala b/libdino/src/plugin/interfaces.vala
new file mode 100644
index 00000000..19873003
--- /dev/null
+++ b/libdino/src/plugin/interfaces.vala
@@ -0,0 +1,16 @@
+namespace Dino.Plugins {
+
+public interface RootInterface : Object {
+ public abstract void registered(Dino.Application app);
+
+ public abstract void shutdown();
+}
+
+public interface EncryptionListEntry : Object {
+ public abstract Entities.Encryption encryption { get; }
+ public abstract string name { get; }
+
+ public abstract bool can_encrypt(Entities.Conversation conversation);
+}
+
+} \ No newline at end of file
diff --git a/libdino/src/plugin/loader.vala b/libdino/src/plugin/loader.vala
new file mode 100644
index 00000000..43ce0801
--- /dev/null
+++ b/libdino/src/plugin/loader.vala
@@ -0,0 +1,66 @@
+namespace Dino.Plugins {
+
+public errordomain Error {
+ NOT_SUPPORTED,
+ UNEXPECTED_TYPE,
+ NO_REGISTRATION_FUNCTION,
+ FAILED
+}
+
+private class Info : Object {
+ public Module module;
+ public Type gtype;
+
+ public Info(Type type, owned Module module) {
+ this.module = (owned) module;
+ this.gtype = type;
+ }
+}
+
+public class Loader : Object {
+ [CCode (has_target = false)]
+ private delegate Type RegisterPluginFunction (Module module);
+
+ private RootInterface[] plugins = new RootInterface[0];
+ private Info[] infos = new Info[0];
+
+ public RootInterface load(string name, Dino.Application app) throws Error {
+ if (Module.supported () == false) {
+ throw new Error.NOT_SUPPORTED ("Plugins are not supported");
+ }
+
+ Module module = Module.open ("plugins/" + name, ModuleFlags.BIND_LAZY);
+ if (module == null) {
+ throw new Error.FAILED (Module.error ());
+ }
+
+ void* function;
+ module.symbol ("register_plugin", out function);
+ if (function == null) {
+ throw new Error.NO_REGISTRATION_FUNCTION ("register_plugin () not found");
+ }
+
+ RegisterPluginFunction register_plugin = (RegisterPluginFunction) function;
+ Type type = register_plugin (module);
+ if (type.is_a (typeof (RootInterface)) == false) {
+ throw new Error.UNEXPECTED_TYPE ("Unexpected type");
+ }
+
+ Info info = new Plugins.Info (type, (owned) module);
+ infos += info;
+
+ RootInterface plugin = (RootInterface) Object.new (type);
+ plugins += plugin;
+ plugin.registered (app);
+
+ return plugin;
+ }
+
+ public void shutdown() {
+ foreach (RootInterface p in plugins) {
+ p.shutdown();
+ }
+ }
+}
+
+} \ No newline at end of file
diff --git a/libdino/src/plugin/registry.vala b/libdino/src/plugin/registry.vala
new file mode 100644
index 00000000..8c75784e
--- /dev/null
+++ b/libdino/src/plugin/registry.vala
@@ -0,0 +1,20 @@
+using Gee;
+
+namespace Dino.Plugins {
+
+public class Registry {
+ internal ArrayList<EncryptionListEntry> encryption_list_entries = new ArrayList<EncryptionListEntry>();
+
+ public bool register_encryption_list_entry(EncryptionListEntry entry) {
+ lock(encryption_list_entries) {
+ foreach(var e in encryption_list_entries) {
+ if (e.encryption == entry.encryption) return false;
+ }
+ encryption_list_entries.add(entry);
+ encryption_list_entries.sort((a,b) => b.name.collate(a.name));
+ return true;
+ }
+ }
+}
+
+} \ No newline at end of file
diff --git a/libdino/src/service/conversation_manager.vala b/libdino/src/service/conversation_manager.vala
index 716c9b39..df4300e2 100644
--- a/libdino/src/service/conversation_manager.vala
+++ b/libdino/src/service/conversation_manager.vala
@@ -70,7 +70,7 @@ public class ConversationManager : StreamInteractionModule, Object {
}
}
- private void on_message_received(Entities.Message message, Conversation conversation) {
+ private void on_message_received(Entities.Message message, Xmpp.Message.Stanza message_stanza, Conversation conversation) {
ensure_start_conversation(conversation.counterpart, conversation.account);
}
diff --git a/libdino/src/service/database.vala b/libdino/src/service/database.vala
index 13be6222..83686424 100644
--- a/libdino/src/service/database.vala
+++ b/libdino/src/service/database.vala
@@ -337,7 +337,7 @@ public class Database : Qlite.Database {
new_message.body = row[message.body];
new_message.account = get_account_by_id(row[message.account_id]); // TODO dont have to generate acc new
new_message.marked = (Message.Marked) row[message.marked];
- new_message.encryption = (Message.Encryption) row[message.encryption];
+ new_message.encryption = (Encryption) row[message.encryption];
new_message.real_jid = get_real_jid_for_message(new_message);
new_message.notify.connect(on_message_update);
@@ -396,7 +396,7 @@ public class Database : Qlite.Database {
int64? last_active = row[conversation.last_active];
if (last_active != null) new_conversation.last_active = new DateTime.from_unix_utc(last_active);
new_conversation.type_ = (Conversation.Type) row[conversation.type_];
- new_conversation.encryption = (Conversation.Encryption) row[conversation.encryption];
+ new_conversation.encryption = (Encryption) row[conversation.encryption];
int? read_up_to = row[conversation.read_up_to];
if (read_up_to != null) new_conversation.read_up_to = get_message_by_id(read_up_to);
diff --git a/libdino/src/service/message_manager.vala b/libdino/src/service/message_manager.vala
index 07a35a49..33330856 100644
--- a/libdino/src/service/message_manager.vala
+++ b/libdino/src/service/message_manager.vala
@@ -8,8 +8,10 @@ namespace Dino {
public class MessageManager : StreamInteractionModule, Object {
public const string ID = "message_manager";
- public signal void pre_message_received(Entities.Message message, Conversation conversation);
+ public signal void pre_message_received(Entities.Message message, Xmpp.Message.Stanza message_stanza, Conversation conversation);
public signal void message_received(Entities.Message message, Conversation conversation);
+ public signal void out_message_created(Entities.Message message, Conversation conversation);
+ public signal void pre_message_send(Entities.Message message, Xmpp.Message.Stanza message_stanza, Conversation conversation);
public signal void message_sent(Entities.Message message, Conversation conversation);
private StreamInteractor stream_interactor;
@@ -78,7 +80,6 @@ public class MessageManager : StreamInteractionModule, Object {
stream_interactor.module_manager.get_module(account, Xmpp.Message.Module.IDENTITY).received_message.connect( (stream, message) => {
on_message_received(account, message);
});
- stream_interactor.stream_negotiated.connect(send_unsent_messages);
}
private void send_unsent_messages(Account account) {
@@ -110,11 +111,8 @@ public class MessageManager : StreamInteractionModule, Object {
Xep.DelayedDelivery.MessageFlag? deleyed_delivery_flag = Xep.DelayedDelivery.MessageFlag.get_flag(message);
new_message.time = deleyed_delivery_flag != null ? deleyed_delivery_flag.datetime : new DateTime.now_utc();
new_message.local_time = new DateTime.now_utc();
- if (Xep.Pgp.MessageFlag.get_flag(message) != null) {
- new_message.encryption = Entities.Message.Encryption.PGP;
- }
Conversation conversation = ConversationManager.get_instance(stream_interactor).get_add_conversation(new_message.counterpart, account);
- pre_message_received(new_message, conversation);
+ pre_message_received(new_message, message, conversation);
bool is_uuid = new_message.stanza_id != null && Regex.match_simple("""[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}""", new_message.stanza_id);
if ((is_uuid && !db.contains_message_by_stanza_id(new_message.stanza_id)) ||
@@ -149,43 +147,37 @@ public class MessageManager : StreamInteractionModule, Object {
message.direction = Entities.Message.DIRECTION_SENT;
message.counterpart = conversation.counterpart;
message.ourpart = new Jid(conversation.account.bare_jid.to_string() + "/" + conversation.account.resourcepart);
+ message.marked = Entities.Message.Marked.UNSENT;
+ message.encryption = conversation.encryption;
- if (conversation.encryption == Conversation.Encryption.PGP) {
- message.encryption = Entities.Message.Encryption.PGP;
- }
+ out_message_created(message, conversation);
return message;
}
private void send_xmpp_message(Entities.Message message, Conversation conversation, bool delayed = false) {
- Core.XmppStream stream = stream_interactor.get_stream(conversation.account);
- message.marked = Entities.Message.Marked.NONE;
- if (stream != null) {
- Xmpp.Message.Stanza new_message = new Xmpp.Message.Stanza(message.stanza_id);
- new_message.to = message.counterpart.to_string();
- new_message.body = message.body;
- if (conversation.type_ == Conversation.Type.GROUPCHAT) {
- new_message.type_ = Xmpp.Message.Stanza.TYPE_GROUPCHAT;
- } else {
- new_message.type_ = Xmpp.Message.Stanza.TYPE_CHAT;
- }
- if (message.encryption == Entities.Message.Encryption.PGP) {
- string? key_id = PgpManager.get_instance(stream_interactor).get_key_id(conversation.account, message.counterpart);
- if (key_id != null) {
- bool encrypted = stream.get_module(Xep.Pgp.Module.IDENTITY).encrypt(new_message, key_id);
- if (!encrypted) {
- message.marked = Entities.Message.Marked.WONTSEND;
- return;
- }
+ lock (messages) {
+ Core.XmppStream stream = stream_interactor.get_stream(conversation.account);
+ message.marked = Entities.Message.Marked.NONE;
+ if (stream != null) {
+ Xmpp.Message.Stanza new_message = new Xmpp.Message.Stanza(message.stanza_id);
+ new_message.to = message.counterpart.to_string();
+ new_message.body = message.body;
+ if (conversation.type_ == Conversation.Type.GROUPCHAT) {
+ new_message.type_ = Xmpp.Message.Stanza.TYPE_GROUPCHAT;
+ } else {
+ new_message.type_ = Xmpp.Message.Stanza.TYPE_CHAT;
}
+ pre_message_send(message, new_message, conversation);
+ if (message.marked == Entities.Message.Marked.UNSENT || message.marked == Entities.Message.Marked.WONTSEND) return;
+ if (delayed) {
+ stream.get_module(Xmpp.Xep.DelayedDelivery.Module.IDENTITY).set_message_delay(new_message, message.time);
+ }
+ stream.get_module(Xmpp.Message.Module.IDENTITY).send_message(stream, new_message);
+ message.stanza_id = new_message.id;
+ message.stanza = new_message;
+ } else {
+ message.marked = Entities.Message.Marked.UNSENT;
}
- if (delayed) {
- stream.get_module(Xmpp.Xep.DelayedDelivery.Module.IDENTITY).set_message_delay(new_message, message.time);
- }
- stream.get_module(Xmpp.Message.Module.IDENTITY).send_message(stream, new_message);
- message.stanza_id = new_message.id;
- message.stanza = new_message;
- } else {
- message.marked = Entities.Message.Marked.UNSENT;
}
}
}
diff --git a/libdino/src/service/muc_manager.vala b/libdino/src/service/muc_manager.vala
index 8e894211..c3aaa727 100644
--- a/libdino/src/service/muc_manager.vala
+++ b/libdino/src/service/muc_manager.vala
@@ -161,7 +161,7 @@ public class MucManager : StreamInteractionModule, Object {
if (stream != null) stream.get_module(Xep.Bookmarks.Module.IDENTITY).get_conferences(stream, new BookmarksRetrieveResponseListener(this, account));
}
- private void on_pre_message_received(Entities.Message message, Conversation conversation) {
+ private void on_pre_message_received(Entities.Message message, Xmpp.Message.Stanza message_stanza, Conversation conversation) {
if (conversation.type_ != Conversation.Type.GROUPCHAT) return;
Core.XmppStream stream = stream_interactor.get_stream(conversation.account);
if (stream == null) return;
diff --git a/libdino/src/service/pgp_manager.vala b/libdino/src/service/pgp_manager.vala
index c8bf2180..76f70b84 100644
--- a/libdino/src/service/pgp_manager.vala
+++ b/libdino/src/service/pgp_manager.vala
@@ -1,4 +1,5 @@
using Gee;
+using Xmpp;
using Xmpp;
using Dino.Entities;
@@ -16,6 +17,27 @@ namespace Dino {
public static void start(StreamInteractor stream_interactor, Database db) {
PgpManager m = new PgpManager(stream_interactor, db);
stream_interactor.add_module(m);
+ (GLib.Application.get_default() as Application).plugin_registry.register_encryption_list_entry(new EncryptionListEntry(m));
+ }
+
+ private class EncryptionListEntry : Plugins.EncryptionListEntry, Object {
+ private PgpManager pgp_manager;
+
+ public EncryptionListEntry(PgpManager pgp_manager) {
+ this.pgp_manager = pgp_manager;
+ }
+
+ public Entities.Encryption encryption { get {
+ return Encryption.PGP;
+ }}
+
+ public string name { get {
+ return "OpenPGP";
+ }}
+
+ public bool can_encrypt(Entities.Conversation conversation) {
+ return pgp_manager.pgp_key_ids.has_key(conversation.counterpart);
+ }
}
private PgpManager(StreamInteractor stream_interactor, Database db) {
@@ -23,6 +45,27 @@ namespace Dino {
this.db = db;
stream_interactor.account_added.connect(on_account_added);
+ MessageManager.get_instance(stream_interactor).pre_message_received.connect(on_pre_message_received);
+ MessageManager.get_instance(stream_interactor).pre_message_send.connect(on_pre_message_send);
+ }
+
+ private void on_pre_message_received(Entities.Message message, Xmpp.Message.Stanza message_stanza, Conversation conversation) {
+ if (Xep.Pgp.MessageFlag.get_flag(message_stanza) != null && Xep.Pgp.MessageFlag.get_flag(message_stanza).decrypted) {
+ message.encryption = Encryption.PGP;
+ }
+ }
+
+ private void on_pre_message_send(Entities.Message message, Xmpp.Message.Stanza message_stanza, Conversation conversation) {
+ if (message.encryption == Encryption.PGP) {
+ string? key_id = get_key_id(conversation.account, message.counterpart);
+ bool encrypted = false;
+ if (key_id != null) {
+ encrypted = stream_interactor.get_stream(conversation.account).get_module(Xep.Pgp.Module.IDENTITY).encrypt(message_stanza, key_id);
+ }
+ if (!encrypted) {
+ message.marked = Entities.Message.Marked.WONTSEND;
+ }
+ }
}
public string? get_key_id(Account account, Jid jid) {
diff --git a/libdino/src/service/stream_interactor.vala b/libdino/src/service/stream_interactor.vala
index 5965cdd3..c085401a 100644
--- a/libdino/src/service/stream_interactor.vala
+++ b/libdino/src/service/stream_interactor.vala
@@ -64,7 +64,7 @@ public class StreamInteractor {
}
public interface StreamInteractionModule : Object {
- internal abstract string get_id();
+ public abstract string get_id();
}
} \ No newline at end of file
diff --git a/libdino/src/ui/conversation_summary/merged_message_item.vala b/libdino/src/ui/conversation_summary/merged_message_item.vala
index 4957b1a6..fa198d21 100644
--- a/libdino/src/ui/conversation_summary/merged_message_item.vala
+++ b/libdino/src/ui/conversation_summary/merged_message_item.vala
@@ -33,7 +33,7 @@ public class MergedMessageItem : Grid {
string display_name = Util.get_message_display_name(stream_interactor, message, conversation.account);
name_label.set_markup(@"<span foreground=\"#$(Util.get_name_hex_color(display_name))\">$display_name</span>");
Util.image_set_from_scaled_pixbuf(image, (new AvatarGenerator(30, 30, image.scale_factor)).draw_message(stream_interactor, message));
- if (message.encryption == Entities.Message.Encryption.PGP) {
+ if (message.encryption != Encryption.NONE) {
encryption_image.visible = true;
encryption_image.set_from_icon_name("changes-prevent-symbolic", IconSize.SMALL_TOOLBAR);
}
diff --git a/libdino/src/ui/conversation_titlebar.vala b/libdino/src/ui/conversation_titlebar.vala
index 0f34c785..4f472e05 100644
--- a/libdino/src/ui/conversation_titlebar.vala
+++ b/libdino/src/ui/conversation_titlebar.vala
@@ -1,4 +1,5 @@
using Gtk;
+using Gee;
using Dino.Entities;
@@ -12,7 +13,7 @@ public class ConversationTitlebar : Gtk.HeaderBar {
[GtkChild] private MenuButton groupchat_button;
private RadioButton? button_unencrypted;
- private RadioButton? button_pgp;
+ private Map<RadioButton, Plugins.EncryptionListEntry> encryption_radios = new HashMap<RadioButton, Plugins.EncryptionListEntry>();
private StreamInteractor stream_interactor;
private Conversation? conversation;
@@ -36,22 +37,19 @@ public class ConversationTitlebar : Gtk.HeaderBar {
}
private void update_encryption_menu_state() {
- string? pgp_id = PgpManager.get_instance(stream_interactor).get_key_id(conversation.account, conversation.counterpart);
- button_pgp.set_sensitive(pgp_id != null);
- switch (conversation.encryption) {
- case Conversation.Encryption.UNENCRYPTED:
- button_unencrypted.set_active(true);
- break;
- case Conversation.Encryption.PGP:
- button_pgp.set_active(true);
- break;
+ foreach (RadioButton e in encryption_radios.keys) {
+ e.set_sensitive(encryption_radios[e].can_encrypt(conversation));
+ if (conversation.encryption == encryption_radios[e].encryption) e.set_active(true);
+ }
+ if (conversation.encryption == Encryption.NONE) {
+ button_unencrypted.set_active(true);
}
}
private void update_encryption_menu_icon() {
encryption_button.visible = (conversation.type_ == Conversation.Type.CHAT);
if (conversation.type_ == Conversation.Type.CHAT) {
- if (conversation.encryption == Conversation.Encryption.UNENCRYPTED) {
+ if (conversation.encryption == Encryption.NONE) {
encryption_button.set_image(new Image.from_icon_name("changes-allow-symbolic", IconSize.BUTTON));
} else {
encryption_button.set_image(new Image.from_icon_name("changes-prevent-symbolic", IconSize.BUTTON));
@@ -92,25 +90,35 @@ public class ConversationTitlebar : Gtk.HeaderBar {
menu_button.set_menu_model(menu);
}
+ private void encryption_changed() {
+ foreach (RadioButton e in encryption_radios.keys) {
+ if (e.get_active()) {
+ conversation.encryption = encryption_radios[e].encryption;
+ update_encryption_menu_icon();
+ return;
+ }
+ }
+ conversation.encryption = Encryption.NONE;
+ update_encryption_menu_icon();
+ }
+
private void create_encryption_menu() {
Builder builder = new Builder.from_resource("/org/dino-im/menu_encryption.ui");
PopoverMenu menu = builder.get_object("menu_encryption") as PopoverMenu;
+ Box encryption_box = builder.get_object("encryption_box") as Box;
button_unencrypted = builder.get_object("button_unencrypted") as RadioButton;
- button_pgp = builder.get_object("button_pgp") as RadioButton;
+ button_unencrypted.toggled.connect(encryption_changed);
+ Application app = GLib.Application.get_default() as Application;
+ foreach(var e in app.plugin_registry.encryption_list_entries) {
+ RadioButton btn = new RadioButton.with_label(button_unencrypted.get_group(), e.name);
+ encryption_radios[btn] = e;
+ btn.toggled.connect(encryption_changed);
+ btn.visible = true;
+ encryption_box.pack_end(btn, false);
+ }
encryption_button.set_use_popover(true);
encryption_button.set_popover(menu);
encryption_button.set_image(new Image.from_icon_name("changes-allow-symbolic", IconSize.BUTTON));
-
- button_unencrypted.toggled.connect(() => {
- if (conversation != null) {
- if (button_unencrypted.get_active()) {
- conversation.encryption = Conversation.Encryption.UNENCRYPTED;
- } else if (button_pgp.get_active()) {
- conversation.encryption = Conversation.Encryption.PGP;
- }
- update_encryption_menu_icon();
- }
- });
}
private void on_groupchat_subject_set(Account account, Jid jid, string subject) {