/* 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 LiftDetailWindow : StackableWindow { private const string CALENDAR_SERVICE = "com.nokia.calendar"; private const string CALENDAR_PATH = "/com/nokia/calendar"; private const string CALENDAR_IF = "com.nokia.calendar"; AdacMitfahrclub adac; Lift lift; Alignment alignment; PannableArea pannable; VBox vbox; OssoABook.Button button_route; OssoABook.Button button_calendar; Label label_driver; OssoABook.Button button_phone; OssoABook.Button button_sms; OssoABook.Button button_email; Image image_smoke; Label label; Label label_changed; Table table; string ics_filename = null; public LiftDetailWindow (AdacMitfahrclub _adac, Lift _lift) { adac = _adac; lift = _lift; update_lift_details (); if (lift.description == null) get_lift_details.begin (); } construct { set_title ("Beifahrer"); var menu = new AppMenu (); var add_contact = new Gtk.Button.with_label (_("New contact")); add_contact.show (); menu.append (add_contact); var goto_website = new Gtk.Button.with_label (_("Show website")); goto_website.show (); menu.append (goto_website); set_main_menu (menu); 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; pannable = new PannableArea (); pannable.hscrollbar_policy = PolicyType.NEVER; vbox = new VBox (false, 0); var hbox = new HBox (false, 0); button_route = new OssoABook.Button (SizeType.FINGER_HEIGHT); button_route.style = OssoABook.ButtonStyle.LABEL; var image_eventbox = new EventBox (); image_smoke = new Image (); image_eventbox.add (image_smoke); hbox.pack_start (button_route, true, true, 0); hbox.pack_start (image_eventbox, false, false, MARGIN_DEFAULT); table = new Table (7, 2, false); button_calendar = new OssoABook.Button (SizeType.FINGER_HEIGHT); button_calendar.set_icon_name ("general_calendar"); button_calendar.set_icon_visible (true); button_calendar.title = _("Departure time"); label_driver = new Label (_("Driver:")); label_driver.set_alignment (0.0f, 0.5f); Hildon.gtk_widget_set_theme_size (label_driver, SizeType.FINGER_HEIGHT); button_phone = new OssoABook.Button (SizeType.FINGER_HEIGHT); button_phone.set_icon_name ("general_call"); button_phone.set_icon_visible (true); button_phone.title = _("Phone"); button_sms = new OssoABook.Button (SizeType.FINGER_HEIGHT); button_sms.set_icon_name ("general_sms"); button_sms.set_icon_visible (true); button_sms.title = _("SMS"); button_email = new OssoABook.Button (SizeType.FINGER_HEIGHT); button_email.set_icon_name ("general_email"); button_email.set_icon_visible (true); button_email.title = _("E-mail"); label = new Label (""); label.set_alignment (0.0f, 0.5f); label.set_line_wrap (true); label_changed = new Label (""); label_changed.set_alignment (1.0f, 0.0f); Hildon.helper_set_logical_color (label_changed, RcFlags.FG, StateType.NORMAL, "SecondaryTextColor"); Hildon.helper_set_logical_font (label_changed, "SmallSystemFont"); if (BeifahrerProgram.orientation.portrait) { table.attach (button_calendar, 0, 2, 0, 1, AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.FILL, 0, 0); table.attach (label_driver, 0, 2, 1, 2, AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.FILL, MARGIN_DEFAULT, 0); table.attach (button_phone, 0, 2, 2, 3, AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.FILL, 0, 0); table.attach (button_sms, 0, 2, 3, 4, AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.FILL, 0, 0); table.attach (button_email, 0, 2, 4, 5, AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.FILL, 0, 0); } else { table.attach (button_calendar, 1, 2, 0, 1, AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.FILL, 0, 0); table.attach (label_driver, 0, 1, 1, 2, AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.FILL, MARGIN_DEFAULT, 0); table.attach (button_phone, 1, 2, 1, 2, AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.FILL, 0, 0); table.attach (button_sms, 1, 2, 2, 3, AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.FILL, 0, 0); table.attach (button_email, 1, 2, 3, 4, AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.FILL, 0, 0); } table.attach (label, 0, 2, 5, 6, AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.FILL, MARGIN_DEFAULT, 0); table.attach (label_changed, 0, 2, 6, 7, AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.FILL, MARGIN_DEFAULT, 0); vbox.pack_start (hbox, true, true, 0); vbox.pack_start (table, true, true, 0); pannable.add_with_viewport (vbox); alignment.add (pannable); alignment.show_all (); button_email.hide (); add (alignment); Gdk.Screen.get_default ().size_changed.connect (on_orientation_changed); add_contact.clicked.connect (on_add_contact_clicked); goto_website.clicked.connect (on_goto_website_clicked); image_eventbox.button_press_event.connect (on_image_eventbox_button_pressed); button_calendar.clicked.connect (on_button_calendar_clicked); button_phone.clicked.connect (on_button_phone_clicked); button_sms.clicked.connect (on_button_sms_clicked); button_email.clicked.connect (on_button_email_clicked); destroy.connect (on_destroy); map_event.connect (on_map_event); } private async void get_lift_details () { Hildon.gtk_window_set_progress_indicator (this, 1); yield adac.update_lift_details (lift); Hildon.gtk_window_set_progress_indicator (this, 0); update_lift_details (); } private void update_lift_details () { button_route.title = _("From %s to %s").printf (lift.city_from, lift.city_to); if (lift.city_via.length () > 0) { string route = _("via "); foreach (string via in lift.city_via) route += via + " "; button_route.value = route; } else { button_route.value = ""; } button_calendar.value = "%02d.%02d.%04d, %d:%02d".printf (lift.time.day, lift.time.month, lift.time.year, lift.time.hour, lift.time.minute); label_driver.set_text (_("Driver: ") + lift.name); if (lift.cell != null) { button_phone.title = _("Cell"); string cell_number = E.normalize_phone_number (lift.cell); button_phone.value = cell_number; button_sms.value = cell_number; } else if (lift.phone != null) { button_phone.title = _("Phone"); string phone_number = E.normalize_phone_number (lift.phone); button_phone.value = phone_number; button_sms.value = phone_number; } else if (lift.phone2 != null) { button_phone.title = _("Phone"); string phone_number = E.normalize_phone_number (lift.phone2); button_phone.value = phone_number; button_sms.value = phone_number; } if (lift.email_image_uri != null) { button_email.value = _("Click to view E-mail image"); button_email.show (); } string lift_text = _("Free places: %d\n").printf (lift.places); lift_text += (lift.price != null) ? _("Price: %s\n").printf (lift.price) : _("(no price given)\n"); if (LiftFlags.SMOKER in lift.flags) try { var pixbuf = IconTheme.get_default ().load_icon ("beifahrer_smoker", 32, IconLookupFlags.NO_SVG); image_smoke.pixbuf = pixbuf; } catch (Error e) { } else if (LiftFlags.NON_SMOKER in lift.flags) try { var pixbuf = IconTheme.get_default ().load_icon ("beifahrer_non_smoker", 32, IconLookupFlags.NO_SVG); image_smoke.pixbuf = pixbuf; } catch (Error e) { } if (LiftFlags.ADAC_MEMBER in lift.flags) lift_text += _("ADAC member "); if (LiftFlags.WOMEN_ONLY in lift.flags) lift_text += _("only women "); lift_text += "\n\n" + lift.description; label.set_text (lift_text); if (lift.modified != null) label_changed.set_text (_("\nLast changed: ") + lift.modified); // Reduce right margin for scrollbar, if update_lift_details is called after mapping the window if (vbox.allocation.height > pannable.allocation.height) alignment.right_padding = MARGIN_DEFAULT; } void on_button_calendar_clicked () { var ical = new StringBuilder ("BEGIN:VCALENDAR\nVERSION:2.0\nMETHOD:PUBLISH\nBEGIN:VEVENT\nUID:"); ical.append ("beifahrer" + lift.href); // UID ical.append ("\nCLASS:PUBLIC\nSUMMARY:"); ical.append_printf (_("From %s to %s with %s"), lift.city_from, lift.city_to, lift.name); ical.append ("\nDTSTART;TZID=Europe/Berlin:"); ical.append_printf ("%04d%02d%02dT%02d%02d00", lift.time.year + 2000, lift.time.month, lift.time.day, lift.time.hour, lift.time.minute); ical.append ("\nDTEND;TZID=Europe/Berlin:"); ical.append_printf ("%04d%02d%02dT%02d%02d00", lift.time.year + 2000, lift.time.month, lift.time.day, lift.time.hour, lift.time.minute); ical.append ("\nDESCRIPTION:"); ical.append (lift.description.replace ("\n", "\\n")); ical.append ("\nEND:VEVENT\nEND:VCALENDAR\n"); ics_filename = Path.build_path ("/", Environment.get_tmp_dir (), "beifahrer.ics"); try { FileUtils.set_contents (ics_filename, ical.str); } catch (FileError e) { stderr.printf ("Failed to write %s: %s\n", ics_filename, e.message); return; } var error = DBus.RawError (); var bus = DBus.RawBus.get (DBus.BusType.SESSION, ref error); var res = HildonMime.open_file (bus, "file://" + ics_filename); } void on_destroy () { if (ics_filename != null) FileUtils.remove (ics_filename); } bool on_map_event (Gdk.Event event) { // Reduce right margin for scrollbar, for preloaded lift if (vbox.allocation.height > pannable.allocation.height) alignment.right_padding = MARGIN_DEFAULT; return true; } void on_button_phone_clicked () { var uri = "tel://"; if (lift.cell != null) uri += E.normalize_phone_number (lift.cell); else if (lift.phone != null) uri += E.normalize_phone_number (lift.phone); try { var action = URIAction.get_default_action_by_uri (uri); if (action != null) { action.open (uri); } else { Banner.show_information (this, null, _("Couldn't call %s URI").printf (uri)); } } catch (Error e) { if (e is URIError) { Banner.show_information (this, null, _("Error: %s").printf (e.message)); } } } void on_button_sms_clicked () { var uri = "sms://"; if (lift.cell != null) uri += E.normalize_phone_number (lift.cell); else if (lift.phone != null) uri += E.normalize_phone_number (lift.phone); try { var action = URIAction.get_default_action_by_uri (uri); if (action != null) { action.open (uri); } else { Banner.show_information (this, null, _("Couldn't open %s URI").printf (uri)); } } catch (Error e) { if (e is URIError) { Banner.show_information (this, null, _("Error: %s").printf (e.message)); } } } void on_button_email_clicked () { var uri = "http://mitfahrclub.adac.de"; uri += lift.email_image_uri; try { var action = URIAction.get_default_action_by_uri (uri); if (action != null) { action.open (uri); } else { Banner.show_information (this, null, _("Couldn't open %s URI").printf (uri)); } } catch (Error e) { if (e is URIError) { Banner.show_information (this, null, _("Error: %s").printf (e.message)); } } } void on_add_contact_clicked () { var contact = new OssoABook.Contact (); var attr_fn = new E.VCardAttribute (null, E.EVC_FN); contact.add_attribute_with_value ((owned) attr_fn, lift.name); if (lift.cell != null) { var attr_cell = new E.VCardAttribute (null, E.EVC_TEL); var param = new E.VCardAttributeParam (E.EVC_TYPE); attr_cell.add_param_with_value ((owned) param, "CELL"); contact.add_attribute_with_value ((owned) attr_cell, E.normalize_phone_number (lift.cell)); } if (lift.phone != null) { var attr_phone = new E.VCardAttribute (null, E.EVC_TEL); var param = new E.VCardAttributeParam (E.EVC_TYPE); attr_phone.add_param_with_value ((owned) param, "VOICE"); contact.add_attribute_with_value ((owned) attr_phone, E.normalize_phone_number (lift.phone)); } var dialog = new OssoABook.TemporaryContactDialog.with_contact (this, contact); dialog.show (); } void on_goto_website_clicked () { BeifahrerProgram.open_browser (this, adac.get_lift_details_url (lift)); } bool on_image_eventbox_button_pressed (Gdk.EventButton event) { if (event.button != 1) return true; if (LiftFlags.SMOKER in lift.flags) Banner.show_information (this, null, _("Smoker")); if (LiftFlags.NON_SMOKER in lift.flags) Banner.show_information (this, null, _("Non-smoker")); return false; } void on_orientation_changed (Gdk.Screen screen) { // Maybe this will be fixed directly in Maemo-GTK, see // http://lists.maemo.org/pipermail/maemo-developers/2010-May/026332.html vbox.queue_resize (); table.remove (button_calendar); table.remove (label_driver); table.remove (button_phone); table.remove (button_sms); table.remove (button_email); if (BeifahrerProgram.orientation.portrait) { table.attach (button_calendar, 0, 2, 0, 1, AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.FILL, 0, 0); table.attach (label_driver, 0, 2, 1, 2, AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.FILL, MARGIN_DEFAULT, 0); table.attach (button_phone, 0, 2, 2, 3, AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.FILL, 0, 0); table.attach (button_sms, 0, 2, 3, 4, AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.FILL, 0, 0); table.attach (button_email, 0, 2, 4, 5, AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.FILL, 0, 0); } else { table.attach (button_calendar, 1, 2, 0, 1, AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.FILL, 0, 0); table.attach (label_driver, 0, 1, 1, 2, AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.FILL, MARGIN_DEFAULT, 0); table.attach (button_phone, 1, 2, 1, 2, AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.FILL, 0, 0); table.attach (button_sms, 1, 2, 2, 3, AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.FILL, 0, 0); table.attach (button_email, 1, 2, 3, 4, AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.FILL, 0, 0); } } }