a lot of changes

This commit is contained in:
Chris Cromer 2019-01-13 19:53:13 -03:00
parent c1cb9c5c00
commit f1c5b4e0a9
Signed by: cromer
GPG Key ID: 39CC813FF3C8708A
27 changed files with 2432 additions and 451 deletions

View File

@ -21,9 +21,9 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
<property name="title">SERNATUR</property> <property name="title">SERNATUR</property>
<property name="window_position">center</property> <property name="window_position">center</property>
<property name="icon_name">sernatur</property> <property name="icon_name">sernatur</property>
<signal name="configure-event" handler="resize_window" swapped="no"/> <signal name="configure-event" handler="on_configure_event" swapped="no"/>
<signal name="destroy" handler="window_quit" swapped="no"/> <signal name="destroy" handler="on_destroy" swapped="no"/>
<signal name="window-state-event" handler="maximize_window" swapped="no"/> <signal name="window-state-event" handler="on_window_state_event" swapped="no"/>
<child> <child>
<placeholder/> <placeholder/>
</child> </child>
@ -48,41 +48,52 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<child> <child>
<object class="GtkMenuItem"> <object class="GtkMenuItem" id="tours">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="label" translatable="yes">Tours</property> <property name="label" translatable="yes">Tours</property>
<signal name="activate" handler="menu_tours" swapped="no"/> <signal name="activate" handler="on_activate_menu" swapped="no"/>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem"> <object class="GtkMenuItem" id="places">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Places</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="staff">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="label" translatable="yes">Staff</property> <property name="label" translatable="yes">Staff</property>
<signal name="activate" handler="on_activate_menu" swapped="no"/>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem"> <object class="GtkMenuItem" id="tourists">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="label" translatable="yes">Tourists</property> <property name="label" translatable="yes">Tourists</property>
<signal name="activate" handler="on_activate_menu" swapped="no"/>
<child type="submenu"> <child type="submenu">
<object class="GtkMenu"> <object class="GtkMenu">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<child> <child>
<object class="GtkMenuItem"> <object class="GtkMenuItem" id="illnesses">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="label" translatable="yes">Illnesses</property> <property name="label" translatable="yes">Illnesses</property>
<signal name="activate" handler="on_activate_menu" swapped="no"/>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem"> <object class="GtkMenuItem" id="participate">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="label" translatable="yes">Participate</property> <property name="label" translatable="yes">Participate</property>
<signal name="activate" handler="on_activate_menu" swapped="no"/>
</object> </object>
</child> </child>
</object> </object>
@ -90,10 +101,11 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem"> <object class="GtkMenuItem" id="vehicles">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="label" translatable="yes">Vehicles</property> <property name="label" translatable="yes">Vehicles</property>
<signal name="activate" handler="on_activate_menu" swapped="no"/>
</object> </object>
</child> </child>
<child> <child>
@ -103,11 +115,11 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem"> <object class="GtkMenuItem" id="quit">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="label" translatable="yes">Quit</property> <property name="label" translatable="yes">Quit</property>
<signal name="activate" handler="menu_quit" swapped="no"/> <signal name="activate" handler="on_activate_menu" swapped="no"/>
</object> </object>
</child> </child>
</object> </object>
@ -125,38 +137,43 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<child> <child>
<object class="GtkMenuItem"> <object class="GtkMenuItem" id="q1">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="label" translatable="yes">(Q1) Regions with discounts</property> <property name="label" translatable="yes">(Q1) Regions with discounts</property>
<signal name="activate" handler="on_activate_menu" swapped="no"/>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem"> <object class="GtkMenuItem" id="q2">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="label" translatable="yes">(Q2) Tour values</property> <property name="label" translatable="yes">(Q2) Tour values</property>
<signal name="activate" handler="on_activate_menu" swapped="no"/>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem"> <object class="GtkMenuItem" id="q3">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="label" translatable="yes">(Q3) Coordinator total</property> <property name="label" translatable="yes">(Q3) Coordinator total</property>
<signal name="activate" handler="on_activate_menu" swapped="no"/>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem"> <object class="GtkMenuItem" id="q4">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="label" translatable="yes">(Q4) Tourist total</property> <property name="label" translatable="yes">(Q4) Tourist total</property>
<signal name="activate" handler="on_activate_menu" swapped="no"/>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem"> <object class="GtkMenuItem" id="q5">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="label" translatable="yes">(Q5) Vehicle total</property> <property name="label" translatable="yes">(Q5) Vehicle total</property>
<signal name="activate" handler="on_activate_menu" swapped="no"/>
</object> </object>
</child> </child>
</object> </object>

View File

@ -11,3 +11,9 @@ tour_gresource = gnome.compile_resources('tour_gresource',
c_name: meson.project_name() + '_resource_tour', c_name: meson.project_name() + '_resource_tour',
export: true, export: true,
install_header: true) install_header: true)
query_gresource = gnome.compile_resources('query_gresource',
'query.gresource.xml',
source_dir: '.',
c_name: meson.project_name() + '_resource_query',
export: true,
install_header: true)

59
data/ui/query.1.ui Normal file
View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1
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.
-->
<interface domain="sernatur">
<requires lib="gtk+" version="3.20"/>
<object class="GtkTreeView" id="query_tree">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="hscroll_policy">natural</property>
<property name="vscroll_policy">natural</property>
<property name="fixed_height_mode">True</property>
<property name="enable_grid_lines">both</property>
<property name="enable_tree_lines">True</property>
<child internal-child="selection">
<object class="GtkTreeSelection">
<property name="mode">none</property>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="region_name">
<property name="sizing">fixed</property>
<property name="title" translatable="yes">Region Name</property>
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="markup">0</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="quantity">
<property name="sizing">fixed</property>
<property name="title" translatable="yes">Quantity</property>
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="markup">1</attribute>
</attributes>
</child>
</object>
</child>
</object>
</interface>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<gresources>
<gresource prefix="/cl/cromer/ubb/sernatur">
<file preprocess="xml-stripblanks">query.window.ui</file>
<file preprocess="xml-stripblanks">query.1.ui</file>
</gresource>
</gresources>

243
data/ui/query.window.ui Normal file
View File

@ -0,0 +1,243 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1
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.
-->
<interface domain="sernatur">
<requires lib="gtk+" version="3.20"/>
<template class="SernaturQueryWindow" parent="GtkApplicationWindow">
<property name="can_focus">False</property>
<property name="type">popup</property>
<property name="modal">True</property>
<property name="window_position">center</property>
<property name="default_width">640</property>
<property name="default_height">480</property>
<property name="destroy_with_parent">True</property>
<property name="icon_name">sernatur</property>
<property name="type_hint">dialog</property>
<property name="skip_taskbar_hint">True</property>
<property name="skip_pager_hint">True</property>
<property name="show_menubar">False</property>
<child type="titlebar">
<placeholder/>
</child>
<child>
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<child>
<object class="GtkScrolledWindow" id="scroll_window">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="halign">center</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="hscrollbar_policy">never</property>
<property name="shadow_type">in</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="hexpand">True</property>
<property name="spacing">25</property>
<child>
<object class="GtkButton" id="close_query">
<property name="label" translatable="yes">Close</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<signal name="clicked" handler="on_clicked_button" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="run_query">
<property name="label" translatable="yes">Run</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<signal name="clicked" handler="on_clicked_button" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<child>
<object class="GtkFrame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0</property>
<property name="label_yalign">0</property>
<property name="shadow_type">out</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="label" translatable="yes">Statement</property>
<attributes>
<attribute name="font-desc" value="Sans Bold 6"/>
</attributes>
</object>
</child>
<child type="label_item">
<placeholder/>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkFrame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0</property>
<property name="label_yalign">0</property>
<property name="shadow_type">out</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="label" translatable="yes">View and Query</property>
<attributes>
<attribute name="font-desc" value="Sans Bold 6"/>
</attributes>
</object>
</child>
<child type="label_item">
<placeholder/>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkFrame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="label_xalign">0</property>
<property name="label_yalign">0</property>
<property name="shadow_type">out</property>
<child>
<object class="GtkLabel" id="statement">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<attributes>
<attribute name="font-desc" value="Sans 6"/>
</attributes>
</object>
</child>
<child type="label_item">
<placeholder/>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkFrame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="label_xalign">0</property>
<property name="label_yalign">0</property>
<property name="shadow_type">out</property>
<child>
<object class="GtkLabel" id="sql">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<attributes>
<attribute name="font-desc" value="Monospace 6"/>
</attributes>
</object>
</child>
<child type="label_item">
<placeholder/>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
</object>
</child>
</template>
</interface>

333
data/ui/tour.editor.ui Normal file
View File

@ -0,0 +1,333 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1
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.
-->
<interface domain="sernatur">
<requires lib="gtk+" version="3.20"/>
<object class="GtkAdjustment" id="minimum_people_adjustment">
<property name="lower">1</property>
<property name="upper">1000</property>
<property name="value">1</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<template class="SernaturTourEditor" parent="GtkApplicationWindow">
<property name="can_focus">False</property>
<property name="type">popup</property>
<property name="title" translatable="yes">Tour Editor</property>
<property name="modal">True</property>
<property name="window_position">center</property>
<property name="destroy_with_parent">True</property>
<property name="icon_name">sernatur</property>
<property name="type_hint">dialog</property>
<property name="skip_taskbar_hint">True</property>
<property name="skip_pager_hint">True</property>
<property name="show_menubar">False</property>
<child>
<placeholder/>
</child>
<child>
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="label" translatable="yes">Tour Name</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="tour_name">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="hexpand">True</property>
<property name="max_length">50</property>
<property name="caps_lock_warning">False</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="label" translatable="yes">Individual Cost</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="label" translatable="yes">Group Cost</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="label" translatable="yes">Minimum People</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="label" translatable="yes">Region</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">4</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="indiv_cost">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="hexpand">True</property>
<property name="max_length">10</property>
<property name="caps_lock_warning">False</property>
<property name="input_purpose">number</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="group_cost">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="hexpand">True</property>
<property name="max_length">10</property>
<property name="caps_lock_warning">False</property>
<property name="input_purpose">number</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="label" translatable="yes">City</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">5</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="minimum_people">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="hexpand">True</property>
<property name="max_length">4</property>
<property name="width_chars">4</property>
<property name="caps_lock_warning">False</property>
<property name="input_purpose">digits</property>
<property name="adjustment">minimum_people_adjustment</property>
<property name="snap_to_ticks">True</property>
<property name="numeric">True</property>
<property name="update_policy">if-valid</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkComboBoxText" id="region">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="focus_on_click">False</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="hexpand">True</property>
<property name="has_entry">True</property>
<property name="popup_fixed_width">False</property>
<signal name="changed" handler="on_changed_combobox" swapped="no"/>
<child internal-child="entry">
<object class="GtkEntry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">Create a new region by typing here.</property>
<property name="hexpand">True</property>
<property name="max_length">50</property>
<property name="caps_lock_warning">False</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">4</property>
</packing>
</child>
<child>
<object class="GtkComboBoxText" id="city">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="focus_on_click">False</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="hexpand">True</property>
<property name="has_entry">True</property>
<property name="popup_fixed_width">False</property>
<child internal-child="entry">
<object class="GtkEntry" id="city_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">Create a new city by typing here.</property>
<property name="hexpand">True</property>
<property name="max_length">50</property>
<property name="caps_lock_warning">False</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">5</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="hexpand">True</property>
<property name="spacing">25</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkButton" id="cancel">
<property name="label" translatable="yes">Cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Cancel the modification of this tour.</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<signal name="clicked" handler="on_clicked_button" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="save">
<property name="label" translatable="yes">Save</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Save this tour.</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<signal name="clicked" handler="on_clicked_button" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">6</property>
<property name="width">2</property>
</packing>
</child>
</object>
</child>
</template>
</interface>

View File

@ -14,6 +14,7 @@
--> -->
<gresources> <gresources>
<gresource prefix="/cl/cromer/ubb/sernatur"> <gresource prefix="/cl/cromer/ubb/sernatur">
<file preprocess="xml-stripblanks">tour.window.ui</file> <file preprocess="xml-stripblanks">tour.list.ui</file>
<file preprocess="xml-stripblanks">tour.editor.ui</file>
</gresource> </gresource>
</gresources> </gresources>

View File

@ -16,13 +16,16 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
--> -->
<interface domain="sernatur"> <interface domain="sernatur">
<requires lib="gtk+" version="3.20"/> <requires lib="gtk+" version="3.20"/>
<template class="SernaturTourWindow" parent="GtkApplicationWindow"> <template class="SernaturTourList" parent="GtkApplicationWindow">
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="type">popup</property> <property name="type">popup</property>
<property name="title" translatable="yes">Tours</property>
<property name="modal">True</property> <property name="modal">True</property>
<property name="window_position">center-on-parent</property> <property name="window_position">center</property>
<property name="default_height">480</property>
<property name="destroy_with_parent">True</property> <property name="destroy_with_parent">True</property>
<property name="icon_name">sernatur</property> <property name="icon_name">sernatur</property>
<property name="type_hint">dialog</property>
<property name="skip_taskbar_hint">True</property> <property name="skip_taskbar_hint">True</property>
<property name="skip_pager_hint">True</property> <property name="skip_pager_hint">True</property>
<property name="show_menubar">False</property> <property name="show_menubar">False</property>
@ -35,8 +38,6 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
<property name="can_focus">True</property> <property name="can_focus">True</property>
<child> <child>
<object class="GtkScrolledWindow"> <object class="GtkScrolledWindow">
<property name="width_request">-1</property>
<property name="height_request">-1</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="hexpand">True</property> <property name="hexpand">True</property>
@ -56,30 +57,29 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
<property name="enable_tree_lines">True</property> <property name="enable_tree_lines">True</property>
<child internal-child="selection"> <child internal-child="selection">
<object class="GtkTreeSelection" id="selection"> <object class="GtkTreeSelection" id="selection">
<property name="mode">none</property> <signal name="changed" handler="on_changed_selection" swapped="no"/>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkTreeViewColumn"> <object class="GtkTreeViewColumn" id="tour_name">
<property name="sizing">fixed</property> <property name="sizing">fixed</property>
<property name="title" translatable="yes">Tour Name</property>
<property name="clickable">True</property> <property name="clickable">True</property>
<signal name="clicked" handler="on_clicked_column" swapped="no"/>
<child> <child>
<object class="GtkCellRendererToggle"> <object class="GtkCellRendererText"/>
<property name="radio">True</property>
<signal name="toggled" handler="toggled" swapped="no"/>
</object>
<attributes> <attributes>
<attribute name="active">0</attribute> <attribute name="markup">0</attribute>
</attributes> </attributes>
</child> </child>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkTreeViewColumn"> <object class="GtkTreeViewColumn" id="indiv_cost">
<property name="sizing">fixed</property> <property name="sizing">fixed</property>
<property name="title">Tour Name</property> <property name="title" translatable="yes">Individual Cost</property>
<property name="clickable">True</property> <property name="clickable">True</property>
<property name="sort_indicator">True</property> <signal name="clicked" handler="on_clicked_column" swapped="no"/>
<child> <child>
<object class="GtkCellRendererText"/> <object class="GtkCellRendererText"/>
<attributes> <attributes>
@ -89,11 +89,11 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
</object> </object>
</child> </child>
<child> <child>
<object class="GtkTreeViewColumn"> <object class="GtkTreeViewColumn" id="group_cost">
<property name="sizing">fixed</property> <property name="sizing">fixed</property>
<property name="title" translatable="yes">Individual Cost</property> <property name="title" translatable="yes">Group Cost</property>
<property name="clickable">True</property> <property name="clickable">True</property>
<property name="sort_indicator">True</property> <signal name="clicked" handler="on_clicked_column" swapped="no"/>
<child> <child>
<object class="GtkCellRendererText"/> <object class="GtkCellRendererText"/>
<attributes> <attributes>
@ -103,11 +103,11 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
</object> </object>
</child> </child>
<child> <child>
<object class="GtkTreeViewColumn"> <object class="GtkTreeViewColumn" id="minimum_people">
<property name="sizing">fixed</property> <property name="sizing">fixed</property>
<property name="title" translatable="yes">Group Cost</property> <property name="title" translatable="yes">Minimum People</property>
<property name="clickable">True</property> <property name="clickable">True</property>
<property name="sort_indicator">True</property> <signal name="clicked" handler="on_clicked_column" swapped="no"/>
<child> <child>
<object class="GtkCellRendererText"/> <object class="GtkCellRendererText"/>
<attributes> <attributes>
@ -117,11 +117,11 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
</object> </object>
</child> </child>
<child> <child>
<object class="GtkTreeViewColumn"> <object class="GtkTreeViewColumn" id="city">
<property name="sizing">fixed</property> <property name="sizing">fixed</property>
<property name="title" translatable="yes">Minimum People</property> <property name="title" translatable="yes">City</property>
<property name="clickable">True</property> <property name="clickable">True</property>
<property name="sort_indicator">True</property> <signal name="clicked" handler="on_clicked_column" swapped="no"/>
<child> <child>
<object class="GtkCellRendererText"/> <object class="GtkCellRendererText"/>
<attributes> <attributes>
@ -131,11 +131,11 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
</object> </object>
</child> </child>
<child> <child>
<object class="GtkTreeViewColumn"> <object class="GtkTreeViewColumn" id="region">
<property name="sizing">fixed</property> <property name="sizing">fixed</property>
<property name="title" translatable="yes">City</property> <property name="title" translatable="yes">Region</property>
<property name="clickable">True</property> <property name="clickable">True</property>
<property name="sort_indicator">True</property> <signal name="clicked" handler="on_clicked_column" swapped="no"/>
<child> <child>
<object class="GtkCellRendererText"/> <object class="GtkCellRendererText"/>
<attributes> <attributes>
@ -144,20 +144,6 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
</child> </child>
</object> </object>
</child> </child>
<child>
<object class="GtkTreeViewColumn">
<property name="sizing">fixed</property>
<property name="title" translatable="yes">Region</property>
<property name="clickable">True</property>
<property name="sort_indicator">True</property>
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="markup">6</attribute>
</attributes>
</child>
</object>
</child>
</object> </object>
</child> </child>
</object> </object>
@ -170,34 +156,36 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
<object class="GtkGrid"> <object class="GtkGrid">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="valign">end</property> <property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="hexpand">True</property> <property name="hexpand">True</property>
<property name="column_spacing">25</property>
<property name="column_homogeneous">True</property>
<child> <child>
<object class="GtkButton"> <object class="GtkButton" id="edit_tour">
<property name="label" translatable="yes">New</property> <property name="label" translatable="yes">Edit</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="margin_left">5</property> <property name="tooltip_text" translatable="yes">Edit selected tour.</property>
<property name="margin_right">5</property> <signal name="clicked" handler="on_clicked_button" swapped="no"/>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
</object> </object>
<packing> <packing>
<property name="left_attach">2</property> <property name="left_attach">1</property>
<property name="top_attach">0</property> <property name="top_attach">0</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkButton"> <object class="GtkButton" id="new_tour">
<property name="label" translatable="yes">Edit</property> <property name="label" translatable="yes">New</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="margin_left">5</property> <property name="tooltip_text" translatable="yes">Create a new tour.</property>
<property name="margin_right">5</property> <signal name="clicked" handler="on_clicked_button" swapped="no"/>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
</object> </object>
<packing> <packing>
<property name="left_attach">0</property> <property name="left_attach">0</property>
@ -205,7 +193,32 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
</packing> </packing>
</child> </child>
<child> <child>
<placeholder/> <object class="GtkButton" id="delete_tour">
<property name="label" translatable="yes">Delete</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Delete selected tour.</property>
<property name="halign">baseline</property>
<signal name="clicked" handler="on_clicked_button" swapped="no"/>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="close_tour">
<property name="label" translatable="yes">Close</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="on_clicked_button" swapped="no"/>
</object>
<packing>
<property name="left_attach">3</property>
<property name="top_attach">0</property>
</packing>
</child> </child>
</object> </object>
<packing> <packing>

71
lib/db.vala Normal file
View File

@ -0,0 +1,71 @@
/*
* 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.
*/
/**
* The sernatur library
*/
namespace LibSernatur {
/**
* Sernatur database library
*/
namespace DB {
using Postgres;
/**
* The errors that can be thrown by Postgresql
*/
public errordomain PostgresError {
/**
* Connection error
*/
CONNECT
}
public errordomain DBError {
/**
* Invalid value
*/
INVALID_VALUE
}
/**
* Class to handle database connections
*/
public class Connection : GLib.Object {
/**
* The database connection
*/
public Database db;
/**
* Initialize the connection
* @param host The hostname
* @param port The port
* @param options The extra options to use
* @param tty The terminal to send output to, this is ignored
* @param database The database
* @param username The username
* @param password The password
* @throws PostgresError The error thrown when connection fails
*/
public Connection (string host, string port, string options, string tty, string database, string username, string password) throws PostgresError {
db = set_db_login (host, port, options, tty, database, username, password);
if (db.get_status () != Postgres.ConnectionStatus.OK) {
throw new PostgresError.CONNECT (db.get_error_message ());
}
GLib.print (dgettext (null, "Postgresql server version:") + " %d\n", db.get_server_version ());
}
}
}
}

View File

@ -90,6 +90,53 @@ JOIN region R ON (C.id_region = R.id_region)
} }
return list; return list;
} }
/**
* Get all tuples and fields from database that are within a certain region
* @param conn The database connection to use
* @param region_id The id of the region to filter that results
* @return Returns a list of Ciudad
*/
public static List<Ciudad> get_all_ciudades_in_region(Database conn, uint region_id) {
var res = conn.exec ("
SELECT C.id_ciudad, C.nombre_ciudad,
R.id_region, R.nombre_region
FROM ciudad C
JOIN region R ON (C.id_region = R.id_region)
WHERE (R.id_region = " + region_id.to_string () + ")
");
if (res.get_status () != ExecStatus.TUPLES_OK) {
#if DEBUG
error (conn.get_error_message ());
#else
warning (conn.get_error_message ());
return new List<Ciudad> ();
#endif
}
var wra = new ResultWrapper (res);
List<Ciudad> list = new List<Ciudad> ();
int n = res.get_n_tuples ();
for (int i = 0; i < n; i++) {
try {
var ciudad = new Ciudad (wra.get_int_n (i, "id_ciudad"),
wra.get_string_n (i, "nombre_ciudad"),
new Region (wra.get_int_n (i, "id_region"),
wra.get_string_n (i, "nombre_region")
)
);
list.append (ciudad);
}
catch (Error e) {
#if DEBUG
error (e.message);
#else
warning (e.message);
#endif
}
}
return list;
}
} }
} }
} }

View File

@ -0,0 +1,82 @@
/*
* 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 LibSernatur {
namespace DB {
using Postgres;
using Wrapper;
/**
* The Region class based on the database table
*/
public class RegionesSinDescuento : GLib.Object {
/**
* The name of the region
*/
public string nombre_region { get; set; default = ""; }
/**
* The quanity
*/
public uint cantidad { get; set; default = 0; }
/**
* Initialize the RegionSinDuscuento class
* @param nombre_region The region name
*/
public RegionesSinDescuento (string nombre_region = "", uint cantidad) {
this.nombre_region = nombre_region;
this.cantidad = cantidad;
}
/**
* Get all tuples and fields from database
* @param conn The database connection to use
* @return Returns a list of RegionesSinDescuento
*/
public static List<RegionesSinDescuento> get_regions(Database conn) {
var res = conn.exec ("
SELECT nombreRegion, cantidad FROM REGIONES_SINDESCUENTO WHERE (cantidad = (SELECT MAX(cantidad) FROM REGIONES_SINDESCUENTO))
");
if (res.get_status () != ExecStatus.TUPLES_OK) {
#if DEBUG
error (conn.get_error_message ());
#else
warning (conn.get_error_message ());
return new List<RegionesSinDescuento> ();
#endif
}
var wra = new ResultWrapper (res);
List<RegionesSinDescuento> list = new List<RegionesSinDescuento> ();
int n = res.get_n_tuples ();
for (int i = 0; i < n; i++) {
try {
var region_sin_descuento = new RegionesSinDescuento (wra.get_string_n (i, "nombreRegion"),
wra.get_int_n (i, "cantidad")
);
list.append (region_sin_descuento);
}
catch (Error e) {
#if DEBUG
error (e.message);
#else
warning (e.message);
#endif
}
}
return list;
}
}
}
}

View File

@ -70,14 +70,7 @@ namespace LibSernatur {
* @return Returns a list of Tour * @return Returns a list of Tour
*/ */
public static List<Tour> get_all_tours(Database conn) { public static List<Tour> get_all_tours(Database conn) {
var res = conn.exec (" var res = conn.exec (Query.get_query (Query.Type.SELECT_ALL_TOURS, null));
SELECT T.id_tour, T.nombre_tour, T.costo_indiv, T.costo_grupal, T.minima_personas,
C.id_ciudad, C.nombre_ciudad,
R.id_region, R.nombre_region
FROM tour T
JOIN ciudad C ON (T.id_ciudad = C.id_ciudad)
JOIN region R ON (C.id_region = R.id_region)
");
if (res.get_status () != ExecStatus.TUPLES_OK) { if (res.get_status () != ExecStatus.TUPLES_OK) {
#if DEBUG #if DEBUG
error (conn.get_error_message ()); error (conn.get_error_message ());
@ -116,6 +109,26 @@ JOIN region R ON (C.id_region = R.id_region)
} }
return list; return list;
} }
/**
* Update a tour in the database
* @param tour The tour to update
* @return Returns true if updated
* @throws DBError Thrown if the data in the object is invalid
*/
public static void update_tour (Database conn, Tour tour) throws DBError {
if (tour.id_tour == 0) {
throw new DBError.INVALID_VALUE (dgettext (null, "The id of the tour is invalid!"));
}
var res = conn.exec (Query.get_query (Query.Type.UPDATE_TOUR, tour));
if (res.get_status () != ExecStatus.COMMAND_OK) {
#if DEBUG
error (conn.get_error_message ());
#else
warning (conn.get_error_message ());
#endif
}
}
} }
} }
} }

View File

@ -12,13 +12,7 @@
* 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. * 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.
*/ */
/**
* The sernatur library
*/
namespace LibSernatur { namespace LibSernatur {
/**
* Sernatur database library
*/
namespace DB { namespace DB {
/** /**
* This is a wrapper for Postgres that allows easier use of the database * This is a wrapper for Postgres that allows easier use of the database
@ -30,6 +24,9 @@ namespace LibSernatur {
* The errors that can be thrown by fields in the database * The errors that can be thrown by fields in the database
*/ */
public errordomain Field { public errordomain Field {
/**
* Field was not found in table
*/
NOTFOUND NOTFOUND
} }

View File

@ -3,8 +3,10 @@ gobject_dep = dependency('gobject-2.0')
pq_dep = dependency('libpq', version: '>=9.0') pq_dep = dependency('libpq', version: '>=9.0')
lib_sources = files( lib_sources = files(
'db.vala',
'dbwrapper.vala', 'dbwrapper.vala',
'rut.vala', 'misc.vala',
'queries.vala',
'db/arrienda.vala', 'db/arrienda.vala',
'db/asociado.vala', 'db/asociado.vala',
'db/categoria.vala', 'db/categoria.vala',
@ -20,6 +22,7 @@ lib_sources = files(
'db/posee.vala', 'db/posee.vala',
'db/realiza.vala', 'db/realiza.vala',
'db/region.vala', 'db/region.vala',
'db/regiones_sin_descuento.vala',
'db/requerir_auto.vala', 'db/requerir_auto.vala',
'db/tiene_enfermedad.vala', 'db/tiene_enfermedad.vala',
'db/tour.vala', 'db/tour.vala',

View File

@ -16,7 +16,7 @@ namespace LibSernatur {
/** /**
* The person name space * The person name space
*/ */
namespace Person { namespace Misc {
/** /**
* The errors that can be thrown by the Rut class * The errors that can be thrown by the Rut class
@ -36,6 +36,56 @@ namespace LibSernatur {
INVALIDVERIFIER INVALIDVERIFIER
} }
public class Money : GLib.Object {
public static string format_int (uint value) {
string money = "";
string temp_money = value.to_string ().reverse ();
int money_length = temp_money.length;
for (int i = 0; i < money_length; i++) {
money = money + temp_money.get_char(i).to_string ();
if ((i + 1) % 3 == 0) {
if (i != money_length - 1) {
money = money + ".";
}
}
}
money = money.reverse ();
return "$" + money;
}
public static string format_uint (uint value) {
string money = "";
string temp_money = value.to_string ().reverse ();
int money_length = temp_money.length;
for (int i = 0; i < money_length; i++) {
money = money + temp_money.get_char(i).to_string ();
if ((i + 1) % 3 == 0) {
if (i != money_length - 1) {
money = money + ".";
}
}
}
money = money.reverse ();
return "$" + money;
}
public static string format_string (string value) {
string money = "";
string temp_money = value.reverse ();
int money_length = temp_money.length;
for (int i = 0; i < money_length; i++) {
money = money + temp_money.get_char(i).to_string ();
if ((i + 1) % 3 == 0) {
if (i != money_length - 1) {
money = money + ".";
}
}
}
money = money.reverse ();
return "$" + money;
}
}
/** /**
* This class handles parsing and validation of RUTs * This class handles parsing and validation of RUTs
*/ */
@ -129,7 +179,9 @@ namespace LibSernatur {
for (int i = 0; i < rut_length; i++) { for (int i = 0; i < rut_length; i++) {
new_rut = new_rut + temp_rut.get_char(i).to_string (); new_rut = new_rut + temp_rut.get_char(i).to_string ();
if ((i + 1) % 3 == 0) { if ((i + 1) % 3 == 0) {
new_rut = new_rut + "."; if (i != rut_length - 1) {
new_rut = new_rut + ".";
}
} }
} }
new_rut = new_rut.reverse (); new_rut = new_rut.reverse ();

51
lib/queries.vala Normal file
View File

@ -0,0 +1,51 @@
/*
* 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 LibSernatur {
namespace DB {
/**
* The queries to use to work in the database
*/
public class Query < T > : GLib.Object {
public enum Type {
SELECT_ALL_TOURS,
INSERT_TOUR,
UPDATE_TOUR
}
public static string get_query (Type type, T? t) {
if (type == Type.SELECT_ALL_TOURS) {
return "
SELECT T.id_tour, T.nombre_tour, T.costo_indiv, T.costo_grupal, T.minima_personas,
C.id_ciudad, C.nombre_ciudad,
R.id_region, R.nombre_region
FROM tour T
JOIN ciudad C ON (T.id_ciudad = C.id_ciudad)
JOIN region R ON (C.id_region = R.id_region)";
}
else if (type == Type.UPDATE_TOUR) {
Tour tour = (Tour) t;
return "
UPDATE tour SET
nombre_tour = '" + tour.nombre_tour + "',
costo_indiv = " + tour.costo_indiv.to_string () + ",
costo_grupal = " + tour.costo_grupal.to_string () + ",
minima_personas = " + tour.minima_personas.to_string () + "
WHERE id_tour = " + tour.id_tour.to_string ();
}
return "";
}
}
}
}

View File

@ -1,5 +1,6 @@
lib/db.vala
lib/dbwrapper.vala lib/dbwrapper.vala
lib/rut.vala lib/misc.vala
#lib/db/arrienda.vala #lib/db/arrienda.vala
#lib/db/asociado.vala #lib/db/asociado.vala
#lib/db/categoria.vala #lib/db/categoria.vala
@ -15,6 +16,7 @@ lib/rut.vala
#lib/db/posee.vala #lib/db/posee.vala
#lib/db/realiza.vala #lib/db/realiza.vala
#lib/db/region.vala #lib/db/region.vala
#lib/db/regiones_sin_descuento.vala
#lib/db/requerir_auto.vala #lib/db/requerir_auto.vala
#lib/db/tiene_enfermedad.vala #lib/db/tiene_enfermedad.vala
#lib/db/tour.vala #lib/db/tour.vala
@ -22,9 +24,14 @@ lib/rut.vala
#lib/db/vehiculo.vala #lib/db/vehiculo.vala
src/sernatur.vala src/sernatur.vala
src/main_window.vala src/main_window.vala
src/tour_window.vala src/tour_list.vala
src/tour_editor.vala
src/query_window.vala
data/ui/main.window.ui data/ui/main.window.ui
data/ui/main.splash.ui data/ui/main.splash.ui
data/ui/tour.window.ui data/ui/tour.list.ui
data/ui/tour.editor.ui
data/ui/query.window.ui
data/ui/query.1.ui
data/gschema/cl.cromer.ubb.sernatur.db.gschema.xml data/gschema/cl.cromer.ubb.sernatur.db.gschema.xml
data/gschema/cl.cromer.ubb.sernatur.window.gschema.xml data/gschema/cl.cromer.ubb.sernatur.window.gschema.xml

360
po/es.po
View File

@ -7,8 +7,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: sernatur\n" "Project-Id-Version: sernatur\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-01-06 19:53-0300\n" "POT-Creation-Date: 2019-01-13 19:14-0300\n"
"PO-Revision-Date: 2019-01-06 19:55-0300\n" "PO-Revision-Date: 2019-01-13 19:15-0300\n"
"Last-Translator: Chris Cromer <chris@cromer.cl>\n" "Last-Translator: Chris Cromer <chris@cromer.cl>\n"
"Language-Team: none\n" "Language-Team: none\n"
"Language: es\n" "Language: es\n"
@ -17,190 +17,234 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 2.0.6\n" "X-Generator: Poedit 2.0.6\n"
"X-Poedit-SourceCharset: UTF-8\n"
#: lib/dbwrapper.vala:141 "X-Poedit-Basepath: .\n"
#, c-format
msgid "The field %s was not found in the query results!"
msgstr "La campo %s no estaba en los resultados de la consulta!"
#: lib/rut.vala:85
#, c-format
msgid "The RUT %s has an invalid character!"
msgstr "El RUT %s tiene un carácter invalido!"
#: lib/rut.vala:101
#, c-format
msgid "The RUT %s is too big!"
msgstr "El RUT %s es demasiado grande!"
#: lib/rut.vala:106
#, c-format
msgid "The verifier %C is invalid!"
msgstr "El verificador %C es invalido!"
#: src/sernatur.vala:87
#, c-format
msgid "Error: %s\n"
msgstr "Error %s\n"
#: src/sernatur.vala:88
#, c-format
msgid ""
"Run '%s --help' to see a full list of available command line "
"options.\n"
msgstr ""
"Correr '%s --help' para ver una lista completa de las opciones de la "
"consola.\n"
#: src/sernatur.vala:93
msgid "SERNATUR version: "
msgstr "Versión de SERNATUR:"
#: src/main_window.vala:160
msgid "Error"
msgstr "Error"
#: src/main_window.vala:165
msgid "Postgresql server version:"
msgstr "Versión del servidor Postgresql:"
#: data/ui/main.window.ui:44
msgid "_Menu"
msgstr "_Menú"
#: data/ui/main.window.ui:54
msgid "Tours"
msgstr "Tours"
#: data/ui/main.window.ui:62
msgid "Staff"
msgstr "Empleados"
#: data/ui/main.window.ui:69
msgid "Tourists"
msgstr "Turistas"
#: data/ui/main.window.ui:78
msgid "Illnesses"
msgstr "Enfermedades"
#: data/ui/main.window.ui:85
msgid "Participate"
msgstr "Participar"
#: data/ui/main.window.ui:96
msgid "Vehicles"
msgstr "Vehículos"
#: data/ui/main.window.ui:109
msgid "Quit"
msgstr "Salir"
#: data/ui/main.window.ui:121
msgid "_Views"
msgstr "_Vistas"
#: data/ui/main.window.ui:131
msgid "(Q1) Regions with discounts"
msgstr "(Q1) Regiones sin descuentos"
#: data/ui/main.window.ui:138
msgid "(Q2) Tour values"
msgstr "(Q2) Valores tour"
#: data/ui/main.window.ui:145
msgid "(Q3) Coordinator total"
msgstr "(Q3) Total de coordinadores"
#: data/ui/main.window.ui:152
msgid "(Q4) Tourist total"
msgstr "(Q4) Total de turistas"
#: data/ui/main.window.ui:159
msgid "(Q5) Vehicle total"
msgstr "(Q5) Total de vehículos"
#: data/ui/main.splash.ui:46 #: data/ui/main.splash.ui:46
msgid "Christopher Cromer" msgid "Christopher Cromer"
msgstr "Christopher Cromer" msgstr "Christopher Cromer"
#: data/ui/tour.window.ui:94 #: data/ui/main.window.ui:44
msgid "_Menu"
msgstr "_Menú"
#: data/ui/main.window.ui:54 data/ui/query.window.ui:22 data/ui/tour.list.ui:22
msgid "Tours"
msgstr "Tours"
#: data/ui/main.window.ui:62
msgid "Places"
msgstr "Lugares"
#: data/ui/main.window.ui:69
msgid "Staff"
msgstr "Empleados"
#: data/ui/main.window.ui:77
msgid "Tourists"
msgstr "Turistas"
#: data/ui/main.window.ui:87
msgid "Illnesses"
msgstr "Enfermedades"
#: data/ui/main.window.ui:95
msgid "Participate"
msgstr "Participar"
#: data/ui/main.window.ui:107
msgid "Vehicles"
msgstr "Vehículos"
#: data/ui/main.window.ui:121
msgid "Quit"
msgstr "Salir"
#: data/ui/main.window.ui:133
msgid "_Views"
msgstr "_Vistas"
#: data/ui/main.window.ui:143
msgid "(Q1) Regions with discounts"
msgstr "(Q1) Regiones sin descuentos"
#: data/ui/main.window.ui:151
msgid "(Q2) Tour values"
msgstr "(Q2) Valores tour"
#: data/ui/main.window.ui:159
msgid "(Q3) Coordinator total"
msgstr "(Q3) Total de coordinadores"
#: data/ui/main.window.ui:167
msgid "(Q4) Tourist total"
msgstr "(Q4) Total de turistas"
#: data/ui/main.window.ui:175
msgid "(Q5) Vehicle total"
msgstr "(Q5) Total de vehículos"
#: data/ui/query.1.ui:37
msgid "Region Name"
msgstr "Nombre de Región"
#: data/ui/query.1.ui:49
msgid "Quantity"
msgstr "Cantidad"
#: data/ui/query.window.ui:67 data/ui/tour.list.ui:212
msgid "Close"
msgstr "Cerrar"
#: data/ui/query.window.ui:85
msgid "Run"
msgstr "Correr"
#: data/ui/query.window.ui:127
msgid "Statement"
msgstr "Enunciado"
#: data/ui/query.window.ui:157
msgid "View and Query"
msgstr "Vista y Consulta"
#: data/ui/tour.editor.ui:29
msgid "Tour Editor"
msgstr "Editor de Tour"
#: data/ui/tour.editor.ui:54 data/ui/tour.list.ui:66
msgid "Tour Name"
msgstr "Nombre del Tour"
#: data/ui/tour.editor.ui:87 data/ui/tour.list.ui:80
msgid "Individual Cost" msgid "Individual Cost"
msgstr "Costo Individual" msgstr "Costo Individual"
#: data/ui/tour.window.ui:108 #: data/ui/tour.editor.ui:103 data/ui/tour.list.ui:94
msgid "Group Cost" msgid "Group Cost"
msgstr "Costo Grupal" msgstr "Costo Grupal"
#: data/ui/tour.window.ui:122 #: data/ui/tour.editor.ui:119 data/ui/tour.list.ui:108
msgid "Minimum People" msgid "Minimum People"
msgstr "Mínima Personas" msgstr "Mínima Personas"
#: data/ui/tour.window.ui:136 #: data/ui/tour.editor.ui:135 data/ui/tour.list.ui:136
msgid "City"
msgstr "Ciudad"
#: data/ui/tour.window.ui:150
msgid "Region" msgid "Region"
msgstr "Región" msgstr "Región"
#: data/ui/tour.window.ui:177 #: data/ui/tour.editor.ui:187 data/ui/tour.list.ui:122
msgid "New" msgid "City"
msgstr "Nuevo" msgstr "Ciudad"
#: data/ui/tour.window.ui:193 #: data/ui/tour.editor.ui:234
msgid "Create a new region by typing here."
msgstr "Crear una nueva región con escribir aquí."
#: data/ui/tour.editor.ui:262
msgid "Create a new city by typing here."
msgstr "Crear una nueva ciudad con escribir aquí."
#: data/ui/tour.editor.ui:287
msgid "Cancel"
msgstr "Cancelar"
#: data/ui/tour.editor.ui:291
msgid "Cancel the modification of this tour."
msgstr "Cancelar la modificación de este tour."
#: data/ui/tour.editor.ui:306
msgid "Save"
msgstr "Guardar"
#: data/ui/tour.editor.ui:310
msgid "Save this tour."
msgstr "Guardar este tour."
#: data/ui/tour.list.ui:168
msgid "Edit" msgid "Edit"
msgstr "Editar" msgstr "Editar"
#: data/gschema/cl.cromer.ubb.sernatur.db.gschema.xml:5 #: data/ui/tour.list.ui:173
#: data/gschema/cl.cromer.ubb.sernatur.db.gschema.xml:6 msgid "Edit selected tour."
msgid "Host to connect to" msgstr "Editar el tour seleccionado."
msgstr "Servidor a conectar"
#: data/gschema/cl.cromer.ubb.sernatur.db.gschema.xml:12 #: data/ui/tour.list.ui:183
#: data/gschema/cl.cromer.ubb.sernatur.db.gschema.xml:13 msgid "New"
msgid "Port number to use" msgstr "Nuevo"
msgstr "Número de puerto a usar"
#: data/gschema/cl.cromer.ubb.sernatur.db.gschema.xml:19 #: data/ui/tour.list.ui:187
#: data/gschema/cl.cromer.ubb.sernatur.db.gschema.xml:20 msgid "Create a new tour."
msgid "Options to use" msgstr "Crear un tour nuevo."
msgstr "Opciones a usar"
#: data/gschema/cl.cromer.ubb.sernatur.db.gschema.xml:26 #: data/ui/tour.list.ui:197
#: data/gschema/cl.cromer.ubb.sernatur.db.gschema.xml:27 msgid "Delete"
msgid "tty to send debug info (ignored)" msgstr "Borrar"
msgstr "tty para enviar datos de depuración (ignorado)"
#: data/gschema/cl.cromer.ubb.sernatur.db.gschema.xml:33 #: data/ui/tour.list.ui:201
#: data/gschema/cl.cromer.ubb.sernatur.db.gschema.xml:34 msgid "Delete selected tour."
msgid "Database to use" msgstr "Borrar el tour seleccionado."
msgstr "Base de dato a usar"
#: data/gschema/cl.cromer.ubb.sernatur.db.gschema.xml:40 #: src/main_window.vala:184
#: data/gschema/cl.cromer.ubb.sernatur.db.gschema.xml:41 msgid "Error"
msgid "Username to use" msgstr "Error"
msgstr "Nombre de usuario a usar"
#: data/gschema/cl.cromer.ubb.sernatur.db.gschema.xml:47 #: src/sernatur.vala:88
#: data/gschema/cl.cromer.ubb.sernatur.db.gschema.xml:48 #, c-format
msgid "Password to use" msgid "Error: %s\n"
msgstr "Contraseña a usar" msgstr "Error %s\n"
#: data/gschema/cl.cromer.ubb.sernatur.window.gschema.xml:5 #: src/sernatur.vala:89
#: data/gschema/cl.cromer.ubb.sernatur.window.gschema.xml:6 #, c-format
msgid "Should the program open maximized or not" msgid "Run '%s --help' to see a full list of available command line options.\n"
msgstr "Si el programa debe abrir maximizado ó no" msgstr ""
"Correr '%s --help' para ver una lista completa de las opciones de la "
"consola.\n"
#: data/gschema/cl.cromer.ubb.sernatur.window.gschema.xml:12 #: src/sernatur.vala:94
#: data/gschema/cl.cromer.ubb.sernatur.window.gschema.xml:13 msgid "SERNATUR version: "
msgid "Window width" msgstr "Versión de SERNATUR: "
msgstr "El ancho de la ventana"
#: data/gschema/cl.cromer.ubb.sernatur.window.gschema.xml:19 #~ msgid "Postgresql server version:"
#: data/gschema/cl.cromer.ubb.sernatur.window.gschema.xml:20 #~ msgstr "Versión del servidor Postgresql:"
msgid "Window height"
msgstr "La altura de la venta"
#~ msgid "Could not load application icon: %s\n" #~ msgid "The field %s was not found in the query results!"
#~ msgstr "No se puede cargar el icono de la aplicación: %s\n" #~ msgstr "La campo %s no estaba en los resultados de la consulta!"
#~ msgid "The RUT %s has an invalid character!"
#~ msgstr "El RUT %s tiene un carácter invalido!"
#~ msgid "The RUT %s is too big!"
#~ msgstr "El RUT %s es demasiado grande!"
#~ msgid "The verifier %C is invalid!"
#~ msgstr "El verificador %C es invalido!"
#~ msgid "Host to connect to"
#~ msgstr "Servidor a conectar"
#~ msgid "Port number to use"
#~ msgstr "Número de puerto a usar"
#~ msgid "Options to use"
#~ msgstr "Opciones a usar"
#~ msgid "tty to send debug info (ignored)"
#~ msgstr "tty para enviar datos de depuración (ignorado)"
#~ msgid "Database to use"
#~ msgstr "Base de dato a usar"
#~ msgid "Username to use"
#~ msgstr "Nombre de usuario a usar"
#~ msgid "Password to use"
#~ msgstr "Contraseña a usar"
#~ msgid "Should the program open maximized or not"
#~ msgstr "Si el programa debe abrir maximizado ó no"
#~ msgid "Window width"
#~ msgstr "El ancho de la ventana"
#~ msgid "Window height"
#~ msgstr "La altura de la venta"

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: sernatur\n" "Project-Id-Version: sernatur\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-01-06 19:53-0300\n" "POT-Creation-Date: 2019-01-13 19:10-0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -17,101 +17,105 @@ msgstr ""
"Content-Type: text/plain; charset=CHARSET\n" "Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: lib/dbwrapper.vala:141 #: lib/db.vala:67
msgid "Postgresql server version:"
msgstr ""
#: lib/dbwrapper.vala:138
#, c-format #, c-format
msgid "The field %s was not found in the query results!" msgid "The field %s was not found in the query results!"
msgstr "" msgstr ""
#: lib/rut.vala:85 #: lib/misc.vala:138
#, c-format #, c-format
msgid "The RUT %s has an invalid character!" msgid "The RUT %s has an invalid character!"
msgstr "" msgstr ""
#: lib/rut.vala:101 #: lib/misc.vala:154
#, c-format #, c-format
msgid "The RUT %s is too big!" msgid "The RUT %s is too big!"
msgstr "" msgstr ""
#: lib/rut.vala:106 #: lib/misc.vala:159
#, c-format #, c-format
msgid "The verifier %C is invalid!" msgid "The verifier %C is invalid!"
msgstr "" msgstr ""
#: src/sernatur.vala:87 #: src/sernatur.vala:88
#, c-format #, c-format
msgid "Error: %s\n" msgid "Error: %s\n"
msgstr "" msgstr ""
#: src/sernatur.vala:88 #: src/sernatur.vala:89
#, c-format #, c-format
msgid "Run '%s --help' to see a full list of available command line options.\n" msgid "Run '%s --help' to see a full list of available command line options.\n"
msgstr "" msgstr ""
#: src/sernatur.vala:93 #: src/sernatur.vala:94
msgid "SERNATUR version: " msgid "SERNATUR version: "
msgstr "" msgstr ""
#: src/main_window.vala:160 #: src/main_window.vala:184
msgid "Error" msgid "Error"
msgstr "" msgstr ""
#: src/main_window.vala:165
msgid "Postgresql server version:"
msgstr ""
#: data/ui/main.window.ui:44 #: data/ui/main.window.ui:44
msgid "_Menu" msgid "_Menu"
msgstr "" msgstr ""
#: data/ui/main.window.ui:54 #: data/ui/main.window.ui:54 data/ui/tour.list.ui:22 data/ui/query.window.ui:22
msgid "Tours" msgid "Tours"
msgstr "" msgstr ""
#: data/ui/main.window.ui:62 #: data/ui/main.window.ui:62
msgid "Staff" msgid "Places"
msgstr "" msgstr ""
#: data/ui/main.window.ui:69 #: data/ui/main.window.ui:69
msgid "Staff"
msgstr ""
#: data/ui/main.window.ui:77
msgid "Tourists" msgid "Tourists"
msgstr "" msgstr ""
#: data/ui/main.window.ui:78 #: data/ui/main.window.ui:87
msgid "Illnesses" msgid "Illnesses"
msgstr "" msgstr ""
#: data/ui/main.window.ui:85 #: data/ui/main.window.ui:95
msgid "Participate" msgid "Participate"
msgstr "" msgstr ""
#: data/ui/main.window.ui:96 #: data/ui/main.window.ui:107
msgid "Vehicles" msgid "Vehicles"
msgstr "" msgstr ""
#: data/ui/main.window.ui:109 #: data/ui/main.window.ui:121
msgid "Quit" msgid "Quit"
msgstr "" msgstr ""
#: data/ui/main.window.ui:121 #: data/ui/main.window.ui:133
msgid "_Views" msgid "_Views"
msgstr "" msgstr ""
#: data/ui/main.window.ui:131 #: data/ui/main.window.ui:143
msgid "(Q1) Regions with discounts" msgid "(Q1) Regions with discounts"
msgstr "" msgstr ""
#: data/ui/main.window.ui:138 #: data/ui/main.window.ui:151
msgid "(Q2) Tour values" msgid "(Q2) Tour values"
msgstr "" msgstr ""
#: data/ui/main.window.ui:145 #: data/ui/main.window.ui:159
msgid "(Q3) Coordinator total" msgid "(Q3) Coordinator total"
msgstr "" msgstr ""
#: data/ui/main.window.ui:152 #: data/ui/main.window.ui:167
msgid "(Q4) Tourist total" msgid "(Q4) Tourist total"
msgstr "" msgstr ""
#: data/ui/main.window.ui:159 #: data/ui/main.window.ui:175
msgid "(Q5) Vehicle total" msgid "(Q5) Vehicle total"
msgstr "" msgstr ""
@ -119,32 +123,104 @@ msgstr ""
msgid "Christopher Cromer" msgid "Christopher Cromer"
msgstr "" msgstr ""
#: data/ui/tour.window.ui:94 #: data/ui/tour.list.ui:66 data/ui/tour.editor.ui:54
msgid "Tour Name"
msgstr ""
#: data/ui/tour.list.ui:80 data/ui/tour.editor.ui:87
msgid "Individual Cost" msgid "Individual Cost"
msgstr "" msgstr ""
#: data/ui/tour.window.ui:108 #: data/ui/tour.list.ui:94 data/ui/tour.editor.ui:103
msgid "Group Cost" msgid "Group Cost"
msgstr "" msgstr ""
#: data/ui/tour.window.ui:122 #: data/ui/tour.list.ui:108 data/ui/tour.editor.ui:119
msgid "Minimum People" msgid "Minimum People"
msgstr "" msgstr ""
#: data/ui/tour.window.ui:136 #: data/ui/tour.list.ui:122 data/ui/tour.editor.ui:187
msgid "City" msgid "City"
msgstr "" msgstr ""
#: data/ui/tour.window.ui:150 #: data/ui/tour.list.ui:136 data/ui/tour.editor.ui:135
msgid "Region" msgid "Region"
msgstr "" msgstr ""
#: data/ui/tour.window.ui:177 #: data/ui/tour.list.ui:168
msgid "Edit"
msgstr ""
#: data/ui/tour.list.ui:173
msgid "Edit selected tour."
msgstr ""
#: data/ui/tour.list.ui:183
msgid "New" msgid "New"
msgstr "" msgstr ""
#: data/ui/tour.window.ui:193 #: data/ui/tour.list.ui:187
msgid "Edit" msgid "Create a new tour."
msgstr ""
#: data/ui/tour.list.ui:197
msgid "Delete"
msgstr ""
#: data/ui/tour.list.ui:201
msgid "Delete selected tour."
msgstr ""
#: data/ui/tour.list.ui:212 data/ui/query.window.ui:67
msgid "Close"
msgstr ""
#: data/ui/tour.editor.ui:29
msgid "Tour Editor"
msgstr ""
#: data/ui/tour.editor.ui:234
msgid "Create a new region by typing here."
msgstr ""
#: data/ui/tour.editor.ui:262
msgid "Create a new city by typing here."
msgstr ""
#: data/ui/tour.editor.ui:287
msgid "Cancel"
msgstr ""
#: data/ui/tour.editor.ui:291
msgid "Cancel the modification of this tour."
msgstr ""
#: data/ui/tour.editor.ui:306
msgid "Save"
msgstr ""
#: data/ui/tour.editor.ui:310
msgid "Save this tour."
msgstr ""
#: data/ui/query.window.ui:85
msgid "Run"
msgstr ""
#: data/ui/query.window.ui:127
msgid "Statement"
msgstr ""
#: data/ui/query.window.ui:157
msgid "View and Query"
msgstr ""
#: data/ui/query.1.ui:37
msgid "Region Name"
msgstr ""
#: data/ui/query.1.ui:49
msgid "Quantity"
msgstr "" msgstr ""
#: data/gschema/cl.cromer.ubb.sernatur.db.gschema.xml:5 #: data/gschema/cl.cromer.ubb.sernatur.db.gschema.xml:5

View File

@ -13,7 +13,6 @@
*/ */
namespace Sernatur { namespace Sernatur {
using LibSernatur.Person;
using LibSernatur.DB; using LibSernatur.DB;
/** /**
@ -24,7 +23,7 @@ namespace Sernatur {
/** /**
* The opened database connection * The opened database connection
*/ */
private Postgres.Database conn; private Connection conn;
/** /**
* The content grid to fill * The content grid to fill
*/ */
@ -34,13 +33,28 @@ namespace Sernatur {
*/ */
[GtkChild] [GtkChild]
private Gtk.Box mainbox; 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 * This is a callback for when the close button is pressed on the window
* @param widget The widget that called this GtkCallback * @param widget The widget that called this GtkCallback
*/ */
[GtkCallback] [GtkCallback]
private void window_quit(Gtk.Widget widget) { private void on_destroy(Gtk.Widget widget) {
application.quit (); application.quit ();
} }
@ -51,7 +65,7 @@ namespace Sernatur {
* @return Returns true if the event is handled or false if it isn't * @return Returns true if the event is handled or false if it isn't
*/ */
[GtkCallback] [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"); var settings = new Settings ("cl.cromer.ubb.sernatur.window");
if (state.changed_mask == Gdk.WindowState.MAXIMIZED && (state.new_window_state & Gdk.WindowState.MAXIMIZED) != 0) { if (state.changed_mask == Gdk.WindowState.MAXIMIZED && (state.new_window_state & Gdk.WindowState.MAXIMIZED) != 0) {
// Maximized // Maximized
@ -71,7 +85,7 @@ namespace Sernatur {
* @return Returns true if the event is handled or false if it isn't * @return Returns true if the event is handled or false if it isn't
*/ */
[GtkCallback] [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"); var settings = new Settings ("cl.cromer.ubb.sernatur.window");
if (event.get_event_type () == Gdk.EventType.CONFIGURE && !settings.get_boolean ("maximized")) { if (event.get_event_type () == Gdk.EventType.CONFIGURE && !settings.get_boolean ("maximized")) {
if (settings.get_int ("width") != event.get_window ().get_width ()) { 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 * @param menu_item The menu item that was clicked
*/ */
[GtkCallback] [GtkCallback]
private void menu_tours(Gtk.MenuItem menu_item) { private void on_activate_menu(Gtk.MenuItem menu_item) {
var tour_window = new TourWindow (application, conn); if (menu_item == tours) {
tour_window.set_transient_for (this); // Set this window as the parent of the new window var tour_list = new TourList (application, conn);
tour_window.show_all (); tour_list.set_transient_for (this); // Set this window as the parent of the new window
} tour_list.initialize ();
tour_list.show_all ();
/** }
* This is a callback for when the quit option in the menu is clicked else if (menu_item == q1) {
* @param menu_item The menu item that was clicked var query_window = new QueryWindow (application, conn);
*/ query_window.set_transient_for (this); // Set this window as the parent of the new window
[GtkCallback] query_window.initialize ();
private void menu_quit(Gtk.MenuItem menu_item) { query_window.show_all ();
application.quit (); }
else if (menu_item == quit) {
application.quit ();
}
} }
/** /**
@ -118,14 +135,19 @@ namespace Sernatur {
builder.connect_signals (null); builder.connect_signals (null);
content = builder.get_object ("content_grid") as Gtk.Grid; 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); mainbox.pack_start (content, true, false, 0);
} }
catch (Error e) { catch (Error e) {
// This error is not fatal, so let's keep going // This error is not fatal, so let's keep going
warning (e.message); warning (e.message);
} }
}
/**
* Initialize what is needed for this window
*/
public void initialize () {
var settings = new Settings ("cl.cromer.ubb.sernatur.db"); var settings = new Settings ("cl.cromer.ubb.sernatur.db");
var host = settings.get_string ("host"); var host = settings.get_string ("host");
var port = settings.get_string ("port"); var port = settings.get_string ("port");
@ -135,17 +157,19 @@ namespace Sernatur {
var username = settings.get_string ("username"); var username = settings.get_string ("username");
var password = settings.get_string ("password"); var password = settings.get_string ("password");
conn = Postgres.set_db_login (host, port, options, tty, database, username, password); try {
if (conn.get_status () != Postgres.ConnectionStatus.OK) { conn = new Connection (host, port, options, tty, database, username, password);
}
catch (Error e) {
#if DEBUG #if DEBUG
error (conn.get_error_message ()); error (e.message);
#else #else
warning (conn.get_error_message ()); warning (e.message);
var msg = new Gtk.MessageDialog (this, var msg = new Gtk.MessageDialog (this,
Gtk.DialogFlags.MODAL, Gtk.DialogFlags.MODAL,
Gtk.MessageType.ERROR, Gtk.MessageType.ERROR,
Gtk.ButtonsType.CLOSE, Gtk.ButtonsType.CLOSE,
conn.get_error_message ()); e.message);
msg.response.connect ((response_id) => { msg.response.connect ((response_id) => {
switch (response_id) { switch (response_id) {
case Gtk.ResponseType.CLOSE: case Gtk.ResponseType.CLOSE:
@ -155,14 +179,13 @@ namespace Sernatur {
application.quit (); application.quit ();
break; break;
} }
msg.destroy(); msg.destroy ();
}); });
msg.set_title (dgettext (null, "Error")); msg.set_title (dgettext (null, "Error"));
msg.show (); msg.show ();
return; return;
#endif #endif
} }
print (dgettext (null, "Postgresql server version:") + " %d\n", conn.get_server_version ());
} }
} }
} }

View File

@ -16,16 +16,21 @@ config_data_file = configure_file(input: 'config.vala.in',
vala_sources = files( vala_sources = files(
'sernatur.vala', 'sernatur.vala',
'main_window.vala', 'main_window.vala',
'tour_window.vala') 'tour_list.vala',
'tour_editor.vala',
'queries.vala',
'query_window.vala')
sources = vala_sources sources = vala_sources
sources += main_gresource sources += main_gresource
sources += tour_gresource sources += tour_gresource
sources += query_gresource
sources += config_data_file sources += config_data_file
vala_args = ['--vapidir=' + join_paths(meson.source_root(), 'vapi')] 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/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/tour.gresource.xml')]
vala_args += ['--gresources=' + join_paths(meson.source_root(), 'data/ui/query.gresource.xml')]
inc = include_directories('../lib', './') inc = include_directories('../lib', './')

44
src/queries.vala Normal file
View 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
View 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);
}
}
}

View File

@ -56,6 +56,7 @@ namespace Sernatur {
window.icon = new Image.from_resource ("/cl/cromer/ubb/sernatur/pixdata/icon-sernatur.png").get_pixbuf (); window.icon = new Image.from_resource ("/cl/cromer/ubb/sernatur/pixdata/icon-sernatur.png").get_pixbuf ();
window.show_all (); window.show_all ();
window.initialize ();
} }
/** /**

306
src/tour_editor.vala Normal file
View 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
View 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);
}
}
}

View File

@ -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);
}
}
}