1// -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*- 2/*- 3 * Copyright (c) 2011-2018 elementary, Inc. (https://elementary.io) 4 * 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, either version 3 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 * Authored by: Maxwell Barvian <maxwell@elementary.io> 19 * Corentin Noël <corentin@elementary.io> 20 */ 21 22namespace Maya { 23 namespace Option { 24 private static bool add_event = false; 25 private static string show_day = null; 26 } 27 28 public class Application : Gtk.Application { 29 public MainWindow window; 30 public static GLib.Settings? saved_state = null; 31 public static GLib.Settings? wingpanel_settings = null; 32 public static bool run_in_background = false; 33 34 static construct { 35 if (SettingsSchemaSource.get_default ().lookup ("io.elementary.calendar.savedstate", true) != null) { 36 saved_state = new GLib.Settings ("io.elementary.calendar.savedstate"); 37 } 38 39 if (GLib.SettingsSchemaSource.get_default ().lookup ("io.elementary.desktop.wingpanel.datetime", true) != null) { 40 wingpanel_settings = new GLib.Settings ("io.elementary.desktop.wingpanel.datetime"); 41 } 42 } 43 44 construct { 45 flags |= ApplicationFlags.HANDLES_OPEN; 46 47 application_id = Build.EXEC_NAME; 48 49 GLib.Intl.setlocale (LocaleCategory.ALL, ""); 50 GLib.Intl.bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); 51 GLib.Intl.bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); 52 GLib.Intl.textdomain (GETTEXT_PACKAGE); 53 54 var provider = new Gtk.CssProvider (); 55 provider.load_from_resource ("/io/elementary/calendar/Application.css"); 56 Gtk.StyleContext.add_provider_for_screen (Gdk.Screen.get_default (), provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); 57 } 58 59 public const OptionEntry[] APP_OPTIONS = { 60 { "add-event", 'a', 0, OptionArg.NONE, out Option.add_event, N_("Create an event"), null }, 61 { "show-day", 's', 0, OptionArg.STRING, out Option.show_day, N_("Focus the given day"), N_("date") }, 62 { "background", 'b', 0, OptionArg.NONE, out run_in_background, "Run the Application in background", null}, 63 { null } 64 }; 65 66 protected override void activate () { 67 if (run_in_background) { 68 run_in_background = false; 69 new Calendar.TodayEventMonitor (); 70 hold (); 71 return; 72 } 73 74 if (get_windows () != null) { 75 get_windows ().data.present (); // present window if app is already running 76 return; 77 } 78 79 if (Option.show_day != null) { 80 var date = Date (); 81 date.set_parse (Option.show_day); 82 if (date.valid () == true) { 83 var datetime = get_selected_datetime (); 84 datetime = datetime.add_years ((int)date.get_year () - datetime.get_year ()); 85 datetime = datetime.add_days ((int)date.get_day_of_year () - datetime.get_day_of_year ()); 86 87 saved_state.set_string ("selected-day", datetime.format ("%Y-%j")); 88 saved_state.set_string ("month-page", datetime.format ("%Y-%m")); 89 } else { 90 warning ("Invalid date '%s' - Ignoring", Option.show_day); 91 } 92 } 93 94 var calmodel = Calendar.EventStore.get_default (); 95 calmodel.load_all_sources (); 96 97 init_gui (); 98 window.show_all (); 99 100 if (Option.add_event) { 101 Idle.add (() => { 102 window.on_tb_add_clicked (window.calview.selected_date); 103 return false; 104 }); 105 } 106 107 var granite_settings = Granite.Settings.get_default (); 108 var gtk_settings = Gtk.Settings.get_default (); 109 110 gtk_settings.gtk_application_prefer_dark_theme = granite_settings.prefers_color_scheme == Granite.Settings.ColorScheme.DARK; 111 112 granite_settings.notify["prefers-color-scheme"].connect (() => { 113 gtk_settings.gtk_application_prefer_dark_theme = granite_settings.prefers_color_scheme == Granite.Settings.ColorScheme.DARK; 114 }); 115 } 116 117 public override void open (File[] files, string hint) { 118 if (get_windows () == null) { 119 var calmodel = Calendar.EventStore.get_default (); 120 calmodel.load_all_sources (); 121 122 init_gui (); 123 window.show_all (); 124 } else { 125 get_windows ().data.present (); // present window if app is already running 126 } 127 128 var dialog = new Maya.View.ImportDialog (files); 129 dialog.transient_for = window; 130 dialog.show_all (); 131 } 132 133 /** 134 * Initializes the graphical window and its components 135 */ 136 void init_gui () { 137 int window_x, window_y; 138 var rect = Gtk.Allocation (); 139 140 saved_state.get ("window-position", "(ii)", out window_x, out window_y); 141 saved_state.get ("window-size", "(ii)", out rect.width, out rect.height); 142 143 window = new MainWindow (this); 144 window.title = _(Build.APP_NAME); 145 window.set_allocation (rect); 146 147 if (window_x != -1 || window_y != -1) { 148 window.move (window_x, window_y); 149 } 150 151 if (saved_state.get_boolean ("window-maximized")) { 152 window.maximize (); 153 } 154 155 window.destroy.connect (on_quit); 156 157 var quit_action = new SimpleAction ("quit", null); 158 quit_action.activate.connect (() => { 159 if (window != null) { 160 window.destroy (); 161 } 162 }); 163 164 add_action (quit_action); 165 set_accels_for_action ("app.quit", { "<Control>q" }); 166 } 167 168 private void on_quit () { 169 Calendar.EventStore.get_default ().delete_trashed_calendars (); 170 } 171 172 public static DateTime get_selected_datetime () { 173 var selected_day = saved_state.get_string ("selected-day"); 174 if (selected_day == null || selected_day == "") { 175 return new DateTime.now_local (); 176 } 177 178 var numbers = selected_day.split ("-", 2); 179 var dt = new DateTime.local (int.parse (numbers[0]), 1, 1, 0, 0, 0); 180 dt = dt.add_days (int.parse (numbers[1]) - 1); 181 return dt; 182 } 183 } 184 185 public static int main (string[] args) { 186 var context = new OptionContext (_("Calendar")); 187 context.add_main_entries (Application.APP_OPTIONS, "maya"); 188 context.add_group (Gtk.get_option_group (true)); 189 190 try { 191 context.parse (ref args); 192 } catch (Error e) { 193 warning (e.message); 194 } 195 196 GtkClutter.init (ref args); 197 var app = new Application (); 198 199 return app.run (args); 200 } 201} 202