Skip to content
Snippets Groups Projects
Commit b986e764 authored by gyan000's avatar gyan000
Browse files

Import code

parents
Branches
No related tags found
No related merge requests found
Showing
with 1646 additions and 0 deletions
i18n.gettext(meson.project_name(),
args: ['--directory='+meson.source_root(), '--from-code=UTF-8']
)
po/uk.po 0 → 100644
# Ukrainian translations for com.github.gyan000.eos-connect package.
# Copyright (C) 2018 THE com.github.gyan000.eos-connect'S COPYRIGHT HOLDER
# This file is distributed under the same license as the com.github.gyan000.eos-connect package.
# Automatically generated, 2018.
#
msgid ""
msgstr ""
"Project-Id-Version: com.github.gyan000.eos-connect\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-06-03 18:05+0200\n"
"PO-Revision-Date: 2018-06-03 16:22+0200\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
"Language: uk\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ASCII\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
#: src/EOSConnect.vala:19 src/EOSConnect.vala:47
msgid "Use dark style"
msgstr ""
#: src/EOSConnect.vala:45
msgid "Use light style"
msgstr ""
#~ msgid "EOS Connect"
#~ msgstr "EOS Connect"
screenshots/devices.png

74.2 KiB

screenshots/sms.png

177 KiB

/**
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* AUTHORS
* gyan000 <gyan000 (at] ijaz.fr>
*/
namespace EOSConnect {
public class Config : Object {
public static string get_config_dir () {
return Path.build_filename (Environment.get_user_config_dir (), App.APP_NAME);
}
public static string create_if_not_exists_config_dir () {
if (File.new_for_path(Config.get_config_dir ()).query_exists () == false) {
DirUtils.create (Config.get_config_dir (), 0700);
}
return Config.get_config_dir ();
}
}
}
/**
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* AUTHORS
* gyan000 <gyan000 (at] ijaz.fr>
*/
namespace EOSConnect {
public class Contact : Object {
public string name { get; private set; }
public string international_phone_number { get; private set; }
public string photo_uri { get; private set; }
public Contact (string name, string international_phone_number, string photo_uri) {
this.name = name;
this.international_phone_number = international_phone_number;
this.photo_uri = photo_uri;
}
}
}
/**
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* AUTHORS
* gyan000 <gyan000 (at] ijaz.fr>
*/
namespace EOSConnect {
public abstract class ContactsInterface : Object {
public SList<Contact> contacts;
public signal void contact_loaded (Contact contact);
public abstract void load_contacts ();
}
}
/**
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* AUTHORS
* gyan000 <gyan000 (at] ijaz.fr>
*/
using MConnect;
namespace EOSConnect {
public class DebugToolbar : Gtk.Grid {
private Views.DevicesView device_view;
private Gtk.Entry text_data_1;
public DebugToolbar (Views.DevicesView device_view) {
this.device_view = device_view;
}
construct {
Gtk.ComboBoxText combo_box_packets = new Gtk.ComboBoxText ();
combo_box_packets.append_text ("telephony - sms");
combo_box_packets.append_text ("telephony - sms2");
combo_box_packets.append_text ("dismiss notification");
combo_box_packets.set_active(0);
combo_box_packets.margin = 10;
text_data_1 = new Gtk.Entry ();
text_data_1.width_request = 100;
text_data_1.margin = 10;
Gtk.Button button_send_packet = new Gtk.Button.with_label ("send packet");
button_send_packet.margin = 10;
// left, top, width = 1, height = 1
attach (combo_box_packets, 0, 0, 1, 1);
attach (text_data_1, 1, 0, 1, 1);
attach (button_send_packet, 2, 0, 1, 1);
button_send_packet.clicked.connect (() => {
switch (combo_box_packets.get_active_text()) {
case "dismiss notification":
dismiss_notification_id ();
break;
case "telephony - sms":
build_and_send_telephony_sms_packet ();
break;
case "telephony - sms2":
build_and_send_telephony_sms_packet2 ();
break;
}
});
}
private Device get_selected_device () {
Widgets.DeviceListBox device_list_box = device_view.device_list_box;
Widgets.DeviceListBoxRow device_list_box_row = ((Widgets.DeviceListBoxRow)device_list_box.get_selected_row ());
return device_list_box_row.device;
}
private void build_and_send_telephony_sms_packet () {
string phone_thumbnail;
try {
FileUtils.get_contents ("/home/share/Développements/vala/eos-connect/data/test/telephony-thumbnail-source.b64", out phone_thumbnail);
} catch (Error e) {
warning ("Unable to load the test phone thumbnail.");
}
var body_builder = new Json.Builder ();
body_builder.begin_object ();
body_builder.set_member_name ("event");
body_builder.add_string_value ("sms");
body_builder.set_member_name ("messageBody");
body_builder.add_string_value ("It's a test message.");
body_builder.set_member_name ("contactName");
body_builder.add_string_value ("John Doe");
body_builder.set_member_name ("phoneThumbnail");
body_builder.add_string_value (phone_thumbnail);
body_builder.set_member_name ("phoneNumber");
body_builder.add_string_value ("+33632769364");
body_builder.end_object ();
var packet = new Packet (TelephonyHandler.TELEPHONY, body_builder.get_root ().get_object (), GLib.Random.next_int ());
info ("%s", packet.to_string ());
Device device = get_selected_device ();
((TelephonyHandler)device.get_path_capability_handler (TelephonyHandler.TELEPHONY)).message (device, packet);
}
private void build_and_send_telephony_sms_packet2 () {
string phone_thumbnail;
try {
FileUtils.get_contents ("/home/share/Développements/vala/eos-connect/data/test/telephony-thumbnail-source2.b64", out phone_thumbnail);
} catch (Error e) {
warning ("Unable to load the test phone thumbnail.");
}
var body_builder = new Json.Builder ();
body_builder.begin_object ();
body_builder.set_member_name ("event");
body_builder.add_string_value ("sms");
body_builder.set_member_name ("messageBody");
body_builder.add_string_value ("Coucou\ndésolé je t'ai un peu oublié :|\n bjldaunizeau@gmail.com\nglopiglopa987\nVoulu\nBiz");
body_builder.set_member_name ("contactName");
body_builder.add_string_value ("Bénédicte DAUNIZEAU");
body_builder.set_member_name ("phoneThumbnail");
body_builder.add_string_value (phone_thumbnail);
body_builder.set_member_name ("phoneNumber");
body_builder.add_string_value ("+33633090940");
body_builder.end_object ();
var packet = new Packet (TelephonyHandler.TELEPHONY, body_builder.get_root ().get_object (), GLib.Random.next_int ());
info ("%s", packet.to_string ());
Device device = get_selected_device ();
((TelephonyHandler)device.get_path_capability_handler (TelephonyHandler.TELEPHONY)).message (device, packet);
}
private void dismiss_notification_id () {
var notification_id = text_data_1.get_text ();
Device device = get_selected_device ();
debug ("Trying to dismiss notification ID %s on device %s", notification_id, device.custom_name);
var body_builder = new Json.Builder ();
body_builder.begin_object ();
body_builder.set_member_name ("cancel");
body_builder.add_string_value (notification_id);
body_builder.end_object ();
var packet = new Packet (
NotificationHandler.NOTIFICATION_REQUEST,
body_builder.get_root ().get_object ()
);
device.send (packet);
}
}
}
/**
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* AUTHORS
* gyan000 <gyan000 (at] ijaz.fr>
*/
namespace EOSConnect {
public class EContacts : ContactsInterface {
private HashTable<string, E.BookClient> _source_client;
private SList<E.Contact> _contacts;
public EContacts () {
_source_client = new HashTable<string, E.BookClient> (str_hash, str_equal);
_contacts = new SList<E.Contact> ();
}
public override void load_contacts () {
_open_sources.begin ();
}
private async void _open_sources () {
try {
var registry = yield new E.SourceRegistry (null);
//registry.source_added.connect (_add_source);
registry.list_sources (E.SOURCE_EXTENSION_ADDRESS_BOOK).foreach ((source) => {
E.SourceAddressBook address_book = (E.SourceAddressBook)source.get_extension (E.SOURCE_EXTENSION_ADDRESS_BOOK);
if(source.enabled == true) {
debug ("Discovered source: '%s' with backend: '%s'",
source.dup_display_name (),
address_book.dup_backend_name ());
_add_source (source);
}
});
} catch (GLib.Error error) {
critical (error.message);
}
}
private void _add_source (E.Source source) {
_add_source_async.begin (source);
}
private async void _add_source_async (E.Source source) {
debug ("Adding source: '%s'", source.dup_display_name ());
try {
var client = yield E.BookClient.connect (source, 30, null);
_source_client.insert (source.dup_uid (), client);
} catch (Error e) {
error (e.message);
}
_load_source (source);
// Idle.add (() => {
// _load_source (source);
// return false;
// });
}
private void _load_source (E.Source source) {
E.BookClient client;
lock (_source_client) {
client = _source_client.get (source.dup_uid ());
}
if (client == null) {
return;
}
try {
debug ("Loading contacts from source: '%s'", source.dup_display_name ());
SList<E.Contact> out_contacts;
client.get_contacts_sync ("", out out_contacts);
foreach (E.Contact contact in out_contacts) {
string phone_number = "";
if (contact.mobile_phone != null) {
phone_number = contact.mobile_phone;
} else if (contact.primary_phone != null) {
phone_number = contact.primary_phone;
}
if(phone_number.length > 8) {
E.PhoneNumber e_phone_number = E.PhoneNumber.from_string (phone_number, null);
E.ContactPhoto contact_photo = contact.@get<E.ContactPhoto> (E.ContactField.PHOTO);
Contact new_contact = new Contact (
contact.full_name,
e_phone_number.to_string (E.PhoneNumberFormat.INTERNATIONAL).replace (" ", ""),
contact_photo == null ? "" : contact_photo.get_uri ());
contacts.append (new_contact);
contact_loaded (new_contact);
}
}
} catch (Error e) {
error (e.message);
}
}
}
}
/**
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* AUTHORS
* gyan000 <gyan000 (at] ijaz.fr>
*/
using EOSConnect.Plugin;
using EOSConnect.Plugin.Windows;
using EOSConnect.Widgets;
using Gee;
using MConnect;
using Unity;
namespace EOSConnect {
public class App : Granite.Application {
public const string APP_NAME="eos-connect";
public const string GSETTINGS_SCHEMA_ID="com.github.gyan000.eos-connect";
public const string GSETTINGS_SCHEMA_PATH="/com/github/gyan000/eos-connect";
public HashMap<string, Device> devices_map;
public ContactsInterface contacts_interface;
private GLib.Settings main_settings;
private SMSHistory sms_history_view;
private MainWindow main_window;
private LauncherEntry launcher_entry;
public App () {
devices_map = new HashMap<string, Device> ();
main_settings = new GLib.Settings (GSETTINGS_SCHEMA_ID);
}
construct {
application_id = App.GSETTINGS_SCHEMA_ID;
flags = ApplicationFlags.FLAGS_NONE;
program_name = "EOS Connect";
build_version = "0.5";
}
public override void activate ()
{
MConnectThread mconnect_thread = new MConnectThread (this, devices_map, main_settings);
launcher_entry = LauncherEntry.get_for_desktop_id (GSETTINGS_SCHEMA_ID + ".desktop");
sms_history_view = new SMSHistory (main_settings, devices_map);
// sms_history_view.delete_event.connect ((event) => {
// // sms_history_view.iconify ();
// return true;
// });
main_window = new MainWindow (this, main_settings, sms_history_view);
main_window.show_all ();
main_window.delete_event.connect ((event) => {
// When from launcher menu is clicked.
if (event.send_event == (int8)0) {
main_window.destroy ();
} else { // When close button from the main window is clicked.
main_window.iconify ();
}
return true;
});
init_sms_store.begin (() => {
init_sms_history_window.begin ();
});
mconnect_thread.devices_updated.connect (() => {
update_launcher_entry.begin ();
main_window.update_ui (devices_map);
sms_history_view.update_available_device_combobox ();
});
mconnect_thread.devices_status_updated.connect (() => {
update_launcher_entry.begin ();
sms_history_view.update_available_device_combobox ();
});
shutdown.connect (() => {
mconnect_thread.shutdown();
});
new Thread<int> ("MConnect Thread", mconnect_thread.run);
}
public static int main (string[] args) {
// Needed for mousepad protocol handler.
Gdk.init (ref args);
// Needed for clipboard sharing.
Gtk.init (ref args);
if (!Thread.supported ()) {
error ("Cannot run without thread support.\n");
}
var application = new App ();
return application.run (args);
}
private async void init_sms_store () {
SMSStore.instance (main_settings);
}
private async void init_sms_history_window () {
SimpleAction simple_action = new SimpleAction ("telephony-open-sms-window-reply", null);
simple_action.activate.connect (() => {
sms_history_view.open_sms_window_reply ();
});
this.add_action (simple_action);
SMSStore.instance ().sms_handled.connect ( (sms) => {
sms_history_view.update_message_ui_adding_sms (sms);
});
SMSStore.instance ().contacts_updated.connect ( (sms_contact_map) => {
sms_history_view.update_ui (sms_contact_map);
});
SMSStore.instance ().contact_updated.connect ((sms_contact) => {
sms_history_view.update_list_box_ui (sms_contact);
});
SMSStore.instance ().refresh_contact_list ();
// sms_history_view.show_all ();
contacts_interface = new EContacts ();
contacts_interface.load_contacts ();
contacts_interface.contact_loaded.connect ((contact ) => {
SMSStore.instance ().merge_contact (contact);
});
sms_history_view.contacts_interface = contacts_interface;
}
private async void update_launcher_entry () {
if (launcher_entry.quicklist == null) {
launcher_entry.quicklist = new Dbusmenu.Menuitem ();
}
foreach (var device_entry in devices_map.entries) {
bool to_add = true;
foreach (var device_menuitem in launcher_entry.quicklist.get_children ()) {
if (((DeviceMenuitem)device_menuitem).id == device_entry.value.device_num) {
((DeviceMenuitem)device_menuitem).update_ui ();
to_add = false;
}
}
if (to_add == true) {
launcher_entry.quicklist.child_append (new DeviceMenuitem.with_device (
device_entry.value, sms_history_view));
}
// var device_menuitem = launcher_entry.quicklist.find_id (device_entry.value.device_num);
// @TOCHECK This condition is not working as expected:
// if (device_menuitem is Dbusmenu.Menuitem) {
// print ("\n[UPDATE DEVICE]================> %i - %s\n", device_entry.value.device_num, device_entry.value.custom_name);
// ((DeviceMenuitem)device_menuitem).update_ui ();
// } else {
// print ("\n[ADD DEVICE]================> %i - %s\n", device_entry.value.device_num, device_entry.value.custom_name);
// launcher_entry.quicklist.child_append (new DeviceMenuitem.with_device (device_entry.value));
// }
}
}
}
}
/**
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* AUTHORS
* gyan000 <gyan000 (at] ijaz.fr>
*/
using EOSConnect.Plugin;
using EOSConnect.Plugin.Windows;
using EOSConnect.Widgets;
using Gee;
using Granite.Widgets;
using MConnect;
namespace EOSConnect {
public class MainWindow : Gtk.ApplicationWindow {
public GLib.Settings main_settings { get; construct; }
public SMSHistory sms_history_view { get; construct; }
private Views.DevicesView devices_view;
// private Gtk.InfoBar infobar_error;
// private Gtk.Label info_bar_error_label;
// private Gtk.Overlay overlay;
// private Granite.Widgets.OverlayBar overlaybar;
public MainWindow (Granite.Application application, GLib.Settings main_settings, SMSHistory sms_history_view) {
Object (
application: application,
main_settings: main_settings,
sms_history_view: sms_history_view
);
set_default_size (900, 600);
set_size_request (750, 500);
}
construct {
var theme_button = new Gtk.Button.from_icon_name ("object-inverse");
theme_button.tooltip_text = _("Use dark style");
theme_button.valign = Gtk.Align.CENTER;
var new_sms_button = new Gtk.Button.from_icon_name ("mail-message-new");
new_sms_button.tooltip_text = _("Send a new SMS");
new_sms_button.valign = Gtk.Align.CENTER;
var headerbar = new Gtk.HeaderBar ();
headerbar.get_style_context ().add_class ("default-decoration");
headerbar.show_close_button = true;
headerbar.pack_start (new_sms_button);
headerbar.pack_end (theme_button);
headerbar.title = "EOS Connect";
set_titlebar (headerbar);
window_position = Gtk.WindowPosition.CENTER;
// infobar_error = new Gtk.InfoBar();
// infobar_error.set_show_close_button(true);
// infobar_error.message_type = Gtk.MessageType.ERROR;
// infobar_error.no_show_all = true;
//
// info_bar_error_label = new Gtk.Label ("");
//
// var info_bar_error_content = infobar_error.get_content_area ();
// info_bar_error_content.add (info_bar_error_label);
devices_view = new Views.DevicesView (this);
var main_settings_view = new Views.MainSettingsView (this, main_settings);
var main_stack = new Gtk.Stack ();
main_stack.expand = true;
main_stack.transition_type = Gtk.StackTransitionType.SLIDE_LEFT_RIGHT;
main_stack.add_titled (devices_view, "devices_view", _("Devices"));
main_stack.add_titled (sms_history_view, "sms_history_view", _("SMS"));
main_stack.add_titled (main_settings_view, "main_settings_view", _("Settings"));
var main_stackswitcher = new Gtk.StackSwitcher ();
main_stackswitcher.set_stack (main_stack);
main_stackswitcher.halign = Gtk.Align.CENTER;
main_stackswitcher.homogeneous = true;
var refresh_in_progress = false;
var sub_grid = new Gtk.Grid ();
sub_grid.orientation = Gtk.Orientation.VERTICAL;
sub_grid.margin = 0;
sub_grid.margin_top = 12;
sub_grid.add (main_stackswitcher);
sub_grid.add (main_stack);
var main_grid = new Gtk.Grid ();
main_grid.orientation = Gtk.Orientation.VERTICAL;
// main_grid.add(infobar_error);
main_grid.add(sub_grid);
// Debug toolbar
if (Granite.Services.Logger.DisplayLevel == Granite.Services.Logger.DEBUG) {
var debug_toolbar = new DebugToolbar (devices_view);
main_grid.add(debug_toolbar);
}
// overlay = new Gtk.Overlay ();
// overlay.add_overlay (main_grid);
Gtk.Settings.get_default ().gtk_application_prefer_dark_theme = main_settings.get_boolean ("use-dark-theme");
// add (overlay);
add (main_grid);
theme_button.clicked.connect (() => {
var window_settings = Gtk.Settings.get_default ();
window_settings.gtk_application_prefer_dark_theme = !window_settings.gtk_application_prefer_dark_theme;
main_settings.set_boolean ("use-dark-theme", window_settings.gtk_application_prefer_dark_theme);
if (window_settings.gtk_application_prefer_dark_theme) {
theme_button.tooltip_text = _("Use light style");
} else {
theme_button.tooltip_text = _("Use dark style");
}
});
// infobar_error.response.connect ((response_id) => {
// infobar_error.no_show_all = true;
// infobar_error.hide ();
// });
new_sms_button.clicked.connect ( () => { sms_history_view.handle_new_sms_button (new_sms_button); });
}
public void update_ui (HashMap<string, Device> devices_map) {
devices_view.update_device_list (devices_map);
}
// public void show_error_infobar (string error_message) {
// if (overlaybar != null) { overlaybar.destroy (); } ;
// infobar_error.no_show_all = false;
// info_bar_error_label.label = "%s".printf (error_message);
// infobar_error.show_all ();
// }
//
// public void hide_overlaybar () {
// if (overlaybar != null) { overlaybar.destroy (); } ;
// }
//
// public void display_overlaybar (string status) {
// overlaybar = new Granite.Widgets.OverlayBar (overlay);
// overlaybar.label = _(status);
// overlaybar.active = true;
// }
}
}
/**
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* AUTHORS
* gyan000 <gyan000(at] ijaz.fr>
*/
namespace EOSConnect {
public class Notification : Object {
public string id { get; private set; }
public string app_name { get; private set; }
public bool is_cancelled { get; private set; }
public bool is_clearable { get; private set; }
public string ticker { get; private set; }
public string title { get; private set; }
public string text { get; private set; }
public int64 time { get; private set; }
public string app_icon { get; private set; }
public bool app_icon_available { get; private set; }
public Notification(
string id,
string app_name,
bool is_cancelled,
bool is_clearable,
string ticker,
string title,
string text,
int64 time,
bool app_icon_available,
string app_icon
) {
this.id = id;
this.app_name = app_name;
this.is_cancelled = is_cancelled;
this.is_clearable = is_clearable;
this.ticker = ticker;
this.title = title;
this.text = text;
this.time = time;
this.app_icon_available = app_icon_available;
this.app_icon = app_icon;
}
}
}
/**
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* AUTHORS
* gyan000 <gyan000 (at] ijaz.fr>
*/
using EOSConnect.Plugin.Popover;
using EOSConnect.Widgets;
using Gee;
using MConnect;
namespace EOSConnect.Plugin {
public class Battery : PluginInterface {
public bool battery_low_level_notify_is_active = true;
public double battery_low_level_notify_treshold = 5;
private BatterySettings _battery_settings_popover;
construct {
name = _("Battery");
icon_name = "battery";
capability_name = BatteryHandler.BATTERY;
description = _("Receive battery information");
settings_key_is_active = "kdeconnect-battery-active";
show_configure_button = true;
}
public override PluginListBoxRow get_plugin_list_box_row (PluginInterface plugin, Device device) {
return new Widgets.BatteryPluginListBoxRow (plugin, device);
}
public override void handle_configure_button (Device device) {
if (_battery_settings_popover == null) {
var _battery_settings_popover = new BatterySettings (device, row_configure_button);
_battery_settings_popover.show_all ();
_battery_settings_popover.destroy.connect (() => {
_battery_settings_popover = null;
});
}
}
}
}
/**
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* AUTHORS
* gyan000 <gyan000 (at] ijaz.fr>
*/
using EOSConnect;
using MConnect;
namespace EOSConnect.Plugin.Dialogs {
public class NotificationSettings : Gtk.Dialog {
public Device device { get; construct; }
private Gtk.ListBox listbox_applications;
private Gtk.Entry filter_listbox_application_entry;
public NotificationSettings (Device device, Gtk.Window? window_parent) {
Object (
border_width: 5,
deletable: false,
resizable: false,
title: _("Notifications settings"),
transient_for: window_parent,
device: device
);
}
construct {
listbox_applications = new Gtk.ListBox ();
Gtk.ScrolledWindow scrolled_window = new Gtk.ScrolledWindow (null, null);
scrolled_window.expand = true;
scrolled_window.hscrollbar_policy = Gtk.PolicyType.NEVER;
scrolled_window.add (listbox_applications);
filter_listbox_application_entry = new Gtk.Entry ();
filter_listbox_application_entry.hexpand = true;
var general_grid = new Gtk.Grid ();
general_grid.column_spacing = 12;
general_grid.row_spacing = 6;
general_grid.attach (new Granite.HeaderLabel (_("General")), 0, 0, 2, 1);
general_grid.attach (new SettingsLabel (_("Receive nofitications")), 0, 1, 1, 1);
general_grid.attach (new SettingsSwitch ("kdeconnect-notifications-receive", this.device), 1, 1, 1, 1);
general_grid.attach (new SettingsLabel (_("Send nofitications")), 0, 2, 1, 1);
general_grid.attach (new SettingsSwitch ("kdeconnect-notifications-send", this.device), 1, 2, 1, 1);
general_grid.attach (new Granite.HeaderLabel (_("Applications")), 0, 3, 2, 1);
general_grid.attach (new SettingsLabel (_("Filter in applications")), 0, 5, 1, 1);
general_grid.attach (filter_listbox_application_entry, 1, 5, 3, 1);
general_grid.attach (scrolled_window, 0, 6, 4, 50);
get_content_area ().add (general_grid);
var close_button = new Gtk.Button.with_label (_("Close"));
close_button.clicked.connect (() => {
listbox_applications = null;
destroy ();
});
add_action_widget (close_button, 0);
listbox_applications.set_filter_func (filter_listbox_applications);
Gtk.IconTheme theme = Gtk.IconTheme.get_default ();
foreach (unowned AppInfo appinfo in AppInfo.get_all ()) {
if ("-device.desktop" in appinfo.get_id ()) {
continue;
}
listbox_applications.insert (
new SettingsListBoxRow (appinfo, theme,
device.settings.get_strv ("kdeconnect-notifications-send-banned"), device), 0);
}
filter_listbox_application_entry.changed.connect (() => {
listbox_applications.invalidate_filter ();
});
}
public bool filter_listbox_applications (Gtk.ListBoxRow row) {
if(filter_listbox_application_entry.text.length == 0) {
return true;
}
if (filter_listbox_application_entry.text.down () in ((SettingsListBoxRow)row).row_name.label.down ()) {
return true;
}
return false;
}
private class SettingsLabel : Gtk.Label {
public SettingsLabel (string text) {
label = text;
halign = Gtk.Align.END;
margin_start = 12;
}
}
private class SettingsSwitch : Gtk.Switch {
public SettingsSwitch (string capability_name, Device device) {
halign = Gtk.Align.START;
valign = Gtk.Align.CENTER;
active = device.settings.get_boolean (capability_name);
device.settings.bind (capability_name, this, "active", SettingsBindFlags.DEFAULT);
this.notify["active"].connect (() => {
if(capability_name == "kdeconnect-notifications-receive") {
((Plugin.Notification)device.plugins_map.@get (NotificationHandler.NOTIFICATION))
.settings_receive_is_active = this.active;
}
else {
((Plugin.Notification)device.plugins_map.@get (NotificationHandler.NOTIFICATION))
.settings_send_is_active = this.active;
}
});
}
}
private class SettingsListBoxRow : Gtk.ListBoxRow {
public Gtk.Label row_name { get; private set; }
public SettingsListBoxRow (
AppInfo appinfo,
Gtk.IconTheme theme,
string[] apps_banned,
Device device) {
row_name = new Gtk.Label (appinfo.get_name ());
Icon? icon = appinfo.get_icon ();
if (icon != null && icon is ThemedIcon) {
Gtk.IconInfo? iconinfo = theme.lookup_by_gicon (icon, 48, 0);
if (iconinfo != null) {
Gtk.Image row_image = new Gtk.Image.from_gicon (icon, Gtk.IconSize.DND);
row_image.pixel_size = 32;
Gtk.Grid row_grid = new Gtk.Grid ();
row_grid.margin = 6;
row_grid.column_spacing = 12;
row_name.xalign = 0;
row_name.get_style_context ().add_class (Granite.STYLE_CLASS_H3_LABEL);
row_name.ellipsize = Pango.EllipsizeMode.END;
row_name.hexpand = true;
row_name.xalign = 0;
Gtk.Switch row_switch = new Gtk.Switch ();
row_switch.tooltip_text = _("Activate / Deactivate this plugin");
row_switch.valign = Gtk.Align.CENTER;
if (appinfo.get_id () in apps_banned) {
row_switch.active = false;
} else {
row_switch.active = true;
}
row_switch.notify["active"].connect (() => {
Plugin.Notification plugin_notification =
(Plugin.Notification)device.plugins_map.@get (NotificationHandler.NOTIFICATION);
string[] temp_apps_banned = device.settings.get_strv ("kdeconnect-notifications-send-banned");
// Dissallow this app to send notification.
if (row_switch.active == false) {
temp_apps_banned += appinfo.get_id ();
plugin_notification.settings_apps_ids_banned.add (appinfo.get_id ());
} else { // Allow this app to send notification.
// @TOCHECK Probably a more efficient way to do that.
Gee.ArrayList<string> new_apps_banned = new Gee.ArrayList<string>.wrap (temp_apps_banned);
if (new_apps_banned.contains (appinfo.get_id ())) {
new_apps_banned.remove (appinfo.get_id ());
plugin_notification.settings_apps_ids_banned.remove (appinfo.get_id ());
}
temp_apps_banned = {};
foreach (string app_banned in new_apps_banned) {
temp_apps_banned += app_banned;
}
new_apps_banned = null;
}
device.settings.set_strv ("kdeconnect-notifications-send-banned", temp_apps_banned);
});
// int left, int top, int width = 1, int height = 1
row_grid.attach (row_image, 0, 0, 1, 2);
row_grid.attach (row_name, 1, 0, 1, 1);
row_grid.attach (row_switch, 3, 0, 1, 2);
add (row_grid);
}
}
}
}
}
}
/**
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* AUTHORS
* gyan000 <gyan000 (at] ijaz.fr>
*/
using EOSConnect;
namespace EOSConnect.Plugin.Dialogs {
public class ShareFileInfoProgress : Gtk.Dialog {
private Gtk.ListBox listbox_files;
public unowned SList<string> uris { get; construct; }
public ShareFileInfoProgress (SList<string> uris, Gtk.Window? window_parent) {
Object (
border_width: 5,
deletable: false,
resizable: true,
title: _("File uploads"),
transient_for: window_parent,
uris: uris
);
}
construct {
width_request = 500;
height_request = 350;
listbox_files = new Gtk.ListBox ();
var scrolled_window = new Gtk.ScrolledWindow (null, null);
scrolled_window.expand = true;
scrolled_window.hscrollbar_policy = Gtk.PolicyType.NEVER;
scrolled_window.add (listbox_files);
int num_file = 0;
foreach (unowned string uri in uris) {
listbox_files.insert (
new ProgressFileListBoxRow (uri), ++num_file
);
}
get_content_area ().add (scrolled_window);
add_button ("C_ancel", Gtk.ResponseType.CANCEL);
add_button ("_Close", Gtk.ResponseType.CLOSE);
response.connect (on_response);
show_all ();
}
public void update_progress (int file_num, double progress_percentage) {
ProgressFileListBoxRow box_row = (ProgressFileListBoxRow)listbox_files.get_row_at_index (file_num);
if(box_row == null) {
return;
}
if (progress_percentage < 0) {
box_row.progress_bar.pulse ();
}
else {
box_row.progress_bar.set_fraction (progress_percentage);
}
}
private void on_response (Gtk.Dialog source, int response_id) {
switch (response_id) {
case Gtk.ResponseType.CLOSE:
destroy ();
break;
case Gtk.ResponseType.CANCEL:
// TODO - implement upload cancel.
warning ("Cancel operation not yet implemented.");
destroy ();
break;
}
}
private class ProgressFileListBoxRow : Gtk.ListBoxRow {
public Gtk.ProgressBar progress_bar;
public ProgressFileListBoxRow (string uri) {
var vbox = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
vbox.margin = 5;
progress_bar = new Gtk.ProgressBar ();
progress_bar.pulse_step = 0.05;
vbox.pack_start (progress_bar, true, false, 0);
var details = new Gtk.Label (File.new_for_uri (uri).get_path ());
details.set_line_wrap (true);
details.set_alignment ((float) 0.0, (float) 0.5);
vbox.pack_start (details, true, false, 0);
add (vbox);
}
}
}
}
/**
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* AUTHORS
* gyan000 <gyan000 (at] ijaz.fr>
*/
using EOSConnect.Plugin.Dialogs;
using Gee;
using MConnect;
namespace EOSConnect.Plugin {
public class @Notification : PluginInterface {
public bool settings_receive_is_active = true;
public bool settings_send_is_active = true;
public ArrayList<string> settings_apps_ids_banned;
private NotificationSettings notification_settings_dialog;
construct {
name = _("Notification");
icon_name = "dialog-information";
capability_name = NotificationHandler.NOTIFICATION;
description = _("Setup notification to send or received.");
settings_key_is_active = "kdeconnect-notification-active";
show_configure_button = true;
}
public override void handle_configure_button (Device device) {
if (notification_settings_dialog == null) {
notification_settings_dialog = new Plugin.Dialogs.NotificationSettings(device, parent_window);
notification_settings_dialog.show_all ();
notification_settings_dialog.destroy.connect (() => {
notification_settings_dialog = null;
});
}
notification_settings_dialog.present ();
}
}
}
/**
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* AUTHORS
* gyan000 <gyan000 (at] ijaz.fr>
*/
using EOSConnect.Widgets;
using EOSConnect.Plugin;
using MConnect;
namespace EOSConnect.Plugin {
public class Ping : PluginInterface {
construct {
name = _("Ping");
icon_name = "network-transmit-receive";
capability_name = PingHandler.PING;
description = _("Send or receive a ping.");
settings_key_is_active = "kdeconnect-ping-active";
}
public override PluginListBoxRow get_plugin_list_box_row (PluginInterface plugin, Device device) {
return new Widgets.PingPluginListBoxRow (plugin, device);
}
}
}
/**
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* AUTHORS
* gyan000 <gyan000 (at] ijaz.fr>
*/
using EOSConnect.Widgets;
using MConnect;
namespace EOSConnect.Plugin {
public abstract class PluginInterface : GLib.Object {
public string name { get; protected set; }
public string icon_name { get; protected set; default = "info"; }
public string capability_name { get; protected set; }
public string description { get; protected set; }
public bool is_active = true;
public bool show_configure_button = false;
public string settings_key_is_active { get; protected set; }
public GLib.Application? application { protected get; public set; }
public Gtk.Window? parent_window { protected get; public set; }
public Gtk.Button? row_configure_button { protected get; public set; }
public virtual void init () {
info ("Plugin %s do not have configuration window.", name);
}
public virtual PluginListBoxRow get_plugin_list_box_row (PluginInterface plugin, Device device) {
return new PluginListBoxRow (plugin, device);
}
public virtual void handle_configure_button (Device device) {
info ("Plugin %s do not have configuration window.", name);
}
}
}
/**
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* AUTHORS
* gyan000 <gyan000 (at] ijaz.fr>
*/
using EOSConnect;
using MConnect;
namespace EOSConnect.Plugin.Popover {
public class BatterySettings : Gtk.Popover {
public Device device { get; construct; }
public BatterySettings (Device device, Gtk.Widget? relative_to) {
Object (
device: device,
relative_to: relative_to,
modal: true,
position: Gtk.PositionType.BOTTOM
);
}
construct {
var battery_icon = new Gtk.Image.from_icon_name ("battery-caution", Gtk.IconSize.DND);
battery_icon.pixel_size = 64;
battery_icon.margin = 5;
battery_icon.sensitive = device.settings.get_boolean ("kdeconnect-battery-notify-low-level-active");
var desc_label = new Granite.HeaderLabel (_("Notify when battery charge level is low"));
var charge_label = new Gtk.Label (_("Charge percentage"));
charge_label.halign = Gtk.Align.START;
charge_label.margin = 10;
charge_label.sensitive = device.settings.get_boolean ("kdeconnect-battery-notify-low-level-active");
var charge_battery_spin = new Gtk.SpinButton.with_range (
(double)1, (double)99, (double)1);
charge_battery_spin.halign = Gtk.Align.CENTER;
charge_battery_spin.hexpand = false;
charge_battery_spin.margin = 10;
charge_battery_spin.value = device.settings.get_double("kdeconnect-battery-low-level-treshold");
device.settings.bind ("kdeconnect-battery-low-level-treshold", charge_battery_spin,
"value", SettingsBindFlags.DEFAULT);
var activation_switch = new Gtk.Switch ();
activation_switch.tooltip_text = _("Activate / Deactivate battery alert");
activation_switch.halign = Gtk.Align.END;
activation_switch.hexpand = false;
activation_switch.margin = 10;
device.settings.bind ("kdeconnect-battery-notify-low-level-active", activation_switch,
"active", SettingsBindFlags.DEFAULT);
charge_battery_spin.sensitive = device.settings.get_boolean ("kdeconnect-battery-notify-low-level-active");
// left, top, width, height1
var grid = new Gtk.Grid ();
grid.attach (battery_icon, 0, 0, 1, 3);
grid.attach (desc_label, 1, 0, 3, 1);
grid.attach (charge_label, 1, 1, 1, 1);
grid.attach (charge_battery_spin, 2, 1, 1, 1);
grid.attach (activation_switch, 3, 1, 1, 1);
add (grid);
activation_switch.notify["active"].connect( () => {
((Plugin.Battery)device.plugins_map.@get (BatteryHandler.BATTERY))
.battery_low_level_notify_is_active = activation_switch.active;
battery_icon.sensitive = activation_switch.active;
charge_label.sensitive = activation_switch.active;
charge_battery_spin.sensitive = activation_switch.active;
});
charge_battery_spin.notify["value"].connect( () => {
((Plugin.Battery)device.plugins_map.@get (BatteryHandler.BATTERY))
.battery_low_level_notify_treshold = charge_battery_spin.value;
});
}
}
}
/**
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* AUTHORS
* gyan000 <gyan000 (at] ijaz.fr>
*/
using EOSConnect;
using EOSConnect.Plugin.Widgets;
using Gee;
using MConnect;
namespace EOSConnect.Plugin.Popover {
public class SMSNewMessageNewContact : Gtk.Popover {
public ContactsInterface contacts_interface { get; construct; }
public HashMap<string, Device> devices_map { get; construct; }
private Gtk.ListBox list_box;
private SMSTextEntry text_entry;
public SMSNewMessageNewContact (
Gtk.Widget? relative_to,
ContactsInterface contacts_interface,
HashMap<string, Device> devices_map
) {
Object (
relative_to: relative_to,
modal: true,
position: Gtk.PositionType.BOTTOM,
contacts_interface: contacts_interface,
devices_map: devices_map
);
}
construct {
height_request = 200;
width_request = 400;
list_box = new Gtk.ListBox ();
text_entry = new SMSTextEntry (devices_map);
text_entry.entrytext_view.vexpand = true;
text_entry.message_to_send.connect ((message, device) => { send_message (message, device); });
var main_stack = new Gtk.Stack ();
main_stack.expand = true;
main_stack.transition_type = Gtk.StackTransitionType.SLIDE_LEFT_RIGHT;
main_stack.add_titled (new SelectContactStackView (contacts_interface, list_box), "select_contact_view", _("Contacts"));
main_stack.add_titled (text_entry, "text_entry_view", _("Message"));
var main_stackswitcher = new Gtk.StackSwitcher ();
main_stackswitcher.set_stack (main_stack);
main_stackswitcher.halign = Gtk.Align.CENTER;
main_stackswitcher.homogeneous = true;
var grid = new Gtk.Grid ();
grid.orientation = Gtk.Orientation.VERTICAL;
grid.margin = 5;
grid.add (main_stackswitcher);
grid.add (main_stack);
add (grid);
}
public void update_combo_box_devices () {
text_entry.update_combo_box_devices ();
}
private void send_message (string message, Device device) {
SMS sms = new SMS (
message,
SMS.FROM_ME,
SMS.FROM_TYPE_EOSCONNECT,
new DateTime.now_utc ());
if (device.has_capability_handler (TelephonyHandler.TELEPHONY) ) {
int count = 0;
list_box.@foreach (() => {
ContactListBoxRow clbw = (ContactListBoxRow)list_box.get_row_at_index (count);
((TelephonyHandler)device.get_path_capability_handler(TelephonyHandler.TELEPHONY))
.send_sms (device, clbw.contact.international_phone_number, message);
SMSStore.instance ().add_sms (
device,
sms,
new SMSContact (
clbw.contact.international_phone_number,
clbw.contact.name,
device.id,
"",
clbw.contact.name
));
count++;
});
}
}
private class SelectContactStackView : Gtk.Box {
public SelectContactStackView (ContactsInterface contacts_interface, Gtk.ListBox list_box) {
var scrolled_window = new Gtk.ScrolledWindow (null, null);
scrolled_window.expand = true;
scrolled_window.hscrollbar_policy = Gtk.PolicyType.NEVER;
list_box.margin = 5;
list_box.selection_mode = Gtk.SelectionMode.NONE;
scrolled_window.add (list_box);
var search_entry = new Gtk.SearchEntry();
search_entry.margin = 5;
search_entry.placeholder_text = _("Search a contact or enter a phone number");
var list_store = new Gtk.ListStore(2, typeof(string), typeof(Contact));
Gtk.TreeIter iter;
foreach (Contact contact in contacts_interface.contacts) {
list_store.append(out iter);
list_store.set(iter, 0, contact.name, 1, contact);
}
var entry_completion = new Gtk.EntryCompletion();
entry_completion.model = list_store;
entry_completion.text_column = 0;
entry_completion.popup_completion = true;
search_entry.set_completion(entry_completion);
entry_completion.match_selected.connect( (model, iter) => {
GLib.Value name;
GLib.Value contact;
list_store.get_value (iter, 0, out name);
list_store.get_value (iter, 1, out contact);
bool insert = true;
int count = 0;
list_box.@foreach (() => {
ContactListBoxRow clbw = (ContactListBoxRow)list_box.get_row_at_index (count);
if (((Contact)contact).international_phone_number == clbw.contact.international_phone_number) {
insert = false;
}
});
if (insert == true) {
list_box.insert (new ContactListBoxRow ((Contact)contact), -1);
}
return true;
});
// left, top, width, height
var grid = new Gtk.Grid ();
grid.margin = 5;
grid.attach (search_entry, 0, 0, 1, 1);
grid.attach (scrolled_window, 0, 1, 1, 2);
add (grid);
}
}
private class ContactListBoxRow : Gtk.ListBoxRow {
public Contact contact;
public ContactListBoxRow (Contact contact) {
this.contact = contact;
var grid = new Gtk.Grid ();
grid.margin = 6;
grid.column_spacing = 6;
var avatar = new Granite.Widgets.Avatar ();
if (contact.photo_uri.length > 10) {
try {
var size = 32 * get_style_context ().get_scale ();
var avatar_pixbuf = new Gdk.Pixbuf.from_file_at_scale (
File.new_for_uri(contact.photo_uri).get_path (), size, size, false);
avatar.pixbuf = avatar_pixbuf;
} catch (Error e) {
warning ("Error: %s", e.message);
avatar.show_default (32);
}
} else {
avatar.show_default (32);
}
var contact_name_label = new Gtk.Label (contact.name);
contact_name_label.get_style_context ().add_class (Granite.STYLE_CLASS_H3_LABEL);
contact_name_label.ellipsize = Pango.EllipsizeMode.END;
contact_name_label.halign = Gtk.Align.START;
contact_name_label.valign = Gtk.Align.START;
var contact_phone_number = new Gtk.Label (contact.international_phone_number);
contact_phone_number.margin_top = 2;
contact_phone_number.use_markup = true;
contact_phone_number.ellipsize = Pango.EllipsizeMode.END;
contact_phone_number.halign = Gtk.Align.START;
contact_phone_number.valign = Gtk.Align.START;
var box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
box.pack_start (contact_phone_number, false, false, 0);
grid.attach (avatar, 0, 0, 1, 2);
grid.attach (contact_name_label, 1, 0, 1, 1);
grid.attach (box, 1, 1, 1, 1);
add (grid);
show_all ();
}
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment