/* This file is part of Beifahrer. * * Copyright (C) 2010 Philipp Zabel * * Beifahrer 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 3 of the License, or * (at your option) any later version. * * Beifahrer 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 Beifahrer. If not, see . */ using Gtk; using Hildon; public class QueryWindow : StackableWindow { public const string GCONF_KEY_ARRIVAL = "/apps/beifahrer/arrival"; public const string GCONF_KEY_DEPARTURE = "/apps/beifahrer/departure"; public const string GCONF_KEY_USE_LOCATION = "/apps/beifahrer/use_location"; AdacMitfahrclub adac; CityButton departure_button; CityButton arrival_button; DateButton date; TouchSelector tolerance_selector; Location.GPSDControl control; Location.GPSDevice device; GConf.Client gconf; bool use_location = true; bool want_location; construct { set_title ("Beifahrer"); var menu = new AppMenu (); var settings = new Gtk.Button.with_label (_("Settings")); settings.show (); menu.append (settings); set_main_menu (menu); adac = new AdacMitfahrclub (); gconf = GConf.Client.get_default (); tolerance_selector = new TouchSelector.text (); for (int days = 0; days <= 4; days += 1) tolerance_selector.append_text (_("+/- %d days").printf (days)); var alignment = new Alignment (0.0f, 0.0f, 1.0f, 1.0f); alignment.top_padding = MARGIN_HALF; alignment.left_padding = MARGIN_DOUBLE; alignment.right_padding = MARGIN_DOUBLE; var table = new Table (5, 2, false); departure_button = new CityButton (SizeType.FINGER_HEIGHT, ButtonArrangement.VERTICAL, adac.get_city_list ()); departure_button.set_title (_("Departure")); departure_button.set_value (_("Please select")); departure_button.set_alignment (0.0f, 0.0f, 0.5f, 0.5f); table.attach (departure_button, 0, 2, 0, 1, AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.FILL, 0, 0); try { departure_button.set_active (gconf.get_int ("/apps/beifahrer/departure")); } catch (Error e) { } arrival_button = new CityButton (SizeType.FINGER_HEIGHT, ButtonArrangement.VERTICAL, adac.get_city_list ()); arrival_button.set_title (_("Arrival")); arrival_button.set_value (_("Please select")); arrival_button.set_alignment (0.0f, 0.0f, 0.5f, 0.5f); table.attach (arrival_button, 0, 2, 1, 2, AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.FILL, 0, 0); try { arrival_button.set_active (gconf.get_int ("/apps/beifahrer/arrival")); } catch (Error e) { } var switch_button = new Gtk.Button.with_label (_("Switch departure and arrival")); Hildon.gtk_widget_set_theme_size (switch_button, SizeType.FINGER_HEIGHT); switch_button.set_alignment (0.0f, 0.5f); table.attach (switch_button, 0, 2, 2, 3, AttachOptions.FILL, AttachOptions.FILL, 0, 0); date = new DateButton (SizeType.FINGER_HEIGHT, ButtonArrangement.VERTICAL); date.set_alignment (0.0f, 0.0f, 0.5f, 0.5f); table.attach (date, 0, 1, 3, 4, AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.FILL, 0, 0); var button = new PickerButton (SizeType.FINGER_HEIGHT, ButtonArrangement.VERTICAL); button.set_selector (tolerance_selector); button.set_title (_("Tolerance")); button.set_value (_("+/- 0 days")); button.set_alignment (0.0f, 0.0f, 0.5f, 0.5f); table.attach (button, 1, 2, 3, 4, AttachOptions.FILL, AttachOptions.FILL, 0, 0); var search_button = new Gtk.Button.with_label (_("Search")); Hildon.gtk_widget_set_theme_size (search_button, SizeType.FINGER_HEIGHT); table.attach (search_button, 0, 2, 4, 5, AttachOptions.FILL, AttachOptions.FILL, 0, 0); alignment.add (table); add (alignment); switch_button.clicked.connect (on_switch_button_clicked); search_button.clicked.connect (on_search_button_clicked); settings.clicked.connect (on_settings_clicked); show_all (); control = Location.GPSDControl.get_default (); control.preferred_method = Location.METHOD_ACWP; control.preferred_interval = Location.GPSDControlInterval.@1S; control.error.connect (() => { print ("control error\n"); }); control.error_verbose.connect ((e) => { switch (e) { case Location.GPSDControlError.USER_REJECTED_DIALOG: print ("\tuser rejected dialog\n"); break; case Location.GPSDControlError.USER_REJECTED_SETTINGS: print ("\tuser rejected settings\n"); break; case Location.GPSDControlError.BT_GPS_NOT_AVAILABLE: print ("\tbt gps not available\n"); break; case Location.GPSDControlError.METHOD_NOT_ALLOWED_IN_OFFLINE_MODE: print ("\tmethod not allowed in offline mode\n"); break; case Location.GPSDControlError.SYSTEM: Banner.show_information (this, null, _("No GPS available!")); break; } }); control.gpsd_running.connect (() => { print ("control running\n"); }); control.gpsd_stopped.connect (() => { print ("control stopped\n"); }); try { use_location = gconf.get_bool (GCONF_KEY_USE_LOCATION); } catch (Error e) { } want_location = use_location; if (want_location) control.start (); device = (Location.GPSDevice) GLib.Object.@new (typeof (Location.GPSDevice), null); device.changed.connect (on_location_changed); device.connected.connect (() => { print ("device connected\n"); }); device.disconnected.connect (() => { print ("device disconnected\n"); }); // In case the device already has a fix: on_location_changed (); } void on_location_changed () requires (device.fix != null) { if (!want_location || device.status == Location.GPSDeviceStatus.NO_FIX) return; if (Location.GPS_DEVICE_LATLONG_SET in (int) device.fix.fields) { print ("fix: lat=%f, lon=%f\n", device.fix.latitude, device.fix.longitude); unowned City city = adac.find_nearest_city (device.fix.latitude, device.fix.longitude); if (city != null) { int n = adac.get_city_list ().index (city); int n_from = departure_button.get_active (); int n_to = arrival_button.get_active (); print ("city(%d): %s (%d)\n", n, city.name, city.number); if (n != n_from) { departure_button.set_active (n); // If we are at the previous point of arrival, prepare for return trip if (n == n_to) arrival_button.set_active (n_from); } } control.stop (); want_location = false; } } void on_search_button_clicked (Gtk.Button button) { int n; n = departure_button.get_active (); if (n == -1) return; string city_from = adac.get_city_list ().nth_data (n).name; try { if (gconf.get_int (GCONF_KEY_DEPARTURE) != n) gconf.set_int (GCONF_KEY_DEPARTURE, n); } catch (Error e) { } n = arrival_button.get_active (); if (n == -1) return; string city_to = adac.get_city_list ().nth_data (n).name; try { if (gconf.get_int (GCONF_KEY_ARRIVAL) != n) gconf.set_int (GCONF_KEY_ARRIVAL, n); } catch (Error e) { } uint year, month, day; date.get_date (out year, out month, out day); var date = Date (); date.set_day ((DateDay) day); date.set_month ((DateMonth) (month + DateMonth.JANUARY)); date.set_year ((DateYear) year); int tolerance = tolerance_selector.get_active (0); var window = new LiftListWindow (adac); window.show (); window.find_lifts.begin (city_from, departure_button.get_radius (), city_to, arrival_button.get_radius (), date, tolerance); } // Switch departure and arrival void on_switch_button_clicked () { int n = departure_button.get_active (); departure_button.set_active (arrival_button.get_active ()); arrival_button.set_active (n); n = departure_button.get_radius (); departure_button.set_radius (arrival_button.get_radius ()); arrival_button.set_radius (n); } void on_settings_clicked () { var dialog = new SettingsDialog (this); dialog.response.connect (on_settings_response); dialog.show (); } void on_settings_response (int response_id) { bool old_use_location = use_location; use_location = gconf.get_bool (GCONF_KEY_USE_LOCATION); if (!old_use_location && use_location) { want_location = true; control.start (); } } }