/* -*- Mode: vala; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 8 -*- */ /* * Copyright (C) 2011 Alexander Larsson * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * 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, see . */ using Gtk; using Folks; public class Contacts.App : Gtk.Application { public static App app; public GLib.Settings settings; /* moving creation to Window */ public Store contacts_store; public Contacts.Window window; private bool is_prepare_scheluded = false; private bool is_quiescent_scheduled = false; public void show_contact (Contact? contact) { window.set_shown_contact (contact); } public async void show_individual (string id) { var contact = yield contacts_store.find_contact ( (c) => { return c.individual.id == id; }); if (contact != null) { show_contact (contact); } else { var dialog = new MessageDialog (App.app.window, DialogFlags.DESTROY_WITH_PARENT, MessageType.ERROR, ButtonsType.CLOSE, _("No contact with id %s found"), id); dialog.set_title(_("Contact not found")); dialog.show (); dialog.response.connect ( (id) => { dialog.destroy (); }); } } public void change_address_book () { var dialog = new Dialog.with_buttons (_("Change Address Book"), (Window) window, DialogFlags.MODAL | DialogFlags.DESTROY_WITH_PARENT | DialogFlags.USE_HEADER_BAR, _("Change"), ResponseType.OK, _("Cancel"), ResponseType.CANCEL, null); var ok_button = dialog.get_widget_for_response (ResponseType.OK); ok_button.sensitive = false; ok_button.get_style_context ().add_class ("suggested-action"); dialog.set_resizable (false); dialog.set_border_width (12); var explanation_label = new Label (_("New contacts will be added to the selected address book.\nYou are able to view and edit contacts from other address books.")); (dialog.get_content_area () as Box).add (explanation_label); (dialog.get_content_area () as Box).set_spacing (12); var acc = new AccountsList (); acc.update_contents (true); ulong active_button_once = 0; active_button_once = acc.account_selected.connect (() => { ok_button.sensitive = true; acc.disconnect (active_button_once); }); ulong stores_changed_id = contacts_store.eds_persona_store_changed.connect ( () => { acc.update_contents (true); }); (dialog.get_content_area () as Box).add (acc); dialog.show_all (); dialog.response.connect ( (response) => { if (response == ResponseType.OK) { var e_store = acc.selected_store as Edsf.PersonaStore; if (e_store != null) { eds_source_registry.set_default_address_book (e_store.source); var settings = new GLib.Settings ("org.freedesktop.folks"); settings.set_string ("primary-store", "eds:%s".printf(e_store.id)); contacts_store.refresh (); } } contacts_store.disconnect (stores_changed_id); dialog.destroy (); }); } public void show_help () { try { Gtk.show_uri (window.get_screen (), "help:gnome-help/contacts", Gtk.get_current_event_time ()); } catch (GLib.Error e1) { warning ("Error showing help: %s", e1.message); } } public void show_about () { string[] authors = { "Alexander Larsson ", "Erick Pérez Castellanos " }; string[] artists = { "Allan Day " }; Gtk.show_about_dialog (window, "artists", artists, "authors", authors, "translator-credits", _("translator-credits"), "program-name", _("GNOME Contacts"), "title", _("About GNOME Contacts"), "comments", _("Contact Management Application"), "copyright", "Copyright 2011 Red Hat, Inc.\nCopyright 2014 The Contacts Developers", "license-type", Gtk.License.GPL_2_0, "logo-icon-name", "x-office-address-book", "version", Config.PACKAGE_VERSION, "website", "https://wiki.gnome.org/Apps/Contacts", "wrap-license", true); } public async void show_by_email (string email_address) { var contact = yield contacts_store.find_contact ( (c) => { return c.has_email (email_address); }); if (contact != null) { show_contact (contact); } else { var dialog = new MessageDialog (App.app.window, DialogFlags.DESTROY_WITH_PARENT, MessageType.ERROR, ButtonsType.CLOSE, _("No contact with email address %s found"), email_address); dialog.set_title(_("Contact not found")); dialog.show (); dialog.response.connect ( (id) => { dialog.destroy (); }); } } public void show_search (string query) { if (contacts_store.is_quiescent) { window.show_search (query); } else { contacts_store.quiescent.connect_after (() => { window.show_search (query); }); } } private void create_app_menu () { var action = new GLib.SimpleAction ("quit", null); action.activate.connect (() => { this.quit (); }); this.add_action (action); action = new GLib.SimpleAction ("help", null); action.activate.connect (() => { show_help (); }); this.add_action (action); this.add_accelerator ("F1", "app.help", null); action = new GLib.SimpleAction ("about", null); action.activate.connect (() => { show_about (); }); this.add_action (action); action = new GLib.SimpleAction ("change_book", null); action.activate.connect (() => { change_address_book (); }); this.add_action (action); action = new GLib.SimpleAction ("new_contact", null); action.activate.connect (() => { new_contact (); }); this.add_action (action); this.add_accelerator ("n", "app.new_contact", null); var builder = load_ui ("app-menu.ui"); set_app_menu ((MenuModel)builder.get_object ("app-menu")); } private void create_window () { window = new Contacts.Window (this, contacts_store); } private void schedule_window_creation () { /* window creation code is run after Store::prepare */ hold (); ulong id = 0; uint id2 = 0; id = contacts_store.prepared.connect (() => { contacts_store.disconnect (id); Source.remove (id2); create_app_menu (); create_window (); window.show (); schedule_window_finish_ui (); release (); }); // Wait at most 0.5 seconds to show the window id2 = Timeout.add (500, () => { contacts_store.disconnect (id); create_app_menu (); create_window (); window.show (); schedule_window_finish_ui (); release (); return false; }); is_prepare_scheluded = true; } private void schedule_window_finish_ui () { /* make window swap spinner out and init Contacts.ListView */ // We delay the initial show a tiny bit so most contacts are loaded when we show ulong id = 0; uint id2 = 0; id = contacts_store.quiescent.connect (() => { Source.remove (id2); contacts_store.disconnect (id); debug ("callign set_list_pane from quiescent.connect"); window.set_list_pane (); }); // Wait at most 0.5 seconds to show the window id2 = Timeout.add (500, () => { contacts_store.disconnect (id); debug ("callign set_list_pane from 500.timeout"); window.set_list_pane (); return false; }); is_quiescent_scheduled = true; } public override void startup () { ensure_eds_accounts (); contacts_store = new Store (); base.startup (); var css_provider = load_css ("style.css"); Gtk.StyleContext.add_provider_for_screen (Gdk.Screen.get_default(), css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); } public override void activate () { /* window creation code */ if (window == null) { if (!contacts_store.is_prepared) { if (!is_prepare_scheluded) { schedule_window_creation (); return; } } create_app_menu (); create_window (); window.show (); } if (contacts_store.is_quiescent) { debug ("callign set_list_pane cause store is already quiescent"); window.set_list_pane (); } else if (!is_quiescent_scheduled) { schedule_window_finish_ui (); } if (window != null) window.present (); } public void show_message (string message) { var notification = new Gd.Notification (); notification.timeout = 5; var g = new Grid (); g.set_column_spacing (8); var l = new Label (message); l.set_line_wrap (true); l.set_line_wrap_mode (Pango.WrapMode.WORD_CHAR); notification.add (l); notification.show_all (); window.add_notification (notification); } public void new_contact () { window.new_contact (); } private static string individual_id = null; private static string email_address = null; private static string search_terms = null; private static const OptionEntry[] options = { { "individual", 'i', 0, OptionArg.STRING, ref individual_id, N_("Show contact with this individual id"), null }, { "email", 'e', 0, OptionArg.STRING, ref email_address, N_("Show contact with this email address"), null }, { "search", 's', 0, OptionArg.STRING, ref search_terms, null, null }, { null } }; public override int command_line (ApplicationCommandLine command_line) { var args = command_line.get_arguments (); unowned string[] _args = args; var context = new OptionContext (N_("— contact management")); context.add_main_entries (options, Config.GETTEXT_PACKAGE); context.set_translation_domain (Config.GETTEXT_PACKAGE); context.add_group (Gtk.get_option_group (true)); individual_id = null; email_address = null; search_terms = null; try { context.parse (ref _args); } catch (Error e) { printerr ("Unable to parse: %s\n", e.message); return 1; } activate (); if (individual_id != null) app.show_individual.begin (individual_id); if (email_address != null) app.show_by_email.begin (email_address); if (search_terms != null) app.show_search (search_terms); return 0; } public static PersonaStore[] get_eds_address_books () { PersonaStore[] stores = {}; foreach (var backend in app.contacts_store.backend_store.enabled_backends.values) { foreach (var persona_store in backend.persona_stores.values) { if (persona_store.type_id == "eds") { stores += persona_store; } } } return stores; } public App () { Object (application_id: "org.gnome.Contacts", flags: ApplicationFlags.HANDLES_COMMAND_LINE); app = this; settings = new GLib.Settings ("org.gnome.Contacts"); } }