Debian packaging: 0.0.4-1
[beifahrer] / src / lift-list-window.vala
index e4c5ae2..2e5d6ef 100644 (file)
@@ -22,8 +22,19 @@ using Hildon;
 public class LiftListWindow : StackableWindow {
        public const string GCONF_KEY_PRELOAD = "/apps/beifahrer/preload";
 
+       enum Columns {
+               ROUTE,
+               SECONDARY,
+               DATETIME,
+               PLACES,
+               PRICE,
+               SMOKER,
+               LIFT
+       }
+
        AdacMitfahrclub adac;
        ListStore store;
+       TreeSortable sortable;
        Alignment alignment;
        TreeView tree;
        TreeViewColumn route_column;
@@ -42,19 +53,30 @@ public class LiftListWindow : StackableWindow {
                set_title ("Beifahrer");
 
                var menu = new AppMenu ();
+               var sort_by_time = new RadioButton.with_label (null, _("Time"));
+                sort_by_time.set_mode (false);
+               sort_by_time.show ();
+               var sort_by_price = new RadioButton.with_label_from_widget (sort_by_time, _("Price"));
+                sort_by_price.set_mode (false);
+               sort_by_price.show ();
+               menu.add_filter (sort_by_time);
+               menu.add_filter (sort_by_price);
                goto_website = new Gtk.Button.with_label (_("Show website"));
                menu.append (goto_website);
                set_main_menu (menu);
 
                gconf = GConf.Client.get_default ();
-               store = new ListStore (6, typeof (string), typeof (string), typeof (string), typeof (string), typeof (string), typeof (Lift));
+               store = new ListStore (7, typeof (string), typeof (string), typeof (string), typeof (string), typeof (string), typeof (string), typeof (Lift));
+               sortable = new TreeModelSort.with_model (store);
+               sortable.set_sort_func (Columns.DATETIME, datetime_sort_func);
+               sortable.set_sort_func (Columns.PRICE, price_sort_func);
 
                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;
 
-               tree = (TreeView) Hildon.gtk_tree_view_new_with_model (UIMode.NORMAL, store);
+               tree = (TreeView) Hildon.gtk_tree_view_new_with_model (UIMode.NORMAL, sortable);
                Hildon.gtk_widget_set_theme_size (tree, SizeType.FINGER_HEIGHT);
 
                tree.set_headers_visible (false);
@@ -64,36 +86,69 @@ public class LiftListWindow : StackableWindow {
                var selection = tree.get_selection ();
                selection.set_mode (SelectionMode.SINGLE);
 
-               // Source and destination column
-               route_column = new TreeViewColumn.with_attributes ("Route", new CellRendererText (), "markup", 0);
+               // Source - destination / driver column
+               var route_column = new TreeViewColumn ();
+               route_column.set_title (_("Route"));
                route_column.set_reorderable (false);
                route_column.set_sizing (TreeViewColumnSizing.AUTOSIZE);
                route_column.set_expand (true);
                tree.append_column (route_column);
 
+               var vbox_renderer = new CellRendererVBox ();
+
+               var renderer = new CellRendererText ();
+               renderer.yalign = 1.0f;
+               renderer.set_fixed_size (-1, 32);
+               vbox_renderer.append (renderer, true);
+               vbox_renderer.set_data ("route-renderer", renderer);
+
+               // Add secondary text to column (driver name, route details)
+               renderer = new CellRendererText ();
+               renderer.yalign = 0;
+               renderer.set_fixed_size (-1, 32);
+               renderer.ellipsize = Pango.EllipsizeMode.END;
+               Pango.AttrList attr_list = new Pango.AttrList ();
+               var style = Gtk.rc_get_style_by_paths (Gtk.Settings.get_default (), "SmallSystemFont", null, typeof (void));
+               if (style != null) {
+                       var attr_font_desc = new Pango.AttrFontDesc (style.font_desc.copy ());
+                       attr_list.insert ((owned) attr_font_desc);
+               }
+               Gdk.Color color;
+               this.ensure_style ();
+               if (this.style.lookup_color ("SecondaryTextColor", out color)) {
+                       Pango.Attribute attr_color = Pango.attr_foreground_new (color.red, color.green, color.blue);
+                       attr_list.insert ((owned) attr_color);
+               }
+               renderer.attributes = attr_list;
+               vbox_renderer.append (renderer, true);
+               vbox_renderer.set_data ("secondary-renderer", renderer);
+
+               route_column.pack_start (vbox_renderer, true);
+               route_column.set_cell_data_func (vbox_renderer, vbox_data_func);
+
                // Date and time column
-               var datetime_column = new TreeViewColumn.with_attributes ("DateTime", new CellRendererText (), "text", 1);
+               var datetime_column = new TreeViewColumn.with_attributes ("DateTime", new CellRendererText (), "text", Columns.DATETIME);
                datetime_column.set_reorderable (false);
                datetime_column.set_sizing (TreeViewColumnSizing.AUTOSIZE);
                datetime_column.set_expand (true);
                tree.append_column (datetime_column);
 
                // Free places column
-               var places_column = new TreeViewColumn.with_attributes ("Places", new CellRendererText (), "text", 2);
+               var places_column = new TreeViewColumn.with_attributes ("Places", new CellRendererText (), "text", Columns.PLACES);
                places_column.set_reorderable (false);
                places_column.set_sizing (TreeViewColumnSizing.AUTOSIZE);
                places_column.set_expand (true);
                tree.append_column (places_column);
 
                // Price column
-               var price_column = new TreeViewColumn.with_attributes ("Price", new CellRendererText (), "text", 3);
+               var price_column = new TreeViewColumn.with_attributes ("Price", new CellRendererText (), "text", Columns.PRICE);
                price_column.set_reorderable (false);
                price_column.set_sizing (TreeViewColumnSizing.AUTOSIZE);
                price_column.set_expand (true);
                tree.append_column (price_column);
 
                // Smoker/Non-smoker column
-               var smoke_column = new TreeViewColumn.with_attributes ("Smoker", new CellRendererPixbuf (), "icon-name", 4);
+               var smoke_column = new TreeViewColumn.with_attributes ("Smoker", new CellRendererPixbuf (), "icon-name", Columns.SMOKER);
                smoke_column.set_reorderable (false);
                smoke_column.set_sizing (TreeViewColumnSizing.AUTOSIZE);
                smoke_column.set_expand (false);
@@ -122,6 +177,70 @@ public class LiftListWindow : StackableWindow {
                tree.row_activated.connect (this.on_row_activated);
                Gdk.Screen.get_default ().size_changed.connect (this.on_orientation_changed);
                goto_website.clicked.connect (on_goto_website_clicked);
+               sort_by_time.toggled.connect (button => {
+                       if (button.get_active ())
+                               sortable.set_sort_column_id (Columns.DATETIME, Gtk.SortType.ASCENDING);
+               });
+               sort_by_price.toggled.connect (button => {
+                       if (button.get_active ())
+                               sortable.set_sort_column_id (Columns.PRICE, Gtk.SortType.ASCENDING);
+               });
+       }
+
+       private int datetime_sort_func (TreeModel model, TreeIter a, TreeIter b) {
+               Lift la;
+               Lift lb;
+               model.get (a, Columns.LIFT, out la);
+               model.get (b, Columns.LIFT, out lb);
+               int year = la.time.year - lb.time.year;
+               if (year != 0)
+                       return year;
+               int month = la.time.month - lb.time.month;
+               if (month != 0)
+                       return month;
+               int day = la.time.day - lb.time.day;
+               if (day != 0)
+                       return day;
+               int hour = la.time.hour - lb.time.hour;
+               // Negative hour means no exact time available
+               // - sort those entries last
+               if (la.time.hour < 0) {
+                       hour += 24;
+                       return hour;
+               }
+               if (lb.time.hour < 0) {
+                       hour -= 24;
+                       return hour;
+               }
+               if (hour != 0)
+                       return hour;
+               int minute = la.time.minute - lb.time.minute;
+               return minute;
+       }
+
+       private int price_sort_func (TreeModel model, TreeIter a, TreeIter b) {
+               string pa;
+               string pb;
+               model.get (a, Columns.PRICE, out pa);
+               model.get (b, Columns.PRICE, out pb);
+               if (pa == null && pb != null)
+                       return 1;
+               if (pa != null && pb == null)
+                       return -1;
+               return strcmp (pa, pb);
+       }
+
+       private void vbox_data_func (CellLayout cell_layout, CellRenderer cell, TreeModel model, TreeIter iter) {
+               unowned string text;
+               CellRendererText renderer;
+
+               model.get (iter, Columns.ROUTE, out text);
+               renderer = cell.get_data ("route-renderer");
+               renderer.text = text;
+
+               model.get (iter, Columns.SECONDARY, out text);
+               renderer = cell.get_data ("secondary-renderer");
+               renderer.text = text;
        }
 
        public async void find_lifts (string city_from, int radius_from, string city_to, int radius_to, Date date, int tolerance = 0) {
@@ -143,12 +262,13 @@ public class LiftListWindow : StackableWindow {
                        string datetime = "%02d.%02d.%04d".printf (lift.time.day, lift.time.month, lift.time.year);
                        if (lift.time.hour >= 0)
                                datetime += ", %d:%02d".printf (lift.time.hour, lift.time.minute);
-                       store.insert_with_values (out iter, -1, 0, lift.city_from + " - " + lift.city_to,
-                                                               1, datetime,
-                                                               2, _("%d pl.").printf (lift.places),
-                                                               3, lift.price,
-                                                               4, icon_name,
-                                                               5, lift);
+                       store.insert_with_values (out iter, -1, Columns.ROUTE, lift.city_from + " - " + lift.city_to,
+                                                               Columns.SECONDARY, "",
+                                                               Columns.DATETIME, datetime,
+                                                               Columns.PLACES, _("%d pl.").printf (lift.places),
+                                                               Columns.PRICE, lift.price,
+                                                               Columns.SMOKER, icon_name,
+                                                               Columns.LIFT, lift);
                        // (LiftFlags.WOMEN_ONLY,ADAC_MEMBER in lift.flags)
                }
                if (lift_list.length () > 6)
@@ -164,12 +284,12 @@ public class LiftListWindow : StackableWindow {
                if (preload) {
                        if (store.get_iter_first (out iter)) do {
                                Lift lift2;
-                               store.@get (iter, 5, out lift2);
+                               store.@get (iter, Columns.LIFT, out lift2);
                                if (lift2 == null)
                                        continue;
                                if (lift2.description == null) {
                                        yield adac.update_lift_details (lift2);
-                                       store.@set (iter, 0, lift2.city_from + " - " + lift2.city_to + "\n<small>" + lift2.name + "</small>");
+                                       store.@set (iter, Columns.SECONDARY, lift2.name);
                                }
                        } while (store.iter_next (ref iter));
                }
@@ -187,7 +307,7 @@ public class LiftListWindow : StackableWindow {
                Lift lift;
 
                if (model.get_iter (out iter, path)) {
-                       model.get (iter, 5, out lift);
+                       model.get (iter, Columns.LIFT, out lift);
 
                        var window = new LiftDetailWindow (adac, lift);
                        window.show ();