diff options
-rw-r--r-- | plugins/omemo/CMakeLists.txt | 3 | ||||
-rw-r--r-- | plugins/omemo/data/contact_details_dialog.ui | 52 | ||||
-rw-r--r-- | plugins/omemo/src/contact_details_dialog.vala | 13 | ||||
-rw-r--r-- | plugins/omemo/vapi/qrencode.vapi | 50 |
4 files changed, 111 insertions, 7 deletions
diff --git a/plugins/omemo/CMakeLists.txt b/plugins/omemo/CMakeLists.txt index 5126d05b..f88abbd5 100644 --- a/plugins/omemo/CMakeLists.txt +++ b/plugins/omemo/CMakeLists.txt @@ -54,6 +54,7 @@ CUSTOM_VAPIS ${CMAKE_BINARY_DIR}/exports/xmpp-vala.vapi ${CMAKE_BINARY_DIR}/exports/qlite.vapi ${CMAKE_BINARY_DIR}/exports/dino.vapi + ${CMAKE_CURRENT_SOURCE_DIR}/vapi/qrencode.vapi PACKAGES ${OMEMO_PACKAGES} GRESOURCES @@ -63,7 +64,7 @@ GRESOURCES add_definitions(${VALA_CFLAGS} -DGETTEXT_PACKAGE=\"${GETTEXT_PACKAGE}\" -DLOCALE_INSTALL_DIR=\"${LOCALE_INSTALL_DIR}\") add_library(omemo SHARED ${OMEMO_VALA_C} ${OMEMO_GRESOURCES_TARGET}) add_dependencies(omemo ${GETTEXT_PACKAGE}-translations) -target_link_libraries(omemo libdino signal-protocol-vala ${OMEMO_PACKAGES}) +target_link_libraries(omemo libdino signal-protocol-vala qrencode ${OMEMO_PACKAGES}) set_target_properties(omemo PROPERTIES PREFIX "") set_target_properties(omemo PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins/) diff --git a/plugins/omemo/data/contact_details_dialog.ui b/plugins/omemo/data/contact_details_dialog.ui index 856c7af4..a5e8511b 100644 --- a/plugins/omemo/data/contact_details_dialog.ui +++ b/plugins/omemo/data/contact_details_dialog.ui @@ -110,6 +110,7 @@ <property name="margin-start">20</property> <property name="margin-end">20</property> <property name="margin-top">14</property> + <property name="spacing">40</property> <property name="margin-bottom">14</property> <property name="orientation">horizontal</property> <property name="hexpand">True</property> @@ -122,14 +123,38 @@ </object> </child> <child> - <object class="GtkButton" id="copy"> + <object class="GtkBox"> <property name="visible">True</property> - <property name="halign">end</property> + <property name="orientation">horizontal</property> + <property name="hexpand">True</property> + <property name="spacing">5</property> <child> - <object class="GtkImage"> + <object class="GtkButton" id="show_qrcode"> <property name="visible">True</property> - <property name="icon-size">1</property> - <property name="icon-name">edit-copy-symbolic</property> + <property name="halign">start</property> + <property name="hexpand">True</property> + <child> + <object class="GtkImage"> + <property name="visible">True</property> + <property name="halign">end</property> + <property name="icon-name">camera-photo-symbolic</property> + <property name="icon-size">1</property> + </object> + </child> + </object> + </child> + <child> + <object class="GtkButton" id="copy"> + <property name="visible">True</property> + <property name="halign">end</property> + <property name="hexpand">True</property> + <child> + <object class="GtkImage"> + <property name="visible">True</property> + <property name="icon-size">1</property> + <property name="icon-name">edit-copy-symbolic</property> + </object> + </child> </object> </child> </object> @@ -203,4 +228,21 @@ </object> </child> </template> + <object class="GtkPopover" id="qrcode_popover"> + <property name="visible">False</property> + <property name="relative-to">show_qrcode</property> + <property name="position">left</property> + <property name="modal">True</property> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="margin">10</property> + <child> + <object class="GtkImage" id="qrcode"> + <property name="visible">True</property> + </object> + </child> + </object> + </child> + </object> </interface> diff --git a/plugins/omemo/src/contact_details_dialog.vala b/plugins/omemo/src/contact_details_dialog.vala index b14a108a..575437ff 100644 --- a/plugins/omemo/src/contact_details_dialog.vala +++ b/plugins/omemo/src/contact_details_dialog.vala @@ -3,6 +3,8 @@ using Xmpp; using Gee; using Qlite; using Dino.Entities; +using Qrencode; +using Gdk; namespace Dino.Plugins.Omemo { @@ -23,6 +25,9 @@ public class ContactDetailsDialog : Gtk.Dialog { [GtkChild] private ListBox keys; [GtkChild] private Switch auto_accept; [GtkChild] private Button copy; + [GtkChild] private Button show_qrcode; + [GtkChild] private Image qrcode; + [GtkChild] private Popover qrcode_popover; private void set_device_trust(Row device, bool trust) { Database.IdentityMetaTable.TrustLevel trust_level = trust ? Database.IdentityMetaTable.TrustLevel.TRUSTED : Database.IdentityMetaTable.TrustLevel.UNTRUSTED; @@ -87,7 +92,7 @@ public class ContactDetailsDialog : Gtk.Dialog { if(row == lbr) { Row updated_device = plugin.db.identity_meta.with_address(device[plugin.db.identity_meta.identity_id], device[plugin.db.identity_meta.address_name]).with(plugin.db.identity_meta.device_id, "=", device[plugin.db.identity_meta.device_id]).single().row().inner; ManageKeyDialog manage_dialog = new ManageKeyDialog(updated_device, plugin.db); - manage_dialog.set_transient_for((Window) get_toplevel()); + manage_dialog.set_transient_for((Gtk.Window) get_toplevel()); manage_dialog.present(); manage_dialog.response.connect((response) => { set_row(response, device[plugin.db.identity_meta.now_active], img, status_lbl, lbl, lbr); @@ -184,6 +189,12 @@ public class ContactDetailsDialog : Gtk.Dialog { own_fingerprint.set_markup(fingerprint_markup(fingerprint)); copy.clicked.connect(() => {Clipboard.get_default(get_display()).set_text(fingerprint, fingerprint.length);}); + + int sid = plugin.db.identity.row_with(plugin.db.identity.account_id, account.id)[plugin.db.identity.device_id]; + Pixbuf pixbuf = new QRcode(@"xmpp:$(account.bare_jid)?omemo-sid-$(sid)=$(fingerprint)", 2).to_pixbuf(); + pixbuf = pixbuf.scale_simple(150, 150, InterpType.NEAREST); + qrcode.set_from_pixbuf(pixbuf); + show_qrcode.clicked.connect(qrcode_popover.popup); } new_keys.set_header_func((row, before_row) => { diff --git a/plugins/omemo/vapi/qrencode.vapi b/plugins/omemo/vapi/qrencode.vapi new file mode 100644 index 00000000..54c201ab --- /dev/null +++ b/plugins/omemo/vapi/qrencode.vapi @@ -0,0 +1,50 @@ +using Gdk; + +[CCode (cheader_filename = "qrencode.h")] +namespace Qrencode { + + [CCode (cname = "QRecLevel", cprefix = "QR_ECLEVEL_")] + public enum ECLevel { + L, + M, + Q, + H + } + + [CCode (cname = "QRencodeMode", cprefix = "QR_MODE_")] + public enum EncodeMode { + NUL, + NUM, + AN, + [CCode (cname = "QR_MODE_8")] + EIGHT_BIT, + KANJI, + STRUCTURE, + ECI, + FNC1FIRST, + FNC1SECOND + } + + [CCode (cname = "QRcode", free_function = "QRcode_free", has_type_id = false)] + [Compact] + public class QRcode { + private int version; + private int width; + [CCode (array_length = false)] + private uint8[] data; + + [CCode (cname = "QRcode_encodeString")] + public QRcode (string str, int version = 0, ECLevel level = ECLevel.L, EncodeMode hint = EncodeMode.EIGHT_BIT, bool casesensitive = true); + + public Pixbuf to_pixbuf() { + uint8[] bitmap = new uint8[3*width*width]; + for (int i = 0; i < width*width; i++) { + uint8 color = (data[i] & 1) == 1 ? 0 : 255; + bitmap[i*3] = color; + bitmap[i*3+1] = color; + bitmap[i*3+2] = color; + } + return new Pixbuf.from_data(bitmap, Colorspace.RGB, false, 8, width, width, width*3); + } + } +} |