a lot of changes
This commit is contained in:
@@ -13,7 +13,6 @@
|
||||
*/
|
||||
|
||||
namespace Sernatur {
|
||||
using LibSernatur.Person;
|
||||
using LibSernatur.DB;
|
||||
|
||||
/**
|
||||
@@ -24,7 +23,7 @@ namespace Sernatur {
|
||||
/**
|
||||
* The opened database connection
|
||||
*/
|
||||
private Postgres.Database conn;
|
||||
private Connection conn;
|
||||
/**
|
||||
* The content grid to fill
|
||||
*/
|
||||
@@ -34,13 +33,28 @@ namespace Sernatur {
|
||||
*/
|
||||
[GtkChild]
|
||||
private Gtk.Box mainbox;
|
||||
/**
|
||||
* The tours menu item
|
||||
*/
|
||||
[GtkChild]
|
||||
private Gtk.MenuItem tours;
|
||||
/**
|
||||
* The q1 menu item
|
||||
*/
|
||||
[GtkChild]
|
||||
private Gtk.MenuItem q1;
|
||||
/**
|
||||
* The quit menu item
|
||||
*/
|
||||
[GtkChild]
|
||||
private Gtk.MenuItem quit;
|
||||
|
||||
/**
|
||||
* This is a callback for when the close button is pressed on the window
|
||||
* @param widget The widget that called this GtkCallback
|
||||
*/
|
||||
[GtkCallback]
|
||||
private void window_quit(Gtk.Widget widget) {
|
||||
private void on_destroy(Gtk.Widget widget) {
|
||||
application.quit ();
|
||||
}
|
||||
|
||||
@@ -51,7 +65,7 @@ namespace Sernatur {
|
||||
* @return Returns true if the event is handled or false if it isn't
|
||||
*/
|
||||
[GtkCallback]
|
||||
private bool maximize_window(Gtk.Widget widget, Gdk.EventWindowState state) {
|
||||
private bool on_window_state_event(Gtk.Widget widget, Gdk.EventWindowState state) {
|
||||
var settings = new Settings ("cl.cromer.ubb.sernatur.window");
|
||||
if (state.changed_mask == Gdk.WindowState.MAXIMIZED && (state.new_window_state & Gdk.WindowState.MAXIMIZED) != 0) {
|
||||
// Maximized
|
||||
@@ -71,7 +85,7 @@ namespace Sernatur {
|
||||
* @return Returns true if the event is handled or false if it isn't
|
||||
*/
|
||||
[GtkCallback]
|
||||
private bool resize_window(Gtk.Widget widget, Gdk.Event event) {
|
||||
private bool on_configure_event(Gtk.Widget widget, Gdk.Event event) {
|
||||
var settings = new Settings ("cl.cromer.ubb.sernatur.window");
|
||||
if (event.get_event_type () == Gdk.EventType.CONFIGURE && !settings.get_boolean ("maximized")) {
|
||||
if (settings.get_int ("width") != event.get_window ().get_width ()) {
|
||||
@@ -85,23 +99,26 @@ namespace Sernatur {
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a callback for when the tours option in the menu is clicked
|
||||
* This is a callback for when a menu item is clicked
|
||||
* @param menu_item The menu item that was clicked
|
||||
*/
|
||||
[GtkCallback]
|
||||
private void menu_tours(Gtk.MenuItem menu_item) {
|
||||
var tour_window = new TourWindow (application, conn);
|
||||
tour_window.set_transient_for (this); // Set this window as the parent of the new window
|
||||
tour_window.show_all ();
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a callback for when the quit option in the menu is clicked
|
||||
* @param menu_item The menu item that was clicked
|
||||
*/
|
||||
[GtkCallback]
|
||||
private void menu_quit(Gtk.MenuItem menu_item) {
|
||||
application.quit ();
|
||||
private void on_activate_menu(Gtk.MenuItem menu_item) {
|
||||
if (menu_item == tours) {
|
||||
var tour_list = new TourList (application, conn);
|
||||
tour_list.set_transient_for (this); // Set this window as the parent of the new window
|
||||
tour_list.initialize ();
|
||||
tour_list.show_all ();
|
||||
}
|
||||
else if (menu_item == q1) {
|
||||
var query_window = new QueryWindow (application, conn);
|
||||
query_window.set_transient_for (this); // Set this window as the parent of the new window
|
||||
query_window.initialize ();
|
||||
query_window.show_all ();
|
||||
}
|
||||
else if (menu_item == quit) {
|
||||
application.quit ();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -118,14 +135,19 @@ namespace Sernatur {
|
||||
builder.connect_signals (null);
|
||||
content = builder.get_object ("content_grid") as Gtk.Grid;
|
||||
|
||||
// Add logo to main main box
|
||||
// Add logo to main box
|
||||
mainbox.pack_start (content, true, false, 0);
|
||||
}
|
||||
catch (Error e) {
|
||||
// This error is not fatal, so let's keep going
|
||||
warning (e.message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize what is needed for this window
|
||||
*/
|
||||
public void initialize () {
|
||||
var settings = new Settings ("cl.cromer.ubb.sernatur.db");
|
||||
var host = settings.get_string ("host");
|
||||
var port = settings.get_string ("port");
|
||||
@@ -135,17 +157,19 @@ namespace Sernatur {
|
||||
var username = settings.get_string ("username");
|
||||
var password = settings.get_string ("password");
|
||||
|
||||
conn = Postgres.set_db_login (host, port, options, tty, database, username, password);
|
||||
if (conn.get_status () != Postgres.ConnectionStatus.OK) {
|
||||
try {
|
||||
conn = new Connection (host, port, options, tty, database, username, password);
|
||||
}
|
||||
catch (Error e) {
|
||||
#if DEBUG
|
||||
error (conn.get_error_message ());
|
||||
error (e.message);
|
||||
#else
|
||||
warning (conn.get_error_message ());
|
||||
warning (e.message);
|
||||
var msg = new Gtk.MessageDialog (this,
|
||||
Gtk.DialogFlags.MODAL,
|
||||
Gtk.MessageType.ERROR,
|
||||
Gtk.ButtonsType.CLOSE,
|
||||
conn.get_error_message ());
|
||||
e.message);
|
||||
msg.response.connect ((response_id) => {
|
||||
switch (response_id) {
|
||||
case Gtk.ResponseType.CLOSE:
|
||||
@@ -155,14 +179,13 @@ namespace Sernatur {
|
||||
application.quit ();
|
||||
break;
|
||||
}
|
||||
msg.destroy();
|
||||
msg.destroy ();
|
||||
});
|
||||
msg.set_title (dgettext (null, "Error"));
|
||||
msg.show ();
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
print (dgettext (null, "Postgresql server version:") + " %d\n", conn.get_server_version ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -16,16 +16,21 @@ config_data_file = configure_file(input: 'config.vala.in',
|
||||
vala_sources = files(
|
||||
'sernatur.vala',
|
||||
'main_window.vala',
|
||||
'tour_window.vala')
|
||||
'tour_list.vala',
|
||||
'tour_editor.vala',
|
||||
'queries.vala',
|
||||
'query_window.vala')
|
||||
|
||||
sources = vala_sources
|
||||
sources += main_gresource
|
||||
sources += tour_gresource
|
||||
sources += query_gresource
|
||||
sources += config_data_file
|
||||
|
||||
vala_args = ['--vapidir=' + join_paths(meson.source_root(), 'vapi')]
|
||||
vala_args += ['--gresources=' + join_paths(meson.source_root(), 'data/ui/main.gresource.xml')]
|
||||
vala_args += ['--gresources=' + join_paths(meson.source_root(), 'data/ui/tour.gresource.xml')]
|
||||
vala_args += ['--gresources=' + join_paths(meson.source_root(), 'data/ui/query.gresource.xml')]
|
||||
|
||||
inc = include_directories('../lib', './')
|
||||
|
||||
|
44
src/queries.vala
Normal file
44
src/queries.vala
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2018-2019 Chris Cromer
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
namespace Sernatur {
|
||||
namespace Constants {
|
||||
/**
|
||||
* The Q1 statement
|
||||
*/
|
||||
public const string Q1_STATEMENT = "Genere la vista REGIONES SINDESCUENTO(nombreRegion, cantidad) que contiene el nombre
|
||||
de cada región y la cantidad de personas a las que no se les ha aplicado descuento y que han
|
||||
visitado algún lugar de la región en algún tour, durante el mes de noviembre del presente año.
|
||||
Luego utilizando la vista, muestre las regiones que han recibido la mayor cantidad de turistas
|
||||
sin descuento.";
|
||||
/**
|
||||
* The Q1 sql
|
||||
*/
|
||||
public const string Q1_SQL = "CREATE VIEW REGIONES_SINDESCUENTO(nombreRegion, cantidad)
|
||||
AS (
|
||||
SELECT nombre_region, COUNT(R2.rut_turista) FROM region R
|
||||
JOIN ciudad C ON (C.id_region = R.id_region) JOIN tour T ON (T.id_ciudad = C.id_ciudad)
|
||||
JOIN realiza R2 ON (R2.id_tour = T.id_tour)
|
||||
WHERE (
|
||||
EXISTS(SELECT fecha_llegada
|
||||
FROM asociado
|
||||
WHERE (id_tour = T.id_tour AND fecha_llegada BETWEEN '2018-11-01' AND '2018-11-30')
|
||||
) AND
|
||||
R2.id_descuento = 2
|
||||
)
|
||||
GROUP BY (R.nombre_region)
|
||||
);
|
||||
SELECT nombreRegion, cantidad FROM REGIONES_SINDESCUENTO WHERE (cantidad = (SELECT MAX(cantidad) FROM REGIONES_SINDESCUENTO));";
|
||||
}
|
||||
}
|
131
src/query_window.vala
Normal file
131
src/query_window.vala
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright 2018-2019 Chris Cromer
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
namespace Sernatur {
|
||||
using Constants;
|
||||
using LibSernatur.Misc;
|
||||
using LibSernatur.DB;
|
||||
|
||||
/**
|
||||
* The query window class
|
||||
*/
|
||||
[GtkTemplate (ui = "/cl/cromer/ubb/sernatur/query.window.ui")]
|
||||
public class QueryWindow : Gtk.ApplicationWindow {
|
||||
/**
|
||||
* The open database connection
|
||||
*/
|
||||
private Connection conn;
|
||||
/**
|
||||
* The columns of the tree view
|
||||
*/
|
||||
private enum Column {
|
||||
/**
|
||||
* The tour name
|
||||
*/
|
||||
REGION_NAME,
|
||||
/**
|
||||
* The individual cost
|
||||
*/
|
||||
QUANTITY,
|
||||
/**
|
||||
* The number of colums in this enum
|
||||
*/
|
||||
N_COLUMNS
|
||||
}
|
||||
/**
|
||||
* The list that stores the contents in the tree view
|
||||
*/
|
||||
private Gtk.ListStore list_store;
|
||||
/**
|
||||
* The scroll window where the columns and rows are stored
|
||||
*/
|
||||
[GtkChild]
|
||||
private Gtk.ScrolledWindow scroll_window;
|
||||
[GtkChild]
|
||||
private Gtk.Label statement;
|
||||
[GtkChild]
|
||||
private Gtk.Label sql;
|
||||
[GtkChild]
|
||||
private Gtk.Button run_query;
|
||||
[GtkChild]
|
||||
private Gtk.Button close_query;
|
||||
private Gtk.TreeView query_tree;
|
||||
|
||||
/**
|
||||
* This callback is called when a button is clicked
|
||||
* @param button The button that was clicked
|
||||
*/
|
||||
[GtkCallback]
|
||||
public void on_clicked_button (Gtk.Button button) {
|
||||
if (button == run_query) {
|
||||
list_store.clear ();
|
||||
var region_list = RegionesSinDescuento.get_regions (conn.db);
|
||||
|
||||
region_list.foreach ((entry) => {
|
||||
Gtk.TreeIter iter;
|
||||
list_store.append (out iter);
|
||||
list_store.set (iter,
|
||||
Column.REGION_NAME, entry.nombre_region,
|
||||
Column.QUANTITY, entry.cantidad);
|
||||
});
|
||||
}
|
||||
else if (button == close_query) {
|
||||
this.close ();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the tour list class
|
||||
* @param application The application used to make the GLib object
|
||||
* @param conn The database connection to use
|
||||
*/
|
||||
public QueryWindow (Gtk.Application application, Connection conn) {
|
||||
GLib.Object (application: application);
|
||||
this.conn = conn;
|
||||
|
||||
// Load scroll window's content
|
||||
var builder = new Gtk.Builder ();
|
||||
try {
|
||||
builder.add_from_resource ("/cl/cromer/ubb/sernatur/query.1.ui");
|
||||
builder.connect_signals (null);
|
||||
query_tree = builder.get_object ("query_tree") as Gtk.TreeView;
|
||||
query_tree.set_visible (true);
|
||||
|
||||
// Add logo to scroll window
|
||||
scroll_window.add (query_tree);
|
||||
}
|
||||
catch (Error e) {
|
||||
// This error is not fatal, so let's keep going
|
||||
warning (e.message);
|
||||
}
|
||||
|
||||
this.set_visible (true); // This fixes: Gtk-CRITICAL **: 23:58:22.139: gtk_box_gadget_distribute: assertion 'size >= 0' failed in GtkScrollbar
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize what is needed for this window
|
||||
*/
|
||||
public void initialize () {
|
||||
list_store = new Gtk.ListStore (Column.N_COLUMNS,
|
||||
typeof (string),
|
||||
typeof (uint));
|
||||
|
||||
query_tree.set_model (list_store);
|
||||
|
||||
statement.set_text (Q1_STATEMENT);
|
||||
|
||||
sql.set_text (Q1_SQL);
|
||||
}
|
||||
}
|
||||
}
|
@@ -56,6 +56,7 @@ namespace Sernatur {
|
||||
|
||||
window.icon = new Image.from_resource ("/cl/cromer/ubb/sernatur/pixdata/icon-sernatur.png").get_pixbuf ();
|
||||
window.show_all ();
|
||||
window.initialize ();
|
||||
}
|
||||
|
||||
/**
|
||||
|
306
src/tour_editor.vala
Normal file
306
src/tour_editor.vala
Normal file
@@ -0,0 +1,306 @@
|
||||
/*
|
||||
* Copyright 2018-2019 Chris Cromer
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
namespace Sernatur {
|
||||
using LibSernatur.DB;
|
||||
|
||||
/**
|
||||
* The tour editor window class
|
||||
*/
|
||||
[GtkTemplate (ui = "/cl/cromer/ubb/sernatur/tour.editor.ui")]
|
||||
public class TourEditor : Gtk.ApplicationWindow {
|
||||
/**
|
||||
* The open database connection
|
||||
*/
|
||||
private Connection conn;
|
||||
/**
|
||||
* The tour to edit
|
||||
*/
|
||||
private Tour tour;
|
||||
/**
|
||||
* The city data stored in the list store
|
||||
*/
|
||||
private enum CityColumn {
|
||||
/**
|
||||
* The city name
|
||||
*/
|
||||
CITY_NAME,
|
||||
/**
|
||||
* The city object
|
||||
*/
|
||||
CITY,
|
||||
/**
|
||||
* The number of colums in this enum
|
||||
*/
|
||||
N_COLUMNS
|
||||
}
|
||||
/**
|
||||
* The region data stored in the list store
|
||||
*/
|
||||
private enum RegionColumn {
|
||||
/**
|
||||
* The region name
|
||||
*/
|
||||
REGION_NAME,
|
||||
/**
|
||||
* The region object
|
||||
*/
|
||||
REGION,
|
||||
/**
|
||||
* The number of colums in this enum
|
||||
*/
|
||||
N_COLUMNS
|
||||
}
|
||||
/**
|
||||
* The tour name
|
||||
*/
|
||||
[GtkChild]
|
||||
private Gtk.Entry tour_name;
|
||||
/**
|
||||
* The individual cost
|
||||
*/
|
||||
[GtkChild]
|
||||
private Gtk.Entry indiv_cost;
|
||||
/**
|
||||
* The group cost
|
||||
*/
|
||||
[GtkChild]
|
||||
private Gtk.Entry group_cost;
|
||||
/**
|
||||
* The minimum number of people
|
||||
*/
|
||||
[GtkChild]
|
||||
private Gtk.SpinButton minimum_people;
|
||||
/**
|
||||
* The region
|
||||
*/
|
||||
[GtkChild]
|
||||
private Gtk.ComboBoxText region;
|
||||
/**
|
||||
* The save button
|
||||
*/
|
||||
[GtkChild]
|
||||
private Gtk.Button save;
|
||||
/**
|
||||
* The cancel button
|
||||
*/
|
||||
[GtkChild]
|
||||
private Gtk.Button cancel;
|
||||
/**
|
||||
* The city
|
||||
*/
|
||||
[GtkChild]
|
||||
private Gtk.ComboBoxText city;
|
||||
/**
|
||||
* The city entry
|
||||
*/
|
||||
[GtkChild]
|
||||
private Gtk.Entry city_entry;
|
||||
/**
|
||||
* A list of the cities from the database
|
||||
*/
|
||||
private List<Ciudad> cities;
|
||||
/**
|
||||
* A list of the regions from the database
|
||||
*/
|
||||
private List<Region> regions;
|
||||
/**
|
||||
* The list that stores the regions for the combo box
|
||||
*/
|
||||
private Gtk.ListStore region_list_store;
|
||||
/**
|
||||
* The list that stores the cities for the combo box
|
||||
*/
|
||||
private Gtk.ListStore city_list_store = null;
|
||||
/**
|
||||
* This signal is called when a tour is saved
|
||||
*/
|
||||
public signal void save_tour ();
|
||||
|
||||
[GtkCallback]
|
||||
public void on_changed_combobox (Gtk.ComboBox combobox) {
|
||||
if (combobox == region) {
|
||||
Gtk.TreeIter iter;
|
||||
region.get_active_iter (out iter);
|
||||
Region temp_region;
|
||||
if (region_list_store.iter_is_valid (iter)) {
|
||||
region_list_store.get (iter,
|
||||
RegionColumn.REGION, out temp_region);
|
||||
tour.ciudad.region = temp_region;
|
||||
if (city_list_store != null && tour.ciudad.region.id_region != 0) {
|
||||
reset_city ();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// New region to be created
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void reset_city () {
|
||||
cities = Ciudad.get_all_ciudades_in_region (conn.db, tour.ciudad.region.id_region);
|
||||
|
||||
if (cities.length () > 0) {
|
||||
cities.sort_with_data ((a, b) => {
|
||||
return strcmp (a.nombre_ciudad, b.nombre_ciudad);
|
||||
});
|
||||
|
||||
if (city_list_store.iter_n_children (null) > 0) {
|
||||
// If there are more than 0 rows clear it
|
||||
city_list_store.clear ();
|
||||
}
|
||||
cities.foreach ((entry) => {
|
||||
Gtk.TreeIter iter;
|
||||
city_list_store.append (out iter);
|
||||
city_list_store.set (iter,
|
||||
CityColumn.CITY_NAME, entry.nombre_ciudad,
|
||||
CityColumn.CITY, entry);
|
||||
if (tour.ciudad.id_ciudad == 0) {
|
||||
tour.ciudad.id_ciudad = entry.id_ciudad;
|
||||
tour.ciudad.nombre_ciudad = entry.nombre_ciudad;
|
||||
}
|
||||
else {
|
||||
if (entry.id_ciudad == tour.ciudad.id_ciudad) {
|
||||
city.set_active_iter (iter);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
city.set_active (-1);
|
||||
city_entry.set_text ("");
|
||||
}
|
||||
|
||||
/**
|
||||
* This callback is called when a button is clicked
|
||||
* @param button The button that was clicked
|
||||
*/
|
||||
[GtkCallback]
|
||||
public void on_clicked_button (Gtk.Button button) {
|
||||
if (button == save) {
|
||||
if (tour.id_tour == 0) {
|
||||
print (city.get_active_text () + "\n");
|
||||
Gtk.TreeIter iter;
|
||||
Ciudad ciudad;
|
||||
city.get_active_iter (out iter);
|
||||
if (city_list_store.iter_is_valid (iter)) {
|
||||
city_list_store.get (iter,
|
||||
CityColumn.CITY, out ciudad);
|
||||
print (ciudad.nombre_ciudad + "\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
tour.nombre_tour = tour_name.get_text ();
|
||||
tour.costo_indiv = (uint) int.parse (indiv_cost.get_text ());
|
||||
tour.costo_grupal = (uint) int.parse (group_cost.get_text ());
|
||||
tour.minima_personas = (uint) minimum_people.get_value_as_int ();
|
||||
try {
|
||||
Tour.update_tour (conn.db, tour);
|
||||
save_tour ();
|
||||
this.close ();
|
||||
}
|
||||
catch (Error e) {
|
||||
#if DEBUG
|
||||
error (e.message);
|
||||
#else
|
||||
warning (e.message);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (button == cancel) {
|
||||
this.close ();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the tour editor class
|
||||
* @param application The application used to make the GLib object
|
||||
* @param conn The database connection to use
|
||||
* @param tour The tour to edit
|
||||
*/
|
||||
public TourEditor (Gtk.Application application, Connection conn, Tour? tour) {
|
||||
GLib.Object (application: application);
|
||||
this.conn = conn;
|
||||
this.tour = tour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize what is needed for this window
|
||||
*/
|
||||
public void initialize () {
|
||||
regions = Region.get_all_regiones (conn.db);
|
||||
|
||||
regions.sort_with_data ((a, b) => {
|
||||
return strcmp (a.nombre_region, b.nombre_region);
|
||||
});
|
||||
|
||||
region_list_store = new Gtk.ListStore (RegionColumn.N_COLUMNS,
|
||||
typeof (string),
|
||||
typeof (Region));
|
||||
|
||||
region.set_model (region_list_store);
|
||||
|
||||
if (tour != null) {
|
||||
tour_name.set_text (tour.nombre_tour);
|
||||
indiv_cost.set_text (tour.costo_indiv.to_string ());
|
||||
group_cost.set_text (tour.costo_grupal.to_string ());
|
||||
minimum_people.set_value (tour.minima_personas);
|
||||
}
|
||||
else {
|
||||
tour = new Tour ();
|
||||
tour.ciudad = new Ciudad ();
|
||||
tour.ciudad.region = new Region ();
|
||||
}
|
||||
|
||||
regions.foreach ((entry) => {
|
||||
Gtk.TreeIter iter;
|
||||
region_list_store.append (out iter);
|
||||
region_list_store.set (iter,
|
||||
RegionColumn.REGION_NAME, entry.nombre_region,
|
||||
RegionColumn.REGION, entry);
|
||||
if (entry.id_region == tour.ciudad.region.id_region) {
|
||||
region.set_active_iter (iter);
|
||||
}
|
||||
});
|
||||
|
||||
region.set_entry_text_column (RegionColumn.REGION_NAME);
|
||||
|
||||
city_list_store = new Gtk.ListStore (CityColumn.N_COLUMNS,
|
||||
typeof (string),
|
||||
typeof (Ciudad));
|
||||
|
||||
city.set_model (city_list_store);
|
||||
|
||||
cities = Ciudad.get_all_ciudades_in_region (conn.db, tour.ciudad.region.id_region);
|
||||
|
||||
if (cities.length () > 0) {
|
||||
cities.sort_with_data ((a, b) => {
|
||||
return strcmp (a.nombre_ciudad, b.nombre_ciudad);
|
||||
});
|
||||
|
||||
cities.foreach ((entry) => {
|
||||
Gtk.TreeIter iter;
|
||||
city_list_store.append (out iter);
|
||||
city_list_store.set (iter,
|
||||
CityColumn.CITY_NAME, entry.nombre_ciudad,
|
||||
CityColumn.CITY, entry);
|
||||
if (entry.id_ciudad == tour.ciudad.id_ciudad) {
|
||||
city.set_active_iter (iter);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
475
src/tour_list.vala
Normal file
475
src/tour_list.vala
Normal file
@@ -0,0 +1,475 @@
|
||||
/*
|
||||
* Copyright 2018-2019 Chris Cromer
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
namespace Sernatur {
|
||||
using LibSernatur.Misc;
|
||||
using LibSernatur.DB;
|
||||
|
||||
/**
|
||||
* The tour list window class
|
||||
*/
|
||||
[GtkTemplate (ui = "/cl/cromer/ubb/sernatur/tour.list.ui")]
|
||||
public class TourList : Gtk.ApplicationWindow {
|
||||
/**
|
||||
* The open database connection
|
||||
*/
|
||||
private Connection conn;
|
||||
/**
|
||||
* The columns of the tree view
|
||||
*/
|
||||
private enum Column {
|
||||
/**
|
||||
* The tour name
|
||||
*/
|
||||
TOUR_NAME,
|
||||
/**
|
||||
* The individual cost
|
||||
*/
|
||||
INDIV_COST,
|
||||
/**
|
||||
* The group cost
|
||||
*/
|
||||
GROUP_COST,
|
||||
/**
|
||||
* The minimum people
|
||||
*/
|
||||
MINIMUM_PEOPLE,
|
||||
/**
|
||||
* The name of the city
|
||||
*/
|
||||
CITY,
|
||||
/**
|
||||
* The name of the region
|
||||
*/
|
||||
REGION,
|
||||
/**
|
||||
* The tour object
|
||||
*/
|
||||
TOUR,
|
||||
/**
|
||||
* The number of colums in this enum
|
||||
*/
|
||||
N_COLUMNS
|
||||
}
|
||||
/**
|
||||
* The list that stores the contents in the tree view
|
||||
*/
|
||||
private Gtk.ListStore list_store;
|
||||
/**
|
||||
* The list of tours
|
||||
*/
|
||||
private List<Tour> tour_list;
|
||||
/**
|
||||
* The tree view widget
|
||||
*/
|
||||
[GtkChild]
|
||||
private Gtk.TreeView tour_tree;
|
||||
/**
|
||||
* Thew new tour button
|
||||
*/
|
||||
[GtkChild]
|
||||
private Gtk.Button new_tour;
|
||||
/**
|
||||
* The edit tour button
|
||||
*/
|
||||
[GtkChild]
|
||||
private Gtk.Button edit_tour;
|
||||
/**
|
||||
* The delete tour button
|
||||
*/
|
||||
[GtkChild]
|
||||
private Gtk.Button delete_tour;
|
||||
/**
|
||||
* The close tour button
|
||||
*/
|
||||
[GtkChild]
|
||||
private Gtk.Button close_tour;
|
||||
/**
|
||||
* The tour name column
|
||||
*/
|
||||
[GtkChild]
|
||||
private Gtk.TreeViewColumn tour_name;
|
||||
/**
|
||||
* The individual cost column
|
||||
*/
|
||||
[GtkChild]
|
||||
private Gtk.TreeViewColumn indiv_cost;
|
||||
/**
|
||||
* The group cost column
|
||||
*/
|
||||
[GtkChild]
|
||||
private Gtk.TreeViewColumn group_cost;
|
||||
/**
|
||||
* The minimum number of people column
|
||||
*/
|
||||
[GtkChild]
|
||||
private Gtk.TreeViewColumn minimum_people;
|
||||
/**
|
||||
* The city column
|
||||
*/
|
||||
[GtkChild]
|
||||
private Gtk.TreeViewColumn city;
|
||||
/**
|
||||
* The region column
|
||||
*/
|
||||
[GtkChild]
|
||||
private Gtk.TreeViewColumn region;
|
||||
/**
|
||||
* The row selection
|
||||
*/
|
||||
[GtkChild]
|
||||
private Gtk.TreeSelection selection;
|
||||
|
||||
/**
|
||||
* This callback is called when the user clicks on a row
|
||||
* @param selection The selection object
|
||||
*/
|
||||
[GtkCallback]
|
||||
private void on_changed_selection(Gtk.TreeSelection selection) {
|
||||
if (selection.count_selected_rows () > 0) {
|
||||
edit_tour.sensitive = true;
|
||||
delete_tour.sensitive =true;
|
||||
}
|
||||
else {
|
||||
edit_tour.sensitive = false;
|
||||
delete_tour.sensitive = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This callback is run when the user clicks on a button
|
||||
* @param button The button that was clicked
|
||||
*/
|
||||
[GtkCallback]
|
||||
private void on_clicked_button (Gtk.Button button) {
|
||||
if (button == new_tour) {
|
||||
var tour_editor = new TourEditor (application, conn, null);
|
||||
tour_editor.set_transient_for (this); // Set this window as the parent of the new window
|
||||
tour_editor.initialize ();
|
||||
tour_editor.show_all ();
|
||||
}
|
||||
else if (button == edit_tour) {
|
||||
Gtk.TreeModel model;
|
||||
Gtk.TreeIter iter;
|
||||
Tour tour;
|
||||
if (selection.get_selected (out model, out iter)) {
|
||||
model.get (iter,
|
||||
Column.TOUR, out tour);
|
||||
var tour_editor = new TourEditor (application, conn, tour);
|
||||
tour_editor.set_transient_for (this); // Set this window as the parent of the new window
|
||||
tour_editor.initialize ();
|
||||
tour_editor.show_all ();
|
||||
tour_editor.save_tour.connect (on_save);
|
||||
}
|
||||
}
|
||||
else if (button == delete_tour) {
|
||||
print ("Delete tour clicked\n");
|
||||
}
|
||||
else if (button == close_tour) {
|
||||
this.close ();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a new or old tour is saved
|
||||
* @param tour_editor The editor that saved the tour
|
||||
*/
|
||||
public void on_save(TourEditor tour_editor) {
|
||||
edit_tour.sensitive = false;
|
||||
delete_tour.sensitive = false;
|
||||
reset_columns ();
|
||||
|
||||
tour_list = Tour.get_all_tours (conn.db);
|
||||
|
||||
list_store.clear ();
|
||||
tour_list.foreach ((entry) => {
|
||||
Gtk.TreeIter iter;
|
||||
list_store.append (out iter);
|
||||
list_store.set (iter,
|
||||
Column.TOUR_NAME, entry.nombre_tour,
|
||||
Column.INDIV_COST, Money.format_uint (entry.costo_indiv),
|
||||
Column.GROUP_COST, Money.format_uint (entry.costo_grupal),
|
||||
Column.MINIMUM_PEOPLE, entry.minima_personas,
|
||||
Column.CITY, entry.ciudad.nombre_ciudad,
|
||||
Column.REGION, entry.ciudad.region.nombre_region,
|
||||
Column.TOUR, entry);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This callback is run when the user clicks on a column to reorder the rows
|
||||
* @param column The column that was clicked
|
||||
*/
|
||||
[GtkCallback]
|
||||
private void on_clicked_column (Gtk.TreeViewColumn column) {
|
||||
edit_tour.sensitive = false;
|
||||
delete_tour.sensitive = false;
|
||||
if (column == tour_name) {
|
||||
if (!tour_name.sort_indicator) {
|
||||
reset_columns ();
|
||||
tour_name.sort_indicator = true;
|
||||
}
|
||||
|
||||
if (tour_name.sort_order == Gtk.SortType.ASCENDING) {
|
||||
tour_name.sort_order = Gtk.SortType.DESCENDING;
|
||||
}
|
||||
else {
|
||||
tour_name.sort_order = Gtk.SortType.ASCENDING;
|
||||
}
|
||||
|
||||
tour_list.sort_with_data ((a, b) => {
|
||||
if (tour_name.sort_order == Gtk.SortType.ASCENDING) {
|
||||
return strcmp (a.nombre_tour, b.nombre_tour);
|
||||
}
|
||||
else {
|
||||
return strcmp (b.nombre_tour, a.nombre_tour);
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (column == indiv_cost) {
|
||||
if (!indiv_cost.sort_indicator) {
|
||||
reset_columns ();
|
||||
indiv_cost.sort_indicator = true;
|
||||
}
|
||||
|
||||
if (indiv_cost.sort_order == Gtk.SortType.ASCENDING) {
|
||||
indiv_cost.sort_order = Gtk.SortType.DESCENDING;
|
||||
}
|
||||
else {
|
||||
indiv_cost.sort_order = Gtk.SortType.ASCENDING;
|
||||
}
|
||||
|
||||
tour_list.sort_with_data ((a, b) => {
|
||||
if (indiv_cost.sort_order == Gtk.SortType.ASCENDING) {
|
||||
if (a.costo_indiv < b.costo_indiv) {
|
||||
return -1;
|
||||
}
|
||||
else if (a.costo_indiv == b.costo_indiv) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (a.costo_indiv < b.costo_indiv) {
|
||||
return 1;
|
||||
}
|
||||
else if (a.costo_indiv == b.costo_indiv) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (column == group_cost) {
|
||||
if (!group_cost.sort_indicator) {
|
||||
reset_columns ();
|
||||
group_cost.sort_indicator = true;
|
||||
}
|
||||
|
||||
if (group_cost.sort_order == Gtk.SortType.ASCENDING) {
|
||||
group_cost.sort_order = Gtk.SortType.DESCENDING;
|
||||
}
|
||||
else {
|
||||
group_cost.sort_order = Gtk.SortType.ASCENDING;
|
||||
}
|
||||
|
||||
tour_list.sort_with_data ((a, b) => {
|
||||
if (group_cost.sort_order == Gtk.SortType.ASCENDING) {
|
||||
if (a.costo_grupal < b.costo_grupal) {
|
||||
return -1;
|
||||
}
|
||||
else if (a.costo_grupal == b.costo_grupal) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (a.costo_grupal < b.costo_grupal) {
|
||||
return 1;
|
||||
}
|
||||
else if (a.costo_grupal == b.costo_grupal) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (column == minimum_people) {
|
||||
if (!minimum_people.sort_indicator) {
|
||||
reset_columns ();
|
||||
minimum_people.sort_indicator = true;
|
||||
}
|
||||
|
||||
if (minimum_people.sort_order == Gtk.SortType.ASCENDING) {
|
||||
minimum_people.sort_order = Gtk.SortType.DESCENDING;
|
||||
}
|
||||
else {
|
||||
minimum_people.sort_order = Gtk.SortType.ASCENDING;
|
||||
}
|
||||
|
||||
tour_list.sort_with_data ((a, b) => {
|
||||
if (minimum_people.sort_order == Gtk.SortType.ASCENDING) {
|
||||
if (a.minima_personas < b.minima_personas) {
|
||||
return -1;
|
||||
}
|
||||
else if (a.minima_personas == b.minima_personas) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (a.minima_personas < b.minima_personas) {
|
||||
return 1;
|
||||
}
|
||||
else if (a.minima_personas == b.minima_personas) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (column == city) {
|
||||
if (!city.sort_indicator) {
|
||||
reset_columns ();
|
||||
city.sort_indicator = true;
|
||||
}
|
||||
|
||||
if (city.sort_order == Gtk.SortType.ASCENDING) {
|
||||
city.sort_order = Gtk.SortType.DESCENDING;
|
||||
}
|
||||
else {
|
||||
city.sort_order = Gtk.SortType.ASCENDING;
|
||||
}
|
||||
|
||||
tour_list.sort_with_data ((a, b) => {
|
||||
if (city.sort_order == Gtk.SortType.ASCENDING) {
|
||||
return strcmp (a.ciudad.nombre_ciudad, b.ciudad.nombre_ciudad);
|
||||
}
|
||||
else {
|
||||
return strcmp (b.ciudad.nombre_ciudad, a.ciudad.nombre_ciudad);
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (column == region) {
|
||||
if (!region.sort_indicator) {
|
||||
reset_columns ();
|
||||
region.sort_indicator = true;
|
||||
}
|
||||
|
||||
if (region.sort_order == Gtk.SortType.ASCENDING) {
|
||||
region.sort_order = Gtk.SortType.DESCENDING;
|
||||
}
|
||||
else {
|
||||
region.sort_order = Gtk.SortType.ASCENDING;
|
||||
}
|
||||
|
||||
tour_list.sort_with_data ((a, b) => {
|
||||
if (region.sort_order == Gtk.SortType.ASCENDING) {
|
||||
return strcmp (a.ciudad.region.nombre_region, b.ciudad.region.nombre_region);
|
||||
}
|
||||
else {
|
||||
return strcmp (b.ciudad.region.nombre_region, a.ciudad.region.nombre_region);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
list_store.clear ();
|
||||
tour_list.foreach ((entry) => {
|
||||
Gtk.TreeIter iter;
|
||||
list_store.append (out iter);
|
||||
list_store.set (iter,
|
||||
Column.TOUR_NAME, entry.nombre_tour,
|
||||
Column.INDIV_COST, Money.format_uint (entry.costo_indiv),
|
||||
Column.GROUP_COST, Money.format_uint (entry.costo_grupal),
|
||||
Column.MINIMUM_PEOPLE, entry.minima_personas,
|
||||
Column.CITY, entry.ciudad.nombre_ciudad,
|
||||
Column.REGION, entry.ciudad.region.nombre_region,
|
||||
Column.TOUR, entry);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the sort indicator and order of all the columns
|
||||
*/
|
||||
private void reset_columns () {
|
||||
tour_name.sort_indicator = false;
|
||||
tour_name.sort_order = Gtk.SortType.DESCENDING;
|
||||
indiv_cost.sort_indicator = false;
|
||||
indiv_cost.sort_order = Gtk.SortType.DESCENDING;
|
||||
group_cost.sort_indicator = false;
|
||||
group_cost.sort_order = Gtk.SortType.DESCENDING;
|
||||
minimum_people.sort_indicator = false;
|
||||
minimum_people.sort_order = Gtk.SortType.DESCENDING;
|
||||
city.sort_indicator = false;
|
||||
city.sort_order = Gtk.SortType.DESCENDING;
|
||||
region.sort_indicator = false;
|
||||
region.sort_order = Gtk.SortType.DESCENDING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the tour list class
|
||||
* @param application The application used to make the GLib object
|
||||
* @param conn The database connection to use
|
||||
*/
|
||||
public TourList (Gtk.Application application, Connection conn) {
|
||||
GLib.Object (application: application);
|
||||
this.conn = conn;
|
||||
|
||||
this.set_visible (true); // This fixes: Gtk-CRITICAL **: 23:58:22.139: gtk_box_gadget_distribute: assertion 'size >= 0' failed in GtkScrollbar
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize what is needed for this window
|
||||
*/
|
||||
public void initialize () {
|
||||
list_store = new Gtk.ListStore (Column.N_COLUMNS,
|
||||
typeof (string),
|
||||
typeof (string),
|
||||
typeof (string),
|
||||
typeof (uint),
|
||||
typeof (string),
|
||||
typeof (string),
|
||||
typeof (Tour));
|
||||
|
||||
tour_list = Tour.get_all_tours (conn.db);
|
||||
|
||||
tour_list.foreach ((entry) => {
|
||||
Gtk.TreeIter iter;
|
||||
list_store.append (out iter);
|
||||
list_store.set (iter,
|
||||
Column.TOUR_NAME, entry.nombre_tour,
|
||||
Column.INDIV_COST, Money.format_uint (entry.costo_indiv),
|
||||
Column.GROUP_COST, Money.format_uint (entry.costo_grupal),
|
||||
Column.MINIMUM_PEOPLE, entry.minima_personas,
|
||||
Column.CITY, entry.ciudad.nombre_ciudad,
|
||||
Column.REGION, entry.ciudad.region.nombre_region,
|
||||
Column.TOUR, entry);
|
||||
});
|
||||
|
||||
tour_tree.set_model (list_store);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,139 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018-2019 Chris Cromer
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
namespace Sernatur {
|
||||
using LibSernatur.Person;
|
||||
using LibSernatur.DB;
|
||||
|
||||
/**
|
||||
* The TourWindow class
|
||||
*/
|
||||
[GtkTemplate (ui = "/cl/cromer/ubb/sernatur/tour.window.ui")]
|
||||
public class TourWindow : Gtk.ApplicationWindow {
|
||||
/**
|
||||
* The open database connection
|
||||
*/
|
||||
private unowned Postgres.Database conn;
|
||||
/**
|
||||
* The columns of the tree view
|
||||
*/
|
||||
private enum Columns {
|
||||
/**
|
||||
* The toggle
|
||||
*/
|
||||
TOGGLE,
|
||||
/**
|
||||
* The tour name
|
||||
*/
|
||||
TOUR_NAME,
|
||||
/**
|
||||
* The individual cost
|
||||
*/
|
||||
INDIV_COST,
|
||||
/**
|
||||
* The group cost
|
||||
*/
|
||||
GROUP_COST,
|
||||
/**
|
||||
* The minimum people
|
||||
*/
|
||||
MINIMUM_PEOPLE,
|
||||
/**
|
||||
* The name of the city
|
||||
*/
|
||||
CITY,
|
||||
/**
|
||||
* The name of the region
|
||||
*/
|
||||
REGION,
|
||||
/**
|
||||
* The number of colums in this enum
|
||||
*/
|
||||
N_COLUMNS
|
||||
}
|
||||
/**
|
||||
* The list that stores the contents in the tree view
|
||||
*/
|
||||
private Gtk.ListStore list_store;
|
||||
/**
|
||||
* The tree view widget
|
||||
*/
|
||||
[GtkChild]
|
||||
private Gtk.TreeView tour_tree;
|
||||
|
||||
/**
|
||||
* This callback is called when the user clicks a radio button next to a row
|
||||
* @param toggle The toggle clicked
|
||||
* @param path The row clicked
|
||||
*/
|
||||
[GtkCallback]
|
||||
private void toggled(Gtk.CellRendererToggle toggle, string path) {
|
||||
Gtk.TreeModelForeachFunc deselect_all = (model, path, iter) => {
|
||||
list_store.set (iter, Columns.TOGGLE, false);
|
||||
return false;
|
||||
};
|
||||
|
||||
// Backup the previous state
|
||||
var tree_path = new Gtk.TreePath.from_string (path);
|
||||
Gtk.TreeIter iter;
|
||||
bool old_val;
|
||||
list_store.get_iter (out iter, tree_path);
|
||||
list_store.get (iter, Columns.TOGGLE, out old_val);
|
||||
|
||||
// Deselect all states
|
||||
list_store.foreach (deselect_all);
|
||||
|
||||
// Invert previous state
|
||||
list_store.get_iter (out iter, tree_path);
|
||||
list_store.set (iter, Columns.TOGGLE, !old_val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the tour window class
|
||||
* @param application The application used to make the GLib object
|
||||
* @param conn The database connection to use
|
||||
*/
|
||||
public TourWindow (Gtk.Application application, Postgres.Database conn) {
|
||||
GLib.Object (application: application);
|
||||
this.conn = conn;
|
||||
|
||||
this.set_visible (true); // This fixes: Gtk-CRITICAL **: 23:58:22.139: gtk_box_gadget_distribute: assertion 'size >= 0' failed in GtkScrollbar
|
||||
|
||||
list_store = new Gtk.ListStore (Columns.N_COLUMNS,
|
||||
typeof (bool),
|
||||
typeof (string),
|
||||
typeof (string),
|
||||
typeof (string),
|
||||
typeof (uint),
|
||||
typeof (string),
|
||||
typeof (string));
|
||||
|
||||
Gtk.TreeIter iter;
|
||||
var tour = Tour.get_all_tours (conn);
|
||||
for (int i = 0; i < tour.length - 1; i++) {
|
||||
list_store.append (out iter);
|
||||
list_store.set (iter,
|
||||
Columns.TOGGLE, false,
|
||||
Columns.TOUR_NAME, tour[i].nombre_tour,
|
||||
Columns.INDIV_COST, tour[i].costo_indiv.to_string (),
|
||||
Columns.GROUP_COST, tour[i].costo_grupal.to_string (),
|
||||
Columns.MINIMUM_PEOPLE, tour[i].minima_personas,
|
||||
Columns.CITY, tour[i].ciudad.nombre_ciudad,
|
||||
Columns.REGION, tour[i].ciudad.region.nombre_region);
|
||||
}
|
||||
|
||||
tour_tree.set_model (list_store);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user