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

View File

@ -11,3 +11,9 @@ tour_gresource = gnome.compile_resources('tour_gresource',
c_name: meson.project_name() + '_resource_tour',
export: 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>
<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>
</gresources>

View File

@ -16,13 +16,16 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-->
<interface domain="sernatur">
<requires lib="gtk+" version="3.20"/>
<template class="SernaturTourWindow" parent="GtkApplicationWindow">
<template class="SernaturTourList" parent="GtkApplicationWindow">
<property name="can_focus">False</property>
<property name="type">popup</property>
<property name="title" translatable="yes">Tours</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="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>
@ -35,8 +38,6 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
<property name="can_focus">True</property>
<child>
<object class="GtkScrolledWindow">
<property name="width_request">-1</property>
<property name="height_request">-1</property>
<property name="visible">True</property>
<property name="can_focus">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>
<child internal-child="selection">
<object class="GtkTreeSelection" id="selection">
<property name="mode">none</property>
<signal name="changed" handler="on_changed_selection" swapped="no"/>
</object>
</child>
<child>
<object class="GtkTreeViewColumn">
<object class="GtkTreeViewColumn" id="tour_name">
<property name="sizing">fixed</property>
<property name="title" translatable="yes">Tour Name</property>
<property name="clickable">True</property>
<signal name="clicked" handler="on_clicked_column" swapped="no"/>
<child>
<object class="GtkCellRendererToggle">
<property name="radio">True</property>
<signal name="toggled" handler="toggled" swapped="no"/>
</object>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="active">0</attribute>
<attribute name="markup">0</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn">
<object class="GtkTreeViewColumn" id="indiv_cost">
<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="sort_indicator">True</property>
<signal name="clicked" handler="on_clicked_column" swapped="no"/>
<child>
<object class="GtkCellRendererText"/>
<attributes>
@ -89,11 +89,11 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
</object>
</child>
<child>
<object class="GtkTreeViewColumn">
<object class="GtkTreeViewColumn" id="group_cost">
<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="sort_indicator">True</property>
<signal name="clicked" handler="on_clicked_column" swapped="no"/>
<child>
<object class="GtkCellRendererText"/>
<attributes>
@ -103,11 +103,11 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
</object>
</child>
<child>
<object class="GtkTreeViewColumn">
<object class="GtkTreeViewColumn" id="minimum_people">
<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="sort_indicator">True</property>
<signal name="clicked" handler="on_clicked_column" swapped="no"/>
<child>
<object class="GtkCellRendererText"/>
<attributes>
@ -117,11 +117,11 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
</object>
</child>
<child>
<object class="GtkTreeViewColumn">
<object class="GtkTreeViewColumn" id="city">
<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="sort_indicator">True</property>
<signal name="clicked" handler="on_clicked_column" swapped="no"/>
<child>
<object class="GtkCellRendererText"/>
<attributes>
@ -131,11 +131,11 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
</object>
</child>
<child>
<object class="GtkTreeViewColumn">
<object class="GtkTreeViewColumn" id="region">
<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="sort_indicator">True</property>
<signal name="clicked" handler="on_clicked_column" swapped="no"/>
<child>
<object class="GtkCellRendererText"/>
<attributes>
@ -144,20 +144,6 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
</child>
</object>
</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>
</child>
</object>
@ -170,34 +156,36 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
<object class="GtkGrid">
<property name="visible">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="column_spacing">25</property>
<property name="column_homogeneous">True</property>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">New</property>
<object class="GtkButton" id="edit_tour">
<property name="label" translatable="yes">Edit</property>
<property name="visible">True</property>
<property name="sensitive">False</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>
<property name="tooltip_text" translatable="yes">Edit selected tour.</property>
<signal name="clicked" handler="on_clicked_button" swapped="no"/>
</object>
<packing>
<property name="left_attach">2</property>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">Edit</property>
<object class="GtkButton" id="new_tour">
<property name="label" translatable="yes">New</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>
<property name="tooltip_text" translatable="yes">Create a new tour.</property>
<signal name="clicked" handler="on_clicked_button" swapped="no"/>
</object>
<packing>
<property name="left_attach">0</property>
@ -205,7 +193,32 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
</packing>
</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>
</object>
<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;
}
/**
* 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
*/
public static List<Tour> get_all_tours(Database conn) {
var res = conn.exec ("
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)
");
var res = conn.exec (Query.get_query (Query.Type.SELECT_ALL_TOURS, null));
if (res.get_status () != ExecStatus.TUPLES_OK) {
#if DEBUG
error (conn.get_error_message ());
@ -116,6 +109,26 @@ JOIN region R ON (C.id_region = R.id_region)
}
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.
*/
/**
* The sernatur library
*/
namespace LibSernatur {
/**
* Sernatur database library
*/
namespace DB {
/**
* 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
*/
public errordomain Field {
/**
* Field was not found in table
*/
NOTFOUND
}

View File

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

View File

@ -16,7 +16,7 @@ namespace LibSernatur {
/**
* The person name space
*/
namespace Person {
namespace Misc {
/**
* The errors that can be thrown by the Rut class
@ -36,6 +36,56 @@ namespace LibSernatur {
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
*/
@ -129,7 +179,9 @@ namespace LibSernatur {
for (int i = 0; i < rut_length; i++) {
new_rut = new_rut + temp_rut.get_char(i).to_string ();
if ((i + 1) % 3 == 0) {
new_rut = new_rut + ".";
if (i != rut_length - 1) {
new_rut = new_rut + ".";
}
}
}
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/rut.vala
lib/misc.vala
#lib/db/arrienda.vala
#lib/db/asociado.vala
#lib/db/categoria.vala
@ -15,6 +16,7 @@ lib/rut.vala
#lib/db/posee.vala
#lib/db/realiza.vala
#lib/db/region.vala
#lib/db/regiones_sin_descuento.vala
#lib/db/requerir_auto.vala
#lib/db/tiene_enfermedad.vala
#lib/db/tour.vala
@ -22,9 +24,14 @@ lib/rut.vala
#lib/db/vehiculo.vala
src/sernatur.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.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.window.gschema.xml

360
po/es.po
View File

@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: sernatur\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-01-06 19:53-0300\n"
"PO-Revision-Date: 2019-01-06 19:55-0300\n"
"POT-Creation-Date: 2019-01-13 19:14-0300\n"
"PO-Revision-Date: 2019-01-13 19:15-0300\n"
"Last-Translator: Chris Cromer <chris@cromer.cl>\n"
"Language-Team: none\n"
"Language: es\n"
@ -17,190 +17,234 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 2.0.6\n"
#: lib/dbwrapper.vala:141
#, 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"
"X-Poedit-SourceCharset: UTF-8\n"
"X-Poedit-Basepath: .\n"
#: data/ui/main.splash.ui:46
msgid "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"
msgstr "Costo Individual"
#: data/ui/tour.window.ui:108
#: data/ui/tour.editor.ui:103 data/ui/tour.list.ui:94
msgid "Group Cost"
msgstr "Costo Grupal"
#: data/ui/tour.window.ui:122
#: data/ui/tour.editor.ui:119 data/ui/tour.list.ui:108
msgid "Minimum People"
msgstr "Mínima Personas"
#: data/ui/tour.window.ui:136
msgid "City"
msgstr "Ciudad"
#: data/ui/tour.window.ui:150
#: data/ui/tour.editor.ui:135 data/ui/tour.list.ui:136
msgid "Region"
msgstr "Región"
#: data/ui/tour.window.ui:177
msgid "New"
msgstr "Nuevo"
#: data/ui/tour.editor.ui:187 data/ui/tour.list.ui:122
msgid "City"
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"
msgstr "Editar"
#: data/gschema/cl.cromer.ubb.sernatur.db.gschema.xml:5
#: data/gschema/cl.cromer.ubb.sernatur.db.gschema.xml:6
msgid "Host to connect to"
msgstr "Servidor a conectar"
#: data/ui/tour.list.ui:173
msgid "Edit selected tour."
msgstr "Editar el tour seleccionado."
#: data/gschema/cl.cromer.ubb.sernatur.db.gschema.xml:12
#: data/gschema/cl.cromer.ubb.sernatur.db.gschema.xml:13
msgid "Port number to use"
msgstr "Número de puerto a usar"
#: data/ui/tour.list.ui:183
msgid "New"
msgstr "Nuevo"
#: data/gschema/cl.cromer.ubb.sernatur.db.gschema.xml:19
#: data/gschema/cl.cromer.ubb.sernatur.db.gschema.xml:20
msgid "Options to use"
msgstr "Opciones a usar"
#: data/ui/tour.list.ui:187
msgid "Create a new tour."
msgstr "Crear un tour nuevo."
#: data/gschema/cl.cromer.ubb.sernatur.db.gschema.xml:26
#: data/gschema/cl.cromer.ubb.sernatur.db.gschema.xml:27
msgid "tty to send debug info (ignored)"
msgstr "tty para enviar datos de depuración (ignorado)"
#: data/ui/tour.list.ui:197
msgid "Delete"
msgstr "Borrar"
#: data/gschema/cl.cromer.ubb.sernatur.db.gschema.xml:33
#: data/gschema/cl.cromer.ubb.sernatur.db.gschema.xml:34
msgid "Database to use"
msgstr "Base de dato a usar"
#: data/ui/tour.list.ui:201
msgid "Delete selected tour."
msgstr "Borrar el tour seleccionado."
#: data/gschema/cl.cromer.ubb.sernatur.db.gschema.xml:40
#: data/gschema/cl.cromer.ubb.sernatur.db.gschema.xml:41
msgid "Username to use"
msgstr "Nombre de usuario a usar"
#: src/main_window.vala:184
msgid "Error"
msgstr "Error"
#: data/gschema/cl.cromer.ubb.sernatur.db.gschema.xml:47
#: data/gschema/cl.cromer.ubb.sernatur.db.gschema.xml:48
msgid "Password to use"
msgstr "Contraseña a usar"
#: src/sernatur.vala:88
#, c-format
msgid "Error: %s\n"
msgstr "Error %s\n"
#: data/gschema/cl.cromer.ubb.sernatur.window.gschema.xml:5
#: data/gschema/cl.cromer.ubb.sernatur.window.gschema.xml:6
msgid "Should the program open maximized or not"
msgstr "Si el programa debe abrir maximizado ó no"
#: src/sernatur.vala:89
#, 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"
#: data/gschema/cl.cromer.ubb.sernatur.window.gschema.xml:12
#: data/gschema/cl.cromer.ubb.sernatur.window.gschema.xml:13
msgid "Window width"
msgstr "El ancho de la ventana"
#: src/sernatur.vala:94
msgid "SERNATUR version: "
msgstr "Versión de SERNATUR: "
#: data/gschema/cl.cromer.ubb.sernatur.window.gschema.xml:19
#: data/gschema/cl.cromer.ubb.sernatur.window.gschema.xml:20
msgid "Window height"
msgstr "La altura de la venta"
#~ msgid "Postgresql server version:"
#~ msgstr "Versión del servidor Postgresql:"
#~ msgid "Could not load application icon: %s\n"
#~ msgstr "No se puede cargar el icono de la aplicación: %s\n"
#~ msgid "The field %s was not found in the query results!"
#~ 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 ""
"Project-Id-Version: sernatur\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"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -17,101 +17,105 @@ msgstr ""
"Content-Type: text/plain; charset=CHARSET\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
msgid "The field %s was not found in the query results!"
msgstr ""
#: lib/rut.vala:85
#: lib/misc.vala:138
#, c-format
msgid "The RUT %s has an invalid character!"
msgstr ""
#: lib/rut.vala:101
#: lib/misc.vala:154
#, c-format
msgid "The RUT %s is too big!"
msgstr ""
#: lib/rut.vala:106
#: lib/misc.vala:159
#, c-format
msgid "The verifier %C is invalid!"
msgstr ""
#: src/sernatur.vala:87
#: src/sernatur.vala:88
#, c-format
msgid "Error: %s\n"
msgstr ""
#: src/sernatur.vala:88
#: src/sernatur.vala:89
#, c-format
msgid "Run '%s --help' to see a full list of available command line options.\n"
msgstr ""
#: src/sernatur.vala:93
#: src/sernatur.vala:94
msgid "SERNATUR version: "
msgstr ""
#: src/main_window.vala:160
#: src/main_window.vala:184
msgid "Error"
msgstr ""
#: src/main_window.vala:165
msgid "Postgresql server version:"
msgstr ""
#: data/ui/main.window.ui:44
msgid "_Menu"
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"
msgstr ""
#: data/ui/main.window.ui:62
msgid "Staff"
msgid "Places"
msgstr ""
#: data/ui/main.window.ui:69
msgid "Staff"
msgstr ""
#: data/ui/main.window.ui:77
msgid "Tourists"
msgstr ""
#: data/ui/main.window.ui:78
#: data/ui/main.window.ui:87
msgid "Illnesses"
msgstr ""
#: data/ui/main.window.ui:85
#: data/ui/main.window.ui:95
msgid "Participate"
msgstr ""
#: data/ui/main.window.ui:96
#: data/ui/main.window.ui:107
msgid "Vehicles"
msgstr ""
#: data/ui/main.window.ui:109
#: data/ui/main.window.ui:121
msgid "Quit"
msgstr ""
#: data/ui/main.window.ui:121
#: data/ui/main.window.ui:133
msgid "_Views"
msgstr ""
#: data/ui/main.window.ui:131
#: data/ui/main.window.ui:143
msgid "(Q1) Regions with discounts"
msgstr ""
#: data/ui/main.window.ui:138
#: data/ui/main.window.ui:151
msgid "(Q2) Tour values"
msgstr ""
#: data/ui/main.window.ui:145
#: data/ui/main.window.ui:159
msgid "(Q3) Coordinator total"
msgstr ""
#: data/ui/main.window.ui:152
#: data/ui/main.window.ui:167
msgid "(Q4) Tourist total"
msgstr ""
#: data/ui/main.window.ui:159
#: data/ui/main.window.ui:175
msgid "(Q5) Vehicle total"
msgstr ""
@ -119,32 +123,104 @@ msgstr ""
msgid "Christopher Cromer"
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"
msgstr ""
#: data/ui/tour.window.ui:108
#: data/ui/tour.list.ui:94 data/ui/tour.editor.ui:103
msgid "Group Cost"
msgstr ""
#: data/ui/tour.window.ui:122
#: data/ui/tour.list.ui:108 data/ui/tour.editor.ui:119
msgid "Minimum People"
msgstr ""
#: data/ui/tour.window.ui:136
#: data/ui/tour.list.ui:122 data/ui/tour.editor.ui:187
msgid "City"
msgstr ""
#: data/ui/tour.window.ui:150
#: data/ui/tour.list.ui:136 data/ui/tour.editor.ui:135
msgid "Region"
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"
msgstr ""
#: data/ui/tour.window.ui:193
msgid "Edit"
#: data/ui/tour.list.ui:187
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 ""
#: data/gschema/cl.cromer.ubb.sernatur.db.gschema.xml:5

View File

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

View File

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

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