changeset 80:c8fd927cd2c4

Restructure the project by placing source code, images into appropriate subdirectories.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 24 Apr 2017 12:12:39 +0300
parents f48b8fc1de64
children 810ca71af506
files Makefile.gen editperson.ui icon-16.png icon-32.png icon-48.png icon-64.png img/icon-16.png img/icon-32.png img/icon-48.png img/icon-64.png img/kampuscafe1.svg img/kampuscafe2.svg img/kampuscafe3.svg img/kampuscafe4.svg img/logo.png kampuscafe1.svg kampuscafe2.svg kampuscafe3.svg kampuscafe4.svg logo.png main.cpp main.h mainwindow.ui resources.qrc src/editperson.ui src/main.cpp src/main.h src/mainwindow.ui src/resources.qrc src/winres.rc.in winres.rc.in
diffstat 31 files changed, 2429 insertions(+), 2427 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile.gen	Wed Apr 12 12:16:00 2017 +0300
+++ b/Makefile.gen	Mon Apr 24 12:12:39 2017 +0300
@@ -17,6 +17,8 @@
 DEFINES += -DQT_DEPRECATED_WARNINGS -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_SQL_LIB -DQT_CORE_LIB
 
 # Application stuff
+APP_SRC=src/
+APP_IMG=img/
 APP_BIN=$(BINPATH)Syntilista$(EXEEXT)
 APP_OBJS=main.o resources.o moc_main.o
 APP_VERSION := $(shell cat VERSION)
@@ -27,14 +29,14 @@
 LOGO_SVG ?= kampuscafe4.svg
 ICON_PNGS = icon-64.png icon-48.png icon-32.png icon-16.png
 
-APP_RESOURCES += logo.png $(ICON_PNGS)
+APP_RESOURCES += $(addprefix $(APP_IMG),logo.png $(ICON_PNGS))
 
 
 # And target lists
 TARGETS = $(APP_BIN)
 NOBUILD_TARGETS += $(OBJPATH) $(BINPATH)
 NOINST_TARGETS +=
-DISTCLEAN_TARGETS += icon.ico moc_*.cpp ui_*.h
+DISTCLEAN_TARGETS += icon.ico $(APP_SRC)moc_*.cpp $(APP_SRC)ui_*.h
 
 
 ###
@@ -60,11 +62,11 @@
 	@echo " MKDIR $@"
 	@$(MKDIR_P) $@
 
-$(OBJPATH)%.o: %.cpp %.h
+$(OBJPATH)%.o: $(APP_SRC)%.cpp $(APP_SRC)%.h
 	@echo " CXX $@"
 	@$(CXX) $(CXXFLAGS) $(DEFINES) $(INCPATH) -c -o $@ $<
 
-$(OBJPATH)%.o: %.cpp
+$(OBJPATH)%.o: $(APP_SRC)%.cpp
 	@echo " CXX $@"
 	@$(CXX) $(CXXFLAGS) $(DEFINES) $(INCPATH) -c -o $@ $<
 
@@ -76,7 +78,7 @@
 %.rc: %.rc.in icon.ico VERSION
 	@sed -e "s/@APP_VERSION@/$(APP_VERSION)/g;s/@APP_VERSION_COM@/$(APP_VERSION_COM)/g;s#@APP_EXE@#$(notdir $(APP_BIN))#g" < $< > $@
 
-$(OBJPATH)%.o: %.rc
+$(OBJPATH)%.o: $(APP_SRC)%.rc
 	@echo " WINDRES $<"
 	@$(WINDRES) $< -O coff -o $@
 
@@ -84,21 +86,21 @@
 ###
 ### Application rules
 ###
-icon-%.png: $(LOGO_SVG)
+$(APP_IMG)icon-%.png: $(addprefix $(APP_IMG),$(LOGO_SVG))
 	inkscape --export-area-page -w $(patsubst icon-%.png,%,$@) -h $(patsubst icon-%.png,%,$@) -e "$@" "$<"
 
-logo.png: $(LOGO_SVG)
+$(APP_IMG)logo.png: $(addprefix $(APP_IMG),$(LOGO_SVG))
 	inkscape --export-area-page -w 320 -h 280 -e "$@" "$<"
 
-icon.ico: $(ICON_PNGS)
+icon.ico: $(addprefix $(APP_IMG),$(ICON_PNGS))
 	@echo " CONVERT $+ -> $@"
 	@convert $+ $@
 
-%.cpp: %.qrc $(APP_RESOURCES)
+$(APP_SRC)%.cpp: $(APP_SRC)%.qrc $(APP_RESOURCES)
 	@echo " Qt:RCC $@ $<"
 	@$(QT_RCC) -name "Syntilista" $< -o $@
 
-$(OBJPATH)main.o: main.cpp main.h ui_mainwindow.h ui_editperson.h VERSION
+$(OBJPATH)main.o: $(addprefix $(APP_SRC),main.cpp main.h ui_mainwindow.h ui_editperson.h) VERSION
 	@echo " CXX $@"
 	@$(CXX) $(CXXFLAGS) $(DEFINES) $(INCPATH) -c -o $@ $<
 
--- a/editperson.ui	Wed Apr 12 12:16:00 2017 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,120 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>EditPerson</class>
- <widget class="QDialog" name="EditPerson">
-  <property name="windowModality">
-   <enum>Qt::NonModal</enum>
-  </property>
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>564</width>
-    <height>500</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>Muokkaa henkilöä</string>
-  </property>
-  <layout class="QVBoxLayout" name="verticalLayout">
-   <item>
-    <widget class="QGroupBox" name="groupBox_2">
-     <property name="title">
-      <string>Henkilön perustiedot</string>
-     </property>
-     <layout class="QFormLayout" name="formLayout">
-      <item row="0" column="0">
-       <widget class="QLabel" name="label_FirstName">
-        <property name="text">
-         <string>Etunimi</string>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="1">
-       <widget class="QLabel" name="label_LastName">
-        <property name="text">
-         <string>Sukunimi</string>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="1">
-       <widget class="QLineEdit" name="edit_LastName"/>
-      </item>
-      <item row="1" column="0">
-       <widget class="QLineEdit" name="edit_FirstName"/>
-      </item>
-      <item row="2" column="0">
-       <widget class="QLabel" name="label_ExtraInfo">
-        <property name="text">
-         <string>Lisätietoja:</string>
-        </property>
-       </widget>
-      </item>
-      <item row="3" column="0" colspan="2">
-       <widget class="QPlainTextEdit" name="textedit_ExtraInfo"/>
-      </item>
-     </layout>
-    </widget>
-   </item>
-   <item>
-    <widget class="QGroupBox" name="groupBox">
-     <property name="title">
-      <string>Tapahtumat:</string>
-     </property>
-     <layout class="QVBoxLayout" name="verticalLayout_2">
-      <item>
-       <widget class="QTableView" name="tableview_Transactions">
-        <property name="contextMenuPolicy">
-         <enum>Qt::DefaultContextMenu</enum>
-        </property>
-        <property name="selectionBehavior">
-         <enum>QAbstractItemView::SelectRows</enum>
-        </property>
-       </widget>
-      </item>
-     </layout>
-    </widget>
-   </item>
-   <item>
-    <layout class="QHBoxLayout" name="horizontalLayout">
-     <item>
-      <spacer name="horizontalSpacer">
-       <property name="orientation">
-        <enum>Qt::Horizontal</enum>
-       </property>
-       <property name="sizeHint" stdset="0">
-        <size>
-         <width>40</width>
-         <height>20</height>
-        </size>
-       </property>
-      </spacer>
-     </item>
-     <item>
-      <widget class="QPushButton" name="button_Cancel">
-       <property name="text">
-        <string>Peruuta</string>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="QPushButton" name="button_OK">
-       <property name="text">
-        <string>Talleta / OK</string>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
-  </layout>
- </widget>
- <tabstops>
-  <tabstop>edit_FirstName</tabstop>
-  <tabstop>edit_LastName</tabstop>
-  <tabstop>textedit_ExtraInfo</tabstop>
-  <tabstop>button_OK</tabstop>
-  <tabstop>button_Cancel</tabstop>
- </tabstops>
- <resources/>
- <connections/>
-</ui>
Binary file icon-16.png has changed
Binary file icon-32.png has changed
Binary file icon-48.png has changed
Binary file icon-64.png has changed
Binary file img/icon-16.png has changed
Binary file img/icon-32.png has changed
Binary file img/icon-48.png has changed
Binary file img/icon-64.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/img/kampuscafe1.svg	Mon Apr 24 12:12:39 2017 +0300
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="129.27827mm"
+   height="100.09245mm"
+   viewBox="0 0 129.27827 100.09245"
+   version="1.1"
+   id="svg8"
+   inkscape:version="0.92.1 r15371"
+   sodipodi:docname="kampuscafe.svg"
+   inkscape:export-filename="/home/ccr/syntilista/logo.png"
+   inkscape:export-xdpi="58.939999"
+   inkscape:export-ydpi="58.939999">
+  <defs
+     id="defs2" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.4142136"
+     inkscape:cx="367.702"
+     inkscape:cy="192.39597"
+     inkscape:document-units="mm"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:snap-grids="true"
+     inkscape:snap-to-guides="false"
+     inkscape:snap-others="true"
+     inkscape:window-width="2558"
+     inkscape:window-height="1402"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:object-nodes="false"
+     inkscape:snap-global="false"
+     inkscape:snap-page="true"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <metadata
+     id="metadata5">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-33.675957,-79.041702)">
+    <rect
+       style="opacity:1;fill:#fcfcfc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.17169559;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
+       id="rect4489"
+       width="129.27827"
+       height="100.09245"
+       x="33.675957"
+       y="79.041702"
+       rx="1.4271281"
+       ry="1.4271282" />
+    <path
+       style="opacity:1;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29645836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
+       d="m 61.847708,113.50711 c -2.514304,4.28362 -1.074055,1.48352 -0.02466,6.03801 11.281973,17.3705 14.842373,47.33917 20.488129,50.62371 10.742374,2.02599 18.417143,-0.41726 29.278183,-0.034 7.36024,-0.56797 9.7848,-5.04174 11.16765,-14.72544 3.83655,-3.17889 5.69394,-1.87444 9.54739,-4.55175 4.59353,-5.56191 6.48809,-9.87079 11.20272,-15.70691 3.69312,-4.88682 6.85525,-13.78534 0.45512,-15.84033 -5.95141,-2.01246 -6.60877,-3.71891 -11.2574,-0.76452 -0.91307,-3.14931 2.43292,-5.33053 -1.97617,-6.79193 -3.71085,-1.9731 -16.87131,-3.27169 -34.741268,-2.92759 -17.86995,0.34409 -27.170753,1.91033 -34.139695,4.68073 z m 61.530802,-0.57086 c 1.30371,0.0876 8.26515,1.57927 3.58221,1.67173 -11.02663,1.67858 -41.8771,4.87511 -61.538187,0.36526 12.90601,-5.85387 48.952857,-4.39622 57.955977,-2.03699 z m -59.185014,4.23437 c 14.143363,10.25342 51.567824,1.63929 64.775664,0.63503 -11.91685,14.59736 -6.08219,45.66306 -15.15371,48.84621 -11.85472,-0.1447 -23.059354,1.86016 -29.777977,-0.035 -3.043523,-0.91095 -9.295304,-33.44794 -19.843972,-49.44627 z m 77.559514,12.20958 c -8.7291,14.02432 -8.79009,20.63449 -17.72206,19.98842 0.96521,-8.38622 3.73261,-19.14833 6.3172,-24.32052 0.89269,-1.78641 3.89953,-3.93174 6.91219,-1.94539 1.78418,1.17636 7.73946,1.06115 4.49267,6.27749 z"
+       id="path4491"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccccczcccccczcccczscsss" />
+    <path
+       style="opacity:1;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.75557709;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
+       d="m 86.980649,113.17149 c 8.624681,1.22211 10.190907,0.34302 15.768381,-0.6914 1.54259,-0.85542 10.03239,0.31297 6.58213,1.58142 -5.08258,0.53408 -3.45152,-1.2253 -10.955968,0.15843 -1.588008,0.55933 -9.701094,0.30125 -11.394543,-1.04845 z"
+       id="path4517"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       style="opacity:1;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.02475154;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
+       d="m 98.432708,116.25617 c -3.64243,1.12556 -15.515477,0.71497 -15.377931,-2.04493 0.228137,-1.42355 -5.640588,-0.36212 -5.731606,-1.05049 4.14736,-0.985 8.914937,-0.40633 9.264379,1.32623 1.791737,2.50119 12.424036,-1.23998 11.845163,1.76915 z"
+       id="path4521"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       style="opacity:1;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29645836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
+       d="m 98.240442,85.527697 c 0.694879,2.429065 -0.171389,2.268105 -1.254906,3.453205 -2.21666,0.90466 -1.275835,2.68681 0.655372,3.07444 6.916682,7.3086 -8.505721,5.95412 -2.152498,2.98704 1.441767,-1.2706 -2.297888,-1.02629 -1.227899,-5.92248 6.395359,-0.73633 1.652463,-5.650141 2.059483,-5.038528 z"
+       id="path4544"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccccc" />
+    <text
+       xml:space="preserve"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.61458302px;line-height:6.61458302px;font-family:'Conduit 2 BRK';-inkscape-font-specification:'Conduit 2 BRK';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       id="text4558"
+       x="-3.3675961"
+       y="-68.848633"
+       transform="matrix(2.0583104,0.04404385,-0.04404385,2.0583104,-69.441849,-187.70019)"><textPath
+         xlink:href="#path4572"
+         id="textPath4574">Kampus Cafe</textPath></text>
+    <path
+       style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.75544739;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
+       d="m 60.429639,145.66518 c 15.437034,-6.02558 31.837023,-7.1078 49.765591,-0.34301"
+       id="path4572"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/img/kampuscafe2.svg	Mon Apr 24 12:12:39 2017 +0300
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="129.27827mm"
+   height="100.09245mm"
+   viewBox="0 0 129.27827 100.09245"
+   version="1.1"
+   id="svg8"
+   inkscape:version="0.92.1 r15371"
+   sodipodi:docname="kampuscafe2.svg"
+   inkscape:export-filename="/home/ccr/syntilista/logo.png"
+   inkscape:export-xdpi="58.939999"
+   inkscape:export-ydpi="58.939999">
+  <defs
+     id="defs2">
+    <path
+       style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.75544739;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
+       d="m 60.429639,145.66518 c 15.437034,-6.02558 31.837023,-7.1078 49.765591,-0.34301"
+       id="path4572-0"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.4142136"
+     inkscape:cx="-3.7309669"
+     inkscape:cy="174.37429"
+     inkscape:document-units="mm"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:snap-grids="true"
+     inkscape:snap-to-guides="false"
+     inkscape:snap-others="true"
+     inkscape:window-width="2558"
+     inkscape:window-height="1402"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:object-nodes="false"
+     inkscape:snap-global="false"
+     inkscape:snap-page="true"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <metadata
+     id="metadata5">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-33.675957,-79.041702)">
+    <rect
+       style="opacity:1;fill:#fcfcfc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.17169559;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
+       id="rect4489"
+       width="129.27827"
+       height="100.09245"
+       x="33.675957"
+       y="79.041702"
+       rx="5.263587"
+       ry="5.263587" />
+    <path
+       style="opacity:1;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29645836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
+       d="m 62.21151,118.69956 c 4.409165,4.34969 9.030096,25.27938 16.3955,51.46927 5.367766,4.2244 29.39154,4.59103 39.13391,-0.034 1.1932,-9.60266 1.68587,-11.18223 2.56869,-13.86554 3.83655,-3.17889 6.83172,-1.42472 10.68517,-4.10203 4.59353,-5.56191 4.89784,-12.30294 12.51234,-17.01653 11.42957,-10.40202 -0.92193,-19.15854 -10.80228,-16.60485 -0.91307,-3.14931 2.43292,-5.33053 -1.97617,-6.79193 -3.71085,-1.9731 -16.87131,-3.27169 -34.741268,-2.92759 -17.86995,0.34409 -26.211638,1.64575 -33.18058,4.41615 -0.891262,1.4726 -1.771128,2.95091 -0.595312,5.45705 z m 65.66492,-5.76331 c 3.19542,5.1354 -50.771937,6.89562 -62.453897,2.03699 12.90601,-5.85387 53.450777,-4.39622 62.453897,-2.03699 z m -63.682934,4.23437 c 6.050393,6.17716 22.651863,6.7611 37.741354,5.96705 -7.865682,17.72781 -6.030294,43.44196 -8.986434,44.69622 -2.244313,1.20734 -9.817979,0.33752 -11.823307,-0.78335 -2.944203,-3.12668 -5.890911,-32.32961 -16.931608,-49.87995 0,0 -6.050398,-6.17713 -5e-6,3e-5 z m 74.384514,12.47416 c -11.93575,12.24285 -9.20443,21.9716 -17.0974,21.90275 0.78925,-7.12082 6.78423,-27.12614 9.61589,-29.30576 6.54001,-0.98632 9.35816,4.16767 7.48151,7.40301 z"
+       id="path4491"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccczccccczcccczcccc" />
+    <path
+       style="opacity:1;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.75557709;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
+       d="m 91.377233,111.86187 c -2.088357,2.91364 5.794323,1.65264 11.371797,0.61822 1.54259,-0.85542 10.03239,0.31297 6.58213,1.58142 -5.08258,0.53408 -3.45152,-1.2253 -10.955968,0.15843 -5.750872,0.76747 -11.064699,-0.72036 -6.997959,-2.35807 z"
+       id="path4517"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       style="opacity:1;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.02475154;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
+       d="m 98.432708,116.25617 c -3.64243,1.12556 -15.515477,0.71497 -15.377931,-2.04493 0.228137,-1.42355 -4.798689,0.85396 -4.889707,0.16559 4.14736,-0.985 7.04405,-1.52887 7.393492,0.20369 1.791737,2.50119 13.453024,-1.33352 12.874151,1.67561 z"
+       id="path4521"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccc" />
+    <path
+       style="opacity:1;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29645836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
+       d="m 96.556644,83.750355 c 0.694879,2.429065 -0.171389,2.268105 -1.254906,3.453205 -2.21666,0.90466 -1.275835,2.68681 0.655372,3.07444 6.91668,7.3086 -8.505721,5.95412 -2.152498,2.98704 1.441767,-1.2706 -2.297888,-1.02629 -1.227899,-5.92248 6.395359,-0.73633 1.652463,-5.650141 2.059483,-5.038528 z"
+       id="path4544"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccccc" />
+    <text
+       xml:space="preserve"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.61455727px;line-height:6.61458302px;font-family:'URW Gothic L';-inkscape-font-specification:'URW Gothic L, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.26471969;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="text4558"
+       x="46.374069"
+       y="-181.29654"
+       transform="matrix(2.3147054,0,0,2.3057299,-1.4448132,-388.12719)"><textPath
+         xlink:href="#path4572"
+         id="textPath4574"> Kampus Cafe</textPath></text>
+    <path
+       style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.75544739;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
+       d="m 19.683807,220.93915 c 11.60216,-8.95683 35.634638,-8.22269 46.458301,-0.87217"
+       id="path4572"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="opacity:1;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.54500002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
+       d="m 132.84703,114.66028 c -5.06553,-2.70415 -23.78713,-4.06917 -30.98141,-2.78419 11.26023,0.50906 29.96108,1.98648 30.08841,4.73637 0.76361,0.0994 0.60544,-1.40801 0.893,-1.95218 z"
+       id="path4583"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccc" />
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/img/kampuscafe3.svg	Mon Apr 24 12:12:39 2017 +0300
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="129.27827mm"
+   height="100.09245mm"
+   viewBox="0 0 129.27827 100.09245"
+   version="1.1"
+   id="svg8"
+   inkscape:version="0.92.1 r15371"
+   sodipodi:docname="kampuscafe3.svg"
+   inkscape:export-filename="/home/ccr/syntilista/logo.png"
+   inkscape:export-xdpi="58.939999"
+   inkscape:export-ydpi="58.939999">
+  <defs
+     id="defs2">
+    <path
+       style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.75544739;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
+       d="m 60.429639,145.66518 c 15.437034,-6.02558 31.837023,-7.1078 49.765591,-0.34301"
+       id="path4572-0"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.75544739;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
+       d="m 19.683807,220.93915 c 11.60216,-8.95683 35.634638,-8.22269 46.458301,-0.87217"
+       id="path4572-6"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.75544739;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
+       d="m 19.683807,220.93915 c 11.60216,-8.95683 35.634638,-8.22269 46.458301,-0.87217"
+       id="path4572-3"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="2.0000001"
+     inkscape:cx="299.69183"
+     inkscape:cy="153.45574"
+     inkscape:document-units="mm"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:snap-grids="true"
+     inkscape:snap-to-guides="false"
+     inkscape:snap-others="true"
+     inkscape:window-width="2558"
+     inkscape:window-height="1402"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:object-nodes="false"
+     inkscape:snap-global="false"
+     inkscape:snap-page="true"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <metadata
+     id="metadata5">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-33.675957,-79.041702)">
+    <rect
+       style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.17169559;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
+       id="rect4489"
+       width="129.27827"
+       height="100.09245"
+       x="33.675957"
+       y="79.041702"
+       rx="5.263587"
+       ry="5.263587" />
+    <path
+       style="opacity:1;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29645836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
+       d="m 62.21151,118.69956 c 4.409165,4.34969 9.030096,25.27938 16.3955,51.46927 5.367766,4.2244 29.39154,4.59103 39.13391,-0.034 1.1932,-9.60266 1.68587,-11.18223 2.56869,-13.86554 3.83655,-3.17889 6.83172,-1.42472 10.68517,-4.10203 4.59353,-5.56191 4.89784,-12.30294 12.51234,-17.01653 11.42957,-10.40202 -0.92193,-19.15854 -10.80228,-16.60485 -0.91307,-3.14931 2.43292,-5.33053 -1.97617,-6.79193 -3.71085,-1.9731 -16.87131,-3.27169 -34.741268,-2.92759 -17.86995,0.34409 -26.211638,1.64575 -33.18058,4.41615 -0.891262,1.4726 -1.771128,2.95091 -0.595312,5.45705 z m 65.66492,-5.76331 c 3.19542,5.1354 -50.771937,6.89562 -62.453897,2.03699 12.90601,-5.85387 53.450777,-4.39622 62.453897,-2.03699 z m 10.70158,16.70853 c -11.93575,12.24285 -9.20443,21.9716 -17.0974,21.90275 0.78925,-7.12082 6.78423,-27.12614 9.61589,-29.30576 6.54001,-0.98632 9.35816,4.16767 7.48151,7.40301 z"
+       id="path4491"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccczccccccccc" />
+    <path
+       style="opacity:1;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.75557709;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
+       d="m 91.377233,111.86187 c -2.088357,2.91364 5.794323,1.65264 11.371797,0.61822 1.54259,-0.85542 10.03239,0.31297 6.58213,1.58142 -5.08258,0.53408 -3.45152,-1.2253 -10.955968,0.15843 -5.750872,0.76747 -11.064699,-0.72036 -6.997959,-2.35807 z"
+       id="path4517"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       style="opacity:1;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.02475154;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
+       d="m 98.432708,116.25617 c -3.64243,1.12556 -15.515477,0.71497 -15.377931,-2.04493 0.228137,-1.42355 -4.798689,0.85396 -4.889707,0.16559 4.14736,-0.985 7.04405,-1.52887 7.393492,0.20369 1.791737,2.50119 13.453024,-1.33352 12.874151,1.67561 z"
+       id="path4521"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccc" />
+    <path
+       style="opacity:1;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29645836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
+       d="m 96.556644,83.750355 c 0.694879,2.429065 -0.171389,2.268105 -1.254906,3.453205 -2.21666,0.90466 -1.275835,2.68681 0.655372,3.07444 6.91668,7.3086 -8.505721,5.95412 -2.152498,2.98704 1.441767,-1.2706 -2.297888,-1.02629 -1.227899,-5.92248 6.395359,-0.73633 1.652463,-5.650141 2.059483,-5.038528 z"
+       id="path4544"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccccc" />
+    <text
+       xml:space="preserve"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.61455727px;line-height:6.61458302px;font-family:'Xipital BRK';-inkscape-font-specification:'Xipital BRK';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26471969;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="text4558"
+       x="46.374069"
+       y="-181.29654"
+       transform="matrix(2.1253758,0,0,2.4298663,3.0532112,-416.20974)"><textPath
+         xlink:href="#path4572"
+         id="textPath4574"> Kampus Cafe</textPath></text>
+    <path
+       style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.75544739;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
+       d="m 19.94839,220.93915 c 12.131327,-8.19749 34.047138,-8.55371 46.32601,-1.00446"
+       id="path4572"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="opacity:1;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.54777914;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
+       d="m 131.53794,114.78751 c -4.95174,-2.69755 -22.98806,-3.6054 -29.86349,-2.054 10.8385,0.21846 28.85832,1.24493 29.06505,4.12916 0.73701,0.0829 0.53874,-1.49563 0.79844,-2.07516 z"
+       id="path4583"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccc" />
+    <text
+       xml:space="preserve"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11.30457115px;line-height:11.30461502px;font-family:'Xerox Malfunction BRK';-inkscape-font-specification:'Xerox Malfunction BRK';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.4524177;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="text4558-7"
+       x="-39.710236"
+       y="194.22658"
+       transform="scale(1.0019445,0.99805928)"> Kampus Cafe</text>
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/img/kampuscafe4.svg	Mon Apr 24 12:12:39 2017 +0300
@@ -0,0 +1,174 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="129.27827mm"
+   height="100.09245mm"
+   viewBox="0 0 129.27827 100.09245"
+   version="1.1"
+   id="svg8"
+   inkscape:version="0.92.1 r15371"
+   sodipodi:docname="kampuscafe4.svg"
+   inkscape:export-filename="/home/ccr/Syntilista/icon-64.png"
+   inkscape:export-xdpi="12.57"
+   inkscape:export-ydpi="12.57">
+  <defs
+     id="defs2">
+    <path
+       style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.75544739;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
+       d="m 60.429639,145.66518 c 15.437034,-6.02558 31.837023,-7.1078 49.765591,-0.34301"
+       id="path4572-0"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.75544739;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
+       d="m 19.683807,220.93915 c 11.60216,-8.95683 35.634638,-8.22269 46.458301,-0.87217"
+       id="path4572-6"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.75544739;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
+       d="m 19.683807,220.93915 c 11.60216,-8.95683 35.634638,-8.22269 46.458301,-0.87217"
+       id="path4572-3"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="2.0000002"
+     inkscape:cx="163.73568"
+     inkscape:cy="202.04481"
+     inkscape:document-units="mm"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:snap-grids="true"
+     inkscape:snap-to-guides="false"
+     inkscape:snap-others="true"
+     inkscape:window-width="1278"
+     inkscape:window-height="992"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:object-nodes="false"
+     inkscape:snap-global="false"
+     inkscape:snap-page="true"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <metadata
+     id="metadata5">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-33.675957,-79.041702)">
+    <rect
+       style="opacity:1;fill:#d86836;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.17169559;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
+       id="rect4489"
+       width="129.27827"
+       height="100.09245"
+       x="33.675957"
+       y="79.041702"
+       rx="5.263587"
+       ry="5.263587"
+       inkscape:export-xdpi="12.57"
+       inkscape:export-ydpi="12.57" />
+    <path
+       style="opacity:1;fill:#974d00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.59584385;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
+       id="path4511"
+       sodipodi:type="arc"
+       sodipodi:cx="93.987808"
+       sodipodi:cy="118.35854"
+       sodipodi:rx="33.208237"
+       sodipodi:ry="6.5481029"
+       sodipodi:start="5.4977871"
+       sodipodi:end="5.4924115"
+       sodipodi:open="true"
+       d="m 117.46958,113.72834 a 33.208237,6.5481029 0 0 1 0.0315,9.25418 33.208237,6.5481029 0 0 1 -46.931871,0.0187 33.208237,6.5481029 0 0 1 -0.157682,-9.25414 33.208237,6.5481029 0 0 1 46.931453,-0.0435"
+       transform="rotate(-1.4760674)" />
+    <g
+       id="g4516"
+       style="fill:#c76906;fill-opacity:1">
+      <path
+         sodipodi:nodetypes="ccccc"
+         inkscape:connector-curvature="0"
+         id="path4517"
+         d="m 91.377233,111.86187 c -2.088357,2.91364 5.794323,1.65264 11.371797,0.61822 1.54259,-0.85542 10.03239,0.31297 6.58213,1.58142 -5.08258,0.53408 -3.45152,-1.2253 -10.955968,0.15843 -5.750872,0.76747 -11.064699,-0.72036 -6.997959,-2.35807 z"
+         style="opacity:1;fill:#c76906;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.75557709;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1" />
+      <path
+         sodipodi:nodetypes="cccccc"
+         inkscape:connector-curvature="0"
+         id="path4521"
+         d="m 98.432708,116.25617 c -3.64243,1.12556 -15.515477,0.71497 -15.377931,-2.04493 0.228137,-1.42355 -4.798689,0.85396 -4.889707,0.16559 4.14736,-0.985 7.04405,-1.52887 7.393492,0.20369 1.791737,2.50119 13.453024,-1.33352 12.874151,1.67561 z"
+         style="opacity:1;fill:#c76906;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.02475154;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1" />
+      <path
+         sodipodi:nodetypes="cccc"
+         inkscape:connector-curvature="0"
+         id="path4583"
+         d="m 131.53794,114.78751 c -4.95174,-2.69755 -22.98806,-3.6054 -29.86349,-2.054 10.8385,0.21846 28.85832,1.24493 29.06505,4.12916 0.73701,0.0829 0.53874,-1.49563 0.79844,-2.07516 z"
+         style="opacity:1;fill:#c76906;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.54777914;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1" />
+    </g>
+    <path
+       style="opacity:1;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29645836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
+       d="m 62.21151,118.69956 c 4.409165,4.34969 9.030096,25.27938 16.3955,51.46927 5.367766,4.2244 29.39154,4.59103 39.13391,-0.034 1.1932,-9.60266 1.68587,-11.18223 2.56869,-13.86554 3.83655,-3.17889 6.83172,-1.42472 10.68517,-4.10203 4.59353,-5.56191 4.89784,-12.30294 12.51234,-17.01653 11.42957,-10.40202 -0.92193,-19.15854 -10.80228,-16.60485 -0.91307,-3.14931 2.43292,-5.33053 -1.97617,-6.79193 -3.71085,-1.9731 -16.87131,-3.27169 -34.741268,-2.92759 -17.86995,0.34409 -26.211638,1.64575 -33.18058,4.41615 -0.891262,1.4726 -1.771128,2.95091 -0.595312,5.45705 z m 65.66492,-5.76331 c 3.19542,5.1354 -50.771937,6.89562 -62.453897,2.03699 12.90601,-5.85387 53.450777,-4.39622 62.453897,-2.03699 z m 10.70158,16.70853 c -11.93575,12.24285 -9.20443,21.9716 -17.0974,21.90275 0.78925,-7.12082 6.78423,-27.12614 9.61589,-29.30576 6.54001,-0.98632 9.35816,4.16767 7.48151,7.40301 z"
+       id="path4491"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccczccccccccc" />
+    <path
+       style="opacity:1;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29645836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
+       d="m 100.92211,83.750355 c 0.69488,2.429065 -0.17139,2.268105 -1.254897,3.453205 -2.216664,0.90466 -1.275839,2.68681 0.655367,3.07444 6.91668,7.3086 -8.50572,5.95412 -2.152497,2.98704 1.44177,-1.2706 -2.297888,-1.02629 -1.227899,-5.92248 6.395356,-0.73633 1.652463,-5.650141 2.059483,-5.038528 z"
+       id="path4544"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccccc" />
+    <text
+       xml:space="preserve"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15.03176022px;line-height:15.03181839px;font-family:'Xipital BRK';-inkscape-font-specification:'Xipital BRK';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.60158265;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="text4558"
+       inkscape:transform-center-x="1.6681159"
+       inkscape:transform-center-y="2.9122167"><textPath
+         xlink:href="#path4497"
+         id="textPath4499">Cafe Kampus</textPath></text>
+    <path
+       style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none"
+       id="path4497"
+       sodipodi:type="arc"
+       sodipodi:cx="-98.053421"
+       sodipodi:cy="-134.99261"
+       sodipodi:rx="64.022369"
+       sodipodi:ry="28.862976"
+       sodipodi:start="0.71258024"
+       sodipodi:end="2.6663229"
+       d="m -49.609137,-116.12234 a 64.022369,28.862976 0 0 1 -56.023063,9.78976 64.022369,28.862976 0 0 1 -49.34795,-15.45296"
+       transform="scale(-1)"
+       sodipodi:open="true" />
+    <path
+       style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.14791916"
+       d="m 79.25037,98.520978 c -0.137248,-0.261792 -0.245338,-0.535534 -0.366883,-0.803253 -0.06638,-0.143254 -0.175431,-0.695861 -0.312471,-0.320844 -0.48232,0.837206 -0.955319,1.679254 -1.43402,2.518338 0.122262,0.343501 0.294066,0.669201 0.412933,1.012831 0.06332,0.15443 0.207886,0.39317 0.27848,0.10735 0.478881,-0.83596 0.946657,-1.676882 1.421968,-2.514429 z"
+       id="path4501"
+       inkscape:connector-curvature="0" />
+  </g>
+</svg>
Binary file img/logo.png has changed
--- a/kampuscafe1.svg	Wed Apr 12 12:16:00 2017 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:xlink="http://www.w3.org/1999/xlink"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="129.27827mm"
-   height="100.09245mm"
-   viewBox="0 0 129.27827 100.09245"
-   version="1.1"
-   id="svg8"
-   inkscape:version="0.92.1 r15371"
-   sodipodi:docname="kampuscafe.svg"
-   inkscape:export-filename="/home/ccr/syntilista/logo.png"
-   inkscape:export-xdpi="58.939999"
-   inkscape:export-ydpi="58.939999">
-  <defs
-     id="defs2" />
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="1.4142136"
-     inkscape:cx="367.702"
-     inkscape:cy="192.39597"
-     inkscape:document-units="mm"
-     inkscape:current-layer="layer1"
-     showgrid="false"
-     inkscape:snap-grids="true"
-     inkscape:snap-to-guides="false"
-     inkscape:snap-others="true"
-     inkscape:window-width="2558"
-     inkscape:window-height="1402"
-     inkscape:window-x="0"
-     inkscape:window-y="0"
-     inkscape:window-maximized="1"
-     inkscape:object-nodes="false"
-     inkscape:snap-global="false"
-     inkscape:snap-page="true"
-     fit-margin-top="0"
-     fit-margin-left="0"
-     fit-margin-right="0"
-     fit-margin-bottom="0" />
-  <metadata
-     id="metadata5">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title></dc:title>
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer"
-     id="layer1"
-     transform="translate(-33.675957,-79.041702)">
-    <rect
-       style="opacity:1;fill:#fcfcfc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.17169559;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
-       id="rect4489"
-       width="129.27827"
-       height="100.09245"
-       x="33.675957"
-       y="79.041702"
-       rx="1.4271281"
-       ry="1.4271282" />
-    <path
-       style="opacity:1;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29645836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
-       d="m 61.847708,113.50711 c -2.514304,4.28362 -1.074055,1.48352 -0.02466,6.03801 11.281973,17.3705 14.842373,47.33917 20.488129,50.62371 10.742374,2.02599 18.417143,-0.41726 29.278183,-0.034 7.36024,-0.56797 9.7848,-5.04174 11.16765,-14.72544 3.83655,-3.17889 5.69394,-1.87444 9.54739,-4.55175 4.59353,-5.56191 6.48809,-9.87079 11.20272,-15.70691 3.69312,-4.88682 6.85525,-13.78534 0.45512,-15.84033 -5.95141,-2.01246 -6.60877,-3.71891 -11.2574,-0.76452 -0.91307,-3.14931 2.43292,-5.33053 -1.97617,-6.79193 -3.71085,-1.9731 -16.87131,-3.27169 -34.741268,-2.92759 -17.86995,0.34409 -27.170753,1.91033 -34.139695,4.68073 z m 61.530802,-0.57086 c 1.30371,0.0876 8.26515,1.57927 3.58221,1.67173 -11.02663,1.67858 -41.8771,4.87511 -61.538187,0.36526 12.90601,-5.85387 48.952857,-4.39622 57.955977,-2.03699 z m -59.185014,4.23437 c 14.143363,10.25342 51.567824,1.63929 64.775664,0.63503 -11.91685,14.59736 -6.08219,45.66306 -15.15371,48.84621 -11.85472,-0.1447 -23.059354,1.86016 -29.777977,-0.035 -3.043523,-0.91095 -9.295304,-33.44794 -19.843972,-49.44627 z m 77.559514,12.20958 c -8.7291,14.02432 -8.79009,20.63449 -17.72206,19.98842 0.96521,-8.38622 3.73261,-19.14833 6.3172,-24.32052 0.89269,-1.78641 3.89953,-3.93174 6.91219,-1.94539 1.78418,1.17636 7.73946,1.06115 4.49267,6.27749 z"
-       id="path4491"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cccccccccczcccccczcccczscsss" />
-    <path
-       style="opacity:1;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.75557709;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
-       d="m 86.980649,113.17149 c 8.624681,1.22211 10.190907,0.34302 15.768381,-0.6914 1.54259,-0.85542 10.03239,0.31297 6.58213,1.58142 -5.08258,0.53408 -3.45152,-1.2253 -10.955968,0.15843 -1.588008,0.55933 -9.701094,0.30125 -11.394543,-1.04845 z"
-       id="path4517"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccc" />
-    <path
-       style="opacity:1;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.02475154;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
-       d="m 98.432708,116.25617 c -3.64243,1.12556 -15.515477,0.71497 -15.377931,-2.04493 0.228137,-1.42355 -5.640588,-0.36212 -5.731606,-1.05049 4.14736,-0.985 8.914937,-0.40633 9.264379,1.32623 1.791737,2.50119 12.424036,-1.23998 11.845163,1.76915 z"
-       id="path4521"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccc" />
-    <path
-       style="opacity:1;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29645836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
-       d="m 98.240442,85.527697 c 0.694879,2.429065 -0.171389,2.268105 -1.254906,3.453205 -2.21666,0.90466 -1.275835,2.68681 0.655372,3.07444 6.916682,7.3086 -8.505721,5.95412 -2.152498,2.98704 1.441767,-1.2706 -2.297888,-1.02629 -1.227899,-5.92248 6.395359,-0.73633 1.652463,-5.650141 2.059483,-5.038528 z"
-       id="path4544"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccccc" />
-    <text
-       xml:space="preserve"
-       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.61458302px;line-height:6.61458302px;font-family:'Conduit 2 BRK';-inkscape-font-specification:'Conduit 2 BRK';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-       id="text4558"
-       x="-3.3675961"
-       y="-68.848633"
-       transform="matrix(2.0583104,0.04404385,-0.04404385,2.0583104,-69.441849,-187.70019)"><textPath
-         xlink:href="#path4572"
-         id="textPath4574">Kampus Cafe</textPath></text>
-    <path
-       style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.75544739;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
-       d="m 60.429639,145.66518 c 15.437034,-6.02558 31.837023,-7.1078 49.765591,-0.34301"
-       id="path4572"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-  </g>
-</svg>
--- a/kampuscafe2.svg	Wed Apr 12 12:16:00 2017 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,132 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:xlink="http://www.w3.org/1999/xlink"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="129.27827mm"
-   height="100.09245mm"
-   viewBox="0 0 129.27827 100.09245"
-   version="1.1"
-   id="svg8"
-   inkscape:version="0.92.1 r15371"
-   sodipodi:docname="kampuscafe2.svg"
-   inkscape:export-filename="/home/ccr/syntilista/logo.png"
-   inkscape:export-xdpi="58.939999"
-   inkscape:export-ydpi="58.939999">
-  <defs
-     id="defs2">
-    <path
-       style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.75544739;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
-       d="m 60.429639,145.66518 c 15.437034,-6.02558 31.837023,-7.1078 49.765591,-0.34301"
-       id="path4572-0"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-  </defs>
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="1.4142136"
-     inkscape:cx="-3.7309669"
-     inkscape:cy="174.37429"
-     inkscape:document-units="mm"
-     inkscape:current-layer="layer1"
-     showgrid="false"
-     inkscape:snap-grids="true"
-     inkscape:snap-to-guides="false"
-     inkscape:snap-others="true"
-     inkscape:window-width="2558"
-     inkscape:window-height="1402"
-     inkscape:window-x="0"
-     inkscape:window-y="0"
-     inkscape:window-maximized="1"
-     inkscape:object-nodes="false"
-     inkscape:snap-global="false"
-     inkscape:snap-page="true"
-     fit-margin-top="0"
-     fit-margin-left="0"
-     fit-margin-right="0"
-     fit-margin-bottom="0" />
-  <metadata
-     id="metadata5">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title></dc:title>
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer"
-     id="layer1"
-     transform="translate(-33.675957,-79.041702)">
-    <rect
-       style="opacity:1;fill:#fcfcfc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.17169559;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
-       id="rect4489"
-       width="129.27827"
-       height="100.09245"
-       x="33.675957"
-       y="79.041702"
-       rx="5.263587"
-       ry="5.263587" />
-    <path
-       style="opacity:1;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29645836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
-       d="m 62.21151,118.69956 c 4.409165,4.34969 9.030096,25.27938 16.3955,51.46927 5.367766,4.2244 29.39154,4.59103 39.13391,-0.034 1.1932,-9.60266 1.68587,-11.18223 2.56869,-13.86554 3.83655,-3.17889 6.83172,-1.42472 10.68517,-4.10203 4.59353,-5.56191 4.89784,-12.30294 12.51234,-17.01653 11.42957,-10.40202 -0.92193,-19.15854 -10.80228,-16.60485 -0.91307,-3.14931 2.43292,-5.33053 -1.97617,-6.79193 -3.71085,-1.9731 -16.87131,-3.27169 -34.741268,-2.92759 -17.86995,0.34409 -26.211638,1.64575 -33.18058,4.41615 -0.891262,1.4726 -1.771128,2.95091 -0.595312,5.45705 z m 65.66492,-5.76331 c 3.19542,5.1354 -50.771937,6.89562 -62.453897,2.03699 12.90601,-5.85387 53.450777,-4.39622 62.453897,-2.03699 z m -63.682934,4.23437 c 6.050393,6.17716 22.651863,6.7611 37.741354,5.96705 -7.865682,17.72781 -6.030294,43.44196 -8.986434,44.69622 -2.244313,1.20734 -9.817979,0.33752 -11.823307,-0.78335 -2.944203,-3.12668 -5.890911,-32.32961 -16.931608,-49.87995 0,0 -6.050398,-6.17713 -5e-6,3e-5 z m 74.384514,12.47416 c -11.93575,12.24285 -9.20443,21.9716 -17.0974,21.90275 0.78925,-7.12082 6.78423,-27.12614 9.61589,-29.30576 6.54001,-0.98632 9.35816,4.16767 7.48151,7.40301 z"
-       id="path4491"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cccccccczccccczcccczcccc" />
-    <path
-       style="opacity:1;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.75557709;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
-       d="m 91.377233,111.86187 c -2.088357,2.91364 5.794323,1.65264 11.371797,0.61822 1.54259,-0.85542 10.03239,0.31297 6.58213,1.58142 -5.08258,0.53408 -3.45152,-1.2253 -10.955968,0.15843 -5.750872,0.76747 -11.064699,-0.72036 -6.997959,-2.35807 z"
-       id="path4517"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccc" />
-    <path
-       style="opacity:1;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.02475154;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
-       d="m 98.432708,116.25617 c -3.64243,1.12556 -15.515477,0.71497 -15.377931,-2.04493 0.228137,-1.42355 -4.798689,0.85396 -4.889707,0.16559 4.14736,-0.985 7.04405,-1.52887 7.393492,0.20369 1.791737,2.50119 13.453024,-1.33352 12.874151,1.67561 z"
-       id="path4521"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cccccc" />
-    <path
-       style="opacity:1;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29645836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
-       d="m 96.556644,83.750355 c 0.694879,2.429065 -0.171389,2.268105 -1.254906,3.453205 -2.21666,0.90466 -1.275835,2.68681 0.655372,3.07444 6.91668,7.3086 -8.505721,5.95412 -2.152498,2.98704 1.441767,-1.2706 -2.297888,-1.02629 -1.227899,-5.92248 6.395359,-0.73633 1.652463,-5.650141 2.059483,-5.038528 z"
-       id="path4544"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccccc" />
-    <text
-       xml:space="preserve"
-       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.61455727px;line-height:6.61458302px;font-family:'URW Gothic L';-inkscape-font-specification:'URW Gothic L, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.26471969;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="text4558"
-       x="46.374069"
-       y="-181.29654"
-       transform="matrix(2.3147054,0,0,2.3057299,-1.4448132,-388.12719)"><textPath
-         xlink:href="#path4572"
-         id="textPath4574"> Kampus Cafe</textPath></text>
-    <path
-       style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.75544739;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
-       d="m 19.683807,220.93915 c 11.60216,-8.95683 35.634638,-8.22269 46.458301,-0.87217"
-       id="path4572"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-    <path
-       style="opacity:1;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.54500002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
-       d="m 132.84703,114.66028 c -5.06553,-2.70415 -23.78713,-4.06917 -30.98141,-2.78419 11.26023,0.50906 29.96108,1.98648 30.08841,4.73637 0.76361,0.0994 0.60544,-1.40801 0.893,-1.95218 z"
-       id="path4583"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cccc" />
-  </g>
-</svg>
--- a/kampuscafe3.svg	Wed Apr 12 12:16:00 2017 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,151 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:xlink="http://www.w3.org/1999/xlink"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="129.27827mm"
-   height="100.09245mm"
-   viewBox="0 0 129.27827 100.09245"
-   version="1.1"
-   id="svg8"
-   inkscape:version="0.92.1 r15371"
-   sodipodi:docname="kampuscafe3.svg"
-   inkscape:export-filename="/home/ccr/syntilista/logo.png"
-   inkscape:export-xdpi="58.939999"
-   inkscape:export-ydpi="58.939999">
-  <defs
-     id="defs2">
-    <path
-       style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.75544739;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
-       d="m 60.429639,145.66518 c 15.437034,-6.02558 31.837023,-7.1078 49.765591,-0.34301"
-       id="path4572-0"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-    <path
-       style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.75544739;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
-       d="m 19.683807,220.93915 c 11.60216,-8.95683 35.634638,-8.22269 46.458301,-0.87217"
-       id="path4572-6"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-    <path
-       style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.75544739;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
-       d="m 19.683807,220.93915 c 11.60216,-8.95683 35.634638,-8.22269 46.458301,-0.87217"
-       id="path4572-3"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-  </defs>
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="2.0000001"
-     inkscape:cx="299.69183"
-     inkscape:cy="153.45574"
-     inkscape:document-units="mm"
-     inkscape:current-layer="layer1"
-     showgrid="false"
-     inkscape:snap-grids="true"
-     inkscape:snap-to-guides="false"
-     inkscape:snap-others="true"
-     inkscape:window-width="2558"
-     inkscape:window-height="1402"
-     inkscape:window-x="0"
-     inkscape:window-y="0"
-     inkscape:window-maximized="1"
-     inkscape:object-nodes="false"
-     inkscape:snap-global="false"
-     inkscape:snap-page="true"
-     fit-margin-top="0"
-     fit-margin-left="0"
-     fit-margin-right="0"
-     fit-margin-bottom="0" />
-  <metadata
-     id="metadata5">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer"
-     id="layer1"
-     transform="translate(-33.675957,-79.041702)">
-    <rect
-       style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.17169559;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
-       id="rect4489"
-       width="129.27827"
-       height="100.09245"
-       x="33.675957"
-       y="79.041702"
-       rx="5.263587"
-       ry="5.263587" />
-    <path
-       style="opacity:1;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29645836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
-       d="m 62.21151,118.69956 c 4.409165,4.34969 9.030096,25.27938 16.3955,51.46927 5.367766,4.2244 29.39154,4.59103 39.13391,-0.034 1.1932,-9.60266 1.68587,-11.18223 2.56869,-13.86554 3.83655,-3.17889 6.83172,-1.42472 10.68517,-4.10203 4.59353,-5.56191 4.89784,-12.30294 12.51234,-17.01653 11.42957,-10.40202 -0.92193,-19.15854 -10.80228,-16.60485 -0.91307,-3.14931 2.43292,-5.33053 -1.97617,-6.79193 -3.71085,-1.9731 -16.87131,-3.27169 -34.741268,-2.92759 -17.86995,0.34409 -26.211638,1.64575 -33.18058,4.41615 -0.891262,1.4726 -1.771128,2.95091 -0.595312,5.45705 z m 65.66492,-5.76331 c 3.19542,5.1354 -50.771937,6.89562 -62.453897,2.03699 12.90601,-5.85387 53.450777,-4.39622 62.453897,-2.03699 z m 10.70158,16.70853 c -11.93575,12.24285 -9.20443,21.9716 -17.0974,21.90275 0.78925,-7.12082 6.78423,-27.12614 9.61589,-29.30576 6.54001,-0.98632 9.35816,4.16767 7.48151,7.40301 z"
-       id="path4491"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cccccccczccccccccc" />
-    <path
-       style="opacity:1;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.75557709;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
-       d="m 91.377233,111.86187 c -2.088357,2.91364 5.794323,1.65264 11.371797,0.61822 1.54259,-0.85542 10.03239,0.31297 6.58213,1.58142 -5.08258,0.53408 -3.45152,-1.2253 -10.955968,0.15843 -5.750872,0.76747 -11.064699,-0.72036 -6.997959,-2.35807 z"
-       id="path4517"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccc" />
-    <path
-       style="opacity:1;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.02475154;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
-       d="m 98.432708,116.25617 c -3.64243,1.12556 -15.515477,0.71497 -15.377931,-2.04493 0.228137,-1.42355 -4.798689,0.85396 -4.889707,0.16559 4.14736,-0.985 7.04405,-1.52887 7.393492,0.20369 1.791737,2.50119 13.453024,-1.33352 12.874151,1.67561 z"
-       id="path4521"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cccccc" />
-    <path
-       style="opacity:1;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29645836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
-       d="m 96.556644,83.750355 c 0.694879,2.429065 -0.171389,2.268105 -1.254906,3.453205 -2.21666,0.90466 -1.275835,2.68681 0.655372,3.07444 6.91668,7.3086 -8.505721,5.95412 -2.152498,2.98704 1.441767,-1.2706 -2.297888,-1.02629 -1.227899,-5.92248 6.395359,-0.73633 1.652463,-5.650141 2.059483,-5.038528 z"
-       id="path4544"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccccc" />
-    <text
-       xml:space="preserve"
-       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.61455727px;line-height:6.61458302px;font-family:'Xipital BRK';-inkscape-font-specification:'Xipital BRK';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26471969;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="text4558"
-       x="46.374069"
-       y="-181.29654"
-       transform="matrix(2.1253758,0,0,2.4298663,3.0532112,-416.20974)"><textPath
-         xlink:href="#path4572"
-         id="textPath4574"> Kampus Cafe</textPath></text>
-    <path
-       style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.75544739;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
-       d="m 19.94839,220.93915 c 12.131327,-8.19749 34.047138,-8.55371 46.32601,-1.00446"
-       id="path4572"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-    <path
-       style="opacity:1;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.54777914;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
-       d="m 131.53794,114.78751 c -4.95174,-2.69755 -22.98806,-3.6054 -29.86349,-2.054 10.8385,0.21846 28.85832,1.24493 29.06505,4.12916 0.73701,0.0829 0.53874,-1.49563 0.79844,-2.07516 z"
-       id="path4583"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cccc" />
-    <text
-       xml:space="preserve"
-       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11.30457115px;line-height:11.30461502px;font-family:'Xerox Malfunction BRK';-inkscape-font-specification:'Xerox Malfunction BRK';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.4524177;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="text4558-7"
-       x="-39.710236"
-       y="194.22658"
-       transform="scale(1.0019445,0.99805928)"> Kampus Cafe</text>
-  </g>
-</svg>
--- a/kampuscafe4.svg	Wed Apr 12 12:16:00 2017 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,174 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:xlink="http://www.w3.org/1999/xlink"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="129.27827mm"
-   height="100.09245mm"
-   viewBox="0 0 129.27827 100.09245"
-   version="1.1"
-   id="svg8"
-   inkscape:version="0.92.1 r15371"
-   sodipodi:docname="kampuscafe4.svg"
-   inkscape:export-filename="/home/ccr/Syntilista/icon-64.png"
-   inkscape:export-xdpi="12.57"
-   inkscape:export-ydpi="12.57">
-  <defs
-     id="defs2">
-    <path
-       style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.75544739;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
-       d="m 60.429639,145.66518 c 15.437034,-6.02558 31.837023,-7.1078 49.765591,-0.34301"
-       id="path4572-0"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-    <path
-       style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.75544739;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
-       d="m 19.683807,220.93915 c 11.60216,-8.95683 35.634638,-8.22269 46.458301,-0.87217"
-       id="path4572-6"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-    <path
-       style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.75544739;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
-       d="m 19.683807,220.93915 c 11.60216,-8.95683 35.634638,-8.22269 46.458301,-0.87217"
-       id="path4572-3"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-  </defs>
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="2.0000002"
-     inkscape:cx="163.73568"
-     inkscape:cy="202.04481"
-     inkscape:document-units="mm"
-     inkscape:current-layer="layer1"
-     showgrid="false"
-     inkscape:snap-grids="true"
-     inkscape:snap-to-guides="false"
-     inkscape:snap-others="true"
-     inkscape:window-width="1278"
-     inkscape:window-height="992"
-     inkscape:window-x="0"
-     inkscape:window-y="0"
-     inkscape:window-maximized="1"
-     inkscape:object-nodes="false"
-     inkscape:snap-global="false"
-     inkscape:snap-page="true"
-     fit-margin-top="0"
-     fit-margin-left="0"
-     fit-margin-right="0"
-     fit-margin-bottom="0" />
-  <metadata
-     id="metadata5">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer"
-     id="layer1"
-     transform="translate(-33.675957,-79.041702)">
-    <rect
-       style="opacity:1;fill:#d86836;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.17169559;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
-       id="rect4489"
-       width="129.27827"
-       height="100.09245"
-       x="33.675957"
-       y="79.041702"
-       rx="5.263587"
-       ry="5.263587"
-       inkscape:export-xdpi="12.57"
-       inkscape:export-ydpi="12.57" />
-    <path
-       style="opacity:1;fill:#974d00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.59584385;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
-       id="path4511"
-       sodipodi:type="arc"
-       sodipodi:cx="93.987808"
-       sodipodi:cy="118.35854"
-       sodipodi:rx="33.208237"
-       sodipodi:ry="6.5481029"
-       sodipodi:start="5.4977871"
-       sodipodi:end="5.4924115"
-       sodipodi:open="true"
-       d="m 117.46958,113.72834 a 33.208237,6.5481029 0 0 1 0.0315,9.25418 33.208237,6.5481029 0 0 1 -46.931871,0.0187 33.208237,6.5481029 0 0 1 -0.157682,-9.25414 33.208237,6.5481029 0 0 1 46.931453,-0.0435"
-       transform="rotate(-1.4760674)" />
-    <g
-       id="g4516"
-       style="fill:#c76906;fill-opacity:1">
-      <path
-         sodipodi:nodetypes="ccccc"
-         inkscape:connector-curvature="0"
-         id="path4517"
-         d="m 91.377233,111.86187 c -2.088357,2.91364 5.794323,1.65264 11.371797,0.61822 1.54259,-0.85542 10.03239,0.31297 6.58213,1.58142 -5.08258,0.53408 -3.45152,-1.2253 -10.955968,0.15843 -5.750872,0.76747 -11.064699,-0.72036 -6.997959,-2.35807 z"
-         style="opacity:1;fill:#c76906;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.75557709;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1" />
-      <path
-         sodipodi:nodetypes="cccccc"
-         inkscape:connector-curvature="0"
-         id="path4521"
-         d="m 98.432708,116.25617 c -3.64243,1.12556 -15.515477,0.71497 -15.377931,-2.04493 0.228137,-1.42355 -4.798689,0.85396 -4.889707,0.16559 4.14736,-0.985 7.04405,-1.52887 7.393492,0.20369 1.791737,2.50119 13.453024,-1.33352 12.874151,1.67561 z"
-         style="opacity:1;fill:#c76906;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.02475154;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1" />
-      <path
-         sodipodi:nodetypes="cccc"
-         inkscape:connector-curvature="0"
-         id="path4583"
-         d="m 131.53794,114.78751 c -4.95174,-2.69755 -22.98806,-3.6054 -29.86349,-2.054 10.8385,0.21846 28.85832,1.24493 29.06505,4.12916 0.73701,0.0829 0.53874,-1.49563 0.79844,-2.07516 z"
-         style="opacity:1;fill:#c76906;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.54777914;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1" />
-    </g>
-    <path
-       style="opacity:1;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29645836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
-       d="m 62.21151,118.69956 c 4.409165,4.34969 9.030096,25.27938 16.3955,51.46927 5.367766,4.2244 29.39154,4.59103 39.13391,-0.034 1.1932,-9.60266 1.68587,-11.18223 2.56869,-13.86554 3.83655,-3.17889 6.83172,-1.42472 10.68517,-4.10203 4.59353,-5.56191 4.89784,-12.30294 12.51234,-17.01653 11.42957,-10.40202 -0.92193,-19.15854 -10.80228,-16.60485 -0.91307,-3.14931 2.43292,-5.33053 -1.97617,-6.79193 -3.71085,-1.9731 -16.87131,-3.27169 -34.741268,-2.92759 -17.86995,0.34409 -26.211638,1.64575 -33.18058,4.41615 -0.891262,1.4726 -1.771128,2.95091 -0.595312,5.45705 z m 65.66492,-5.76331 c 3.19542,5.1354 -50.771937,6.89562 -62.453897,2.03699 12.90601,-5.85387 53.450777,-4.39622 62.453897,-2.03699 z m 10.70158,16.70853 c -11.93575,12.24285 -9.20443,21.9716 -17.0974,21.90275 0.78925,-7.12082 6.78423,-27.12614 9.61589,-29.30576 6.54001,-0.98632 9.35816,4.16767 7.48151,7.40301 z"
-       id="path4491"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cccccccczccccccccc" />
-    <path
-       style="opacity:1;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29645836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:20;stroke-opacity:1"
-       d="m 100.92211,83.750355 c 0.69488,2.429065 -0.17139,2.268105 -1.254897,3.453205 -2.216664,0.90466 -1.275839,2.68681 0.655367,3.07444 6.91668,7.3086 -8.50572,5.95412 -2.152497,2.98704 1.44177,-1.2706 -2.297888,-1.02629 -1.227899,-5.92248 6.395356,-0.73633 1.652463,-5.650141 2.059483,-5.038528 z"
-       id="path4544"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccccc" />
-    <text
-       xml:space="preserve"
-       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15.03176022px;line-height:15.03181839px;font-family:'Xipital BRK';-inkscape-font-specification:'Xipital BRK';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.60158265;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="text4558"
-       inkscape:transform-center-x="1.6681159"
-       inkscape:transform-center-y="2.9122167"><textPath
-         xlink:href="#path4497"
-         id="textPath4499">Cafe Kampus</textPath></text>
-    <path
-       style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none"
-       id="path4497"
-       sodipodi:type="arc"
-       sodipodi:cx="-98.053421"
-       sodipodi:cy="-134.99261"
-       sodipodi:rx="64.022369"
-       sodipodi:ry="28.862976"
-       sodipodi:start="0.71258024"
-       sodipodi:end="2.6663229"
-       d="m -49.609137,-116.12234 a 64.022369,28.862976 0 0 1 -56.023063,9.78976 64.022369,28.862976 0 0 1 -49.34795,-15.45296"
-       transform="scale(-1)"
-       sodipodi:open="true" />
-    <path
-       style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.14791916"
-       d="m 79.25037,98.520978 c -0.137248,-0.261792 -0.245338,-0.535534 -0.366883,-0.803253 -0.06638,-0.143254 -0.175431,-0.695861 -0.312471,-0.320844 -0.48232,0.837206 -0.955319,1.679254 -1.43402,2.518338 0.122262,0.343501 0.294066,0.669201 0.412933,1.012831 0.06332,0.15443 0.207886,0.39317 0.27848,0.10735 0.478881,-0.83596 0.946657,-1.676882 1.421968,-2.514429 z"
-       id="path4501"
-       inkscape:connector-curvature="0" />
-  </g>
-</svg>
Binary file logo.png has changed
--- a/main.cpp	Wed Apr 12 12:16:00 2017 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1189 +0,0 @@
-//
-// Syntilista - velkalistasovellus Kampus-kahvilaan
-// Programmed and designed by Matti Hämäläinen <ccr@tnsp.org>
-// (C) Copyright 2017 Tecnic Software productions (TNSP)
-//
-// Distributed under 3-clause BSD style license, refer to
-// included file "COPYING" for exact terms.
-//
-#include <QApplication>
-#include <QMessageBox>
-#include <QSettings>
-#include "main.h"
-#include "ui_mainwindow.h"
-#include "ui_editperson.h"
-
-double setScale;
-
-
-int errorMsg(QString title, QString msg)
-{
-    QMessageBox dlg;
-
-    dlg.setText(title);
-    dlg.setInformativeText(msg);
-    dlg.setTextFormat(Qt::RichText);
-    dlg.setIcon(QMessageBox::Critical);
-    dlg.setStandardButtons(QMessageBox::Ok);
-    dlg.setDefaultButton(QMessageBox::Ok);
-
-    return dlg.exec();
-}
-
-
-double moneyStrToValue(const QString &str)
-{
-    QString str2 = str;
-    return str2.replace(",", ".").toDouble();
-}
-
-
-QString moneyValueToStr(double val)
-{
-    return QStringLiteral("%1").arg(val, 1, 'f', 2);
-}
-
-
-QString cleanupStr(const QString &str)
-{
-    return str.simplified().trimmed();
-}
-
-
-const QString dateTimeToStr(const QDateTime &val)
-{
-    QDateTime tmp = val;
-    tmp.setOffsetFromUtc(0);
-    return tmp.toLocalTime().toString(QStringLiteral("yyyy-MM-dd hh:mm"));
-}
-
-
-bool checkAndReportSQLError(const QString where, const QSqlError &err)
-{
-    if (err.isValid())
-    {
-        printf("SQL Error in %s: %s\n",
-            where.toUtf8().constData(),
-            err.text().toUtf8().constData());
-        return false;
-    }
-    else
-        return true;
-}
-
-
-void PersonInfo::dump()
-{
-    printf("PersonInfo() #%lld '%s %s' (added=%s, updated=%s, balance %1.2f)\n#%s#\n",
-        id,
-        firstName.toUtf8().constData(),
-        lastName.toUtf8().constData(),
-        dateTimeToStr(added).toUtf8().constData(),
-        dateTimeToStr(updated).toUtf8().constData(),
-        balance,
-        extraInfo.toUtf8().constData());
-}
-
-
-//
-// Get PersonInfo record from SQL database for specified persn ID #
-//
-bool getPersonInfo(qint64 id, PersonInfo &info)
-{
-    QSqlQuery person;
-    person.prepare(
-        "SELECT id,first_name,last_name,extra_info,added,updated, "
-        "(SELECT SUM(value) FROM transactions WHERE transactions.person=people.id) AS balance "
-        "FROM people WHERE id=?");
-
-    person.addBindValue(id);
-    person.exec();
-    if (!person.next())
-        return false;
-
-    info.id         = person.value(0).toInt();
-    info.firstName  = person.value(1).toString();
-    info.lastName   = person.value(2).toString();
-    info.extraInfo  = person.value(3).toString();
-    info.added      = person.value(4).toDateTime();
-    info.updated    = person.value(5).toDateTime();
-    info.balance    = person.value(6).toDouble();
-
-    person.finish();
-
-    return true;
-}
-
-
-void setCommonStyleSheet(QWidget *widget)
-{
-    // Clamp scale value
-    if (setScale < 0.5f)
-        setScale = 0.5f;
-    if (setScale > 3.0f)
-        setScale = 3.0f;
-
-    // Set the stylesheet
-    widget->setStyleSheet(
-        QStringLiteral(
-        "* { font-size: %1pt; }"
-        "QPushButton { font-size: %2pt; padding: 0.25em; }"
-        "#button_AddDebt[enabled='true'] { font-size: %3pt; background-color: #900; color: white; }"
-        "#button_PayDebt[enabled='true'] { font-size: %3pt; background-color: #090; color: white; }"
-        "#button_PayFullDebt[enabled='true'] { background-color: #060; color: white; }"
-
-        "#button_AddDebt[enabled='false'] { font-size: %3pt; background-color: #622; color: black; }"
-        "#button_PayDebt[enabled='false'] { font-size: %3pt; background-color: #262; color: black; }"
-        "#button_PayFullDebt[enabled='false'] { background-color: #131; color: black; }"
-
-        "#label_PersonName { font-size: %5pt; font-weight: bold;  }"
-        "#label_BalanceValue { font-size: %4pt; font-weight: bold; }"
-        "#label_EUR { font-size: %4pt; font-weight: bold; }"
-        "#edit_Amount { font-size: %4pt; margin: 0.5em; padding: 0.5em; }"
-        ).
-        arg(12 * setScale).
-        arg(14 * setScale).
-        arg(16 * setScale).
-        arg(18 * setScale).
-        arg(20 * setScale)
-        );
-}
-
-
-int main(int argc, char *argv[])
-{
-    QApplication sapp(argc, argv);
-
-    //
-    // Initialize / open SQL database connection
-    //
-    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
-    db.setDatabaseName(qApp->applicationDirPath() +
-        QDir::separator() + APP_SQLITE_FILE);
-
-    if (!db.open())
-    {
-        errorMsg(
-            QObject::tr("Tietokantaa ei voitu avata"),
-            QObject::tr("Yhteyttä SQL-tietokantaan ei saatu.<br><br>Virhe: %1<br><br>").
-            arg(db.lastError().text())
-            );
-        return 1;
-    }
-
-    QSqlQuery query;
-    if (!db.tables().contains("people"))
-    {
-        query.exec(QStringLiteral(
-            "CREATE TABLE people (id INTEGER PRIMARY KEY, "
-            "first_name VARCHAR(128) NOT NULL, "
-            "last_name VARCHAR(128) NOT NULL, "
-            "extra_info VARCHAR(2048), "
-            "added DATETIME NOT NULL, "
-            "updated DATETIME NOT NULL)"));
-
-        checkAndReportSQLError("CREATE TABLE people", query.lastError());
-    }
-
-    if (!db.tables().contains("transactions"))
-    {
-        query.exec(QStringLiteral(
-            "CREATE TABLE transactions ("
-            "id INTEGER PRIMARY KEY, "
-            "person INT NOT NULL, "
-            "value REAL, "
-            "added DATETIME NOT NULL)"));
-
-        checkAndReportSQLError("CREATE TABLE transactions", query.lastError());
-    }
-
-    SyntilistaMainWindow swin;
-    swin.show();
-    return sapp.exec();
-}
-
-
-//
-// Main application window code
-//
-SyntilistaMainWindow::SyntilistaMainWindow(QWidget *parent) :
-    QMainWindow(parent),
-    ui(new Ui::SyntilistaMainWindow)
-{
-    // Setup UI
-    ui->setupUi(this);
-
-    // Read config
-    readSettings();
-
-    // Setup other UI things
-    setWindowIcon(QIcon(QPixmap(":/img/icon-64.png")));
-    setWindowTitle(tr("%1 versio %3").
-        arg(tr(APP_NAME)).
-        arg(tr(APP_VERSION)));
-
-    QPixmap logoImage(":/img/logo.png");
-    ui->button_LogoImage->setPixmap(logoImage);
-    ui->button_LogoImage->setAlignment(Qt::AlignCenter);
-
-    setCommonStyleSheet(this);
-
-    // Validator for amount input
-    //ui->edit_Amount->setValidator(new QDoubleValidator(0, 1000, 2, this));
-    QRegExp vregex("\\d{0,4}[,.]\\d{0,2}|\\d{0,4}");
-    ui->edit_Amount->setValidator(new QRegExpValidator(vregex, this));
-
-    // Setup person list filtering and sorting
-    peopleSortIndex = 1;
-    peopleSortOrder = Qt::AscendingOrder;
-    peopleFilter = "";
-
-    model_People = new PersonSQLModel();
-    updatePersonList();
-
-    ui->tableview_People->setModel(model_People);
-    ui->tableview_People->setColumnHidden(0, true);
-    ui->tableview_People->setItemDelegate(new QSqlRelationalDelegate(ui->tableview_People));
-    ui->tableview_People->verticalHeader()->setVisible(false);
-    ui->tableview_People->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
-    ui->tableview_People->setSortingEnabled(true);
-    ui->tableview_People->sortByColumn(peopleSortIndex, peopleSortOrder);
-
-    connect(
-        ui->tableview_People->selectionModel(),
-        SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)),
-        this,
-        SLOT(selectedPersonChanged(const QModelIndex &, const QModelIndex &)));
-
-    connect(
-        ui->tableview_People->horizontalHeader(),
-        SIGNAL(sortIndicatorChanged(int, Qt::SortOrder)),
-        this,
-        SLOT(updateSortOrder(int, Qt::SortOrder)));
-
-    ui->tableview_People->horizontalHeader()->setSortIndicator(1, Qt::AscendingOrder);
-
-    model_Latest = new TransactionSQLModel();
-    ui->tableview_Latest->setModel(model_Latest);
-    ui->tableview_Latest->setItemDelegate(new QSqlRelationalDelegate(ui->tableview_Latest));
-    ui->tableview_Latest->verticalHeader()->setVisible(false);
-    ui->tableview_Latest->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
-
-    setActivePerson(-1);
-
-    // Keyboard shortcuts
-    ui->button_Quit->setShortcut(QKeySequence(Qt::Key_F10));
-    new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q), this, SLOT(on_button_Quit_clicked()));
-
-    ui->button_AddPerson->setShortcut(QKeySequence(Qt::Key_F5));
-    ui->button_DeletePerson->setShortcut(QKeySequence(Qt::Key_F8));
-    ui->button_EditPerson->setShortcut(QKeySequence(Qt::Key_F6));
-    ui->button_ClearFilter->setShortcut(QKeySequence(Qt::Key_Escape));
-    ui->button_Help->setShortcut(QKeySequence(Qt::Key_F1));
-    ui->button_About->setShortcut(QKeySequence(Qt::Key_F2));
-
-    new QShortcut(QKeySequence(QKeySequence::ZoomIn), this, SLOT(changeUIZoomIn()));
-    new QShortcut(QKeySequence(QKeySequence::ZoomOut), this, SLOT(changeUIZoomOut()));
-    new QShortcut(QKeySequence(Qt::CTRL + Qt::KeypadModifier + Qt::Key_Plus), this, SLOT(changeUIZoomIn()));
-    new QShortcut(QKeySequence(Qt::CTRL + Qt::KeypadModifier + Qt::Key_Minus), this, SLOT(changeUIZoomOut()));
-    new QShortcut(QKeySequence(Qt::CTRL + Qt::KeypadModifier + Qt::Key_0), this, SLOT(changeUIZoomReset()));
-    new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_0), this, SLOT(changeUIZoomReset()));
-
-    new QShortcut(QKeySequence(Qt::Key_PageUp), this, SLOT(selectRowPrev()));
-    new QShortcut(QKeySequence(Qt::Key_PageDown), this, SLOT(selectRowNext()));
-
-    new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Return), this, SLOT(focusDebtEdit()));
-}
-
-
-SyntilistaMainWindow::~SyntilistaMainWindow()
-{
-    saveSettings();
-
-    delete ui;
-    delete model_People;
-    delete model_Latest;
-}
-
-
-void SyntilistaMainWindow::statusMsg(const QString &msg)
-{
-    ui->statusbar->showMessage(msg);
-}
-
-
-void SyntilistaMainWindow::readSettings()
-{
-    QSettings settings(APP_VENDOR, APP_ID);
-    move(settings.value("pos", QPoint(100, 100)).toPoint());
-    resize(settings.value("size", QSize(1000, 600)).toSize());
-    setScale = settings.value("scale", 1.0f).toDouble();
-}
-
-
-void SyntilistaMainWindow::saveSettings()
-{
-    QSettings settings(APP_VENDOR, APP_ID);
-    settings.setValue("pos", pos());
-    settings.setValue("size", size());
-    settings.setValue("scale", setScale);
-}
-
-
-void SyntilistaMainWindow::changeUIZoomIn()
-{
-    setScale += 0.1f;
-    setCommonStyleSheet(this);
-}
-
-
-void SyntilistaMainWindow::changeUIZoomOut()
-{
-    setScale -= 0.1f;
-    setCommonStyleSheet(this);
-}
-
-
-void SyntilistaMainWindow::changeUIZoomReset()
-{
-    setScale = 1.0f;
-    setCommonStyleSheet(this);
-}
-
-
-void SyntilistaMainWindow::selectedPersonChanged(const QModelIndex &curr, const QModelIndex &prev)
-{
-    (void) prev;
-    int row = curr.row();
-    if (row >= 0)
-    {
-        const QAbstractItemModel *model = curr.model();
-        setActivePerson(model->data(model->index(row, 0)).toInt());
-    }
-    else
-        setActivePerson(-1);
-}
-
-
-void SyntilistaMainWindow::updateSortOrder(int index, Qt::SortOrder order)
-{
-    peopleSortIndex = index;
-    peopleSortOrder = order;
-    updatePersonList();
-}
-
-
-void SyntilistaMainWindow::setActivePerson(qint64 id)
-{
-    currPerson.id = id;
-
-    ui->button_EditPerson->setEnabled(id >= 0);
-
-    if (id >= 0)
-    {
-        if (!getPersonInfo(id, currPerson))
-        {
-            statusMsg(tr("Virhe! Ei henkilöä ID:llä #%1").arg(id));
-        }
-        else
-        {
-            ui->personGB->setEnabled(true);
-            ui->label_PersonName->setText(currPerson.lastName +", "+ currPerson.firstName);
-
-            ui->label_BalanceValue->setText(moneyValueToStr(currPerson.balance));
-            ui->label_BalanceValue->setStyleSheet(currPerson.balance < 0 ? "color: red;" : "color: green;");
-            ui->button_PayFullDebt->setEnabled(currPerson.balance < 0);
-
-            QSqlQuery query;
-            query.prepare("SELECT id,value,added FROM transactions WHERE person=? ORDER BY added DESC LIMIT 5");
-            query.addBindValue(id);
-            query.exec();
-            checkAndReportSQLError("SELECT transactions for tableview_Latest", query.lastError());
-
-            model_Latest->setQuery(query);
-
-            model_Latest->setHeaderData(0, Qt::Horizontal, tr("ID"));
-            model_Latest->setHeaderData(1, Qt::Horizontal, tr("Summa"));
-            model_Latest->setHeaderData(2, Qt::Horizontal, tr("Aika"));
-
-            ui->tableview_Latest->setModel(model_Latest);
-            ui->tableview_Latest->setColumnHidden(0, true);
-            ui->tableview_Latest->verticalHeader()->setVisible(false);
-            ui->tableview_Latest->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
-
-            setCommonStyleSheet(this);
-            return; // Ugly
-        }
-    }
-
-    // In case of id < 0 or errors ..
-    ui->personGB->setEnabled(false);
-    ui->edit_Amount->clear();
-    ui->label_BalanceValue->setText("--");
-    ui->label_BalanceValue->setStyleSheet(NULL);
-    ui->label_PersonName->setText("???");
-    ui->tableview_Latest->setModel(NULL);
-    setCommonStyleSheet(this);
-}
-
-
-//
-// Widget slot handlers
-//
-void SyntilistaMainWindow::on_button_Quit_clicked()
-{
-    close();
-}
-
-
-void SyntilistaMainWindow::on_button_About_clicked()
-{
-    QMessageBox dlg;
-
-    setCommonStyleSheet(&dlg);
-    dlg.setWindowTitle(tr("Tietoja ohjelmasta"));
-    dlg.setTextFormat(Qt::RichText);
-    dlg.setIconPixmap(QPixmap(":/img/icon-64.png"));
-    dlg.setStandardButtons(QMessageBox::Ok);
-    dlg.setDefaultButton(QMessageBox::Ok);
-
-    //dlg.setInformativeText(tr(
-    dlg.setText(tr(
-        "<h1>%1 v%2</h1>"
-        "<p>"
-        "<b>Ohjelmoinut ja kehittänyt Matti Hämäläinen &lt;ccr@tnsp.org&gt;<br>"
-        "(C) Copyright 2017 Tecnic Software productions (TNSP)</b><br>"
-        "<br>"
-        "Kehitetty Raahen kaupungin Hanketoiminta ja Kehittäminen -yksikön "
-        "alaisuudessa Café Kampuksen käyttöön.<br>"
-        "</p>"
-        "<p>"
-        "Ohjelma ja sen lähdekoodi ovat uudemman BSD-tyylisen lisenssin alaisia. "
-        "Lue ohjelman mukana tullut tiedosto \"COPYING\" (tai \"COPYING.txt\") "
-        "nähdäksesi täydelliset lisenssiehdot."
-        "</p>"
-        ).
-        arg(tr(APP_NAME)).
-        arg(tr(APP_VERSION))
-        );
-
-    dlg.exec();
-}
-
-
-void SyntilistaMainWindow::on_button_Help_clicked()
-{
-    QMessageBox dlg;
-
-    setCommonStyleSheet(&dlg);
-    dlg.setWindowTitle(tr("Tietoja ohjelmasta"));
-    dlg.setTextFormat(Qt::RichText);
-    dlg.setIconPixmap(QPixmap(":/img/icon-64.png"));
-    dlg.setStandardButtons(QMessageBox::Ok);
-    dlg.setDefaultButton(QMessageBox::Ok);
-
-    dlg.setText(tr(
-        "<h1>Pikanäppäimet</h1>"
-        "<table>"
-        "<tr><td><b>F1</b></td><td>Tämä tietoikkuna</td></tr>"
-        "<tr><td><b>F2</b></td><td>Tietoja ohjelmasta</td></tr>"
-        "<tr><td><b>CTRL + Q</b></td><td>Ohjelman lopetus</td></tr>"
-        "<tr><td><b>CTRL + Page Up</b></td><td>Suurenna ohjelman tekstejä/käyttöliittymää</td></tr>"
-        "<tr><td><b>CTRL + Page Down</b></td><td>Pienennä ohjelman tekstejä/käyttöliittymää</td></tr>"
-        "<tr></tr>"
-        "<tr><td><b>Esc</b></td><td>Tyhjennä 'Etsi / suodata' kenttä ja siirry siihen</td></tr>"
-        "<tr><td><b>CTRL + Enter</b></td><td>Siirry summan syöttökenttään</td></tr>"
-        "<tr><td><b>Page Up</b></td><td>Siirry ylös henkilölistassa</td></tr>"
-        "<tr><td><b>Page Down</b></td><td>Siirry alas henkilölistassa</td></tr>"
-        "<tr></tr>"
-        "<tr><td><b>F5</b></td><td>Lisää uusi henkilö</td></tr>"
-        "<tr><td><b>F6</b></td><td>Muokkaa henkilöä</td></tr>"
-        "<tr><td><b>F8</b></td><td>Poista henkilö</td></tr>"
-        "</table>"
-        ));
-
-    dlg.exec();
-}
-
-
-void SyntilistaMainWindow::on_button_DeletePerson_clicked()
-{
-    if (currPerson.id <= 0)
-    {
-        statusMsg(tr("Ei valittua henkilöä!"));
-        return;
-    }
-
-    PersonInfo info;
-    if (!getPersonInfo(currPerson.id, info))
-    {
-        statusMsg(tr("Virhe! Ei henkilöä ID:llä #%1").arg(currPerson.id));
-        return;
-    }
-
-    QMessageBox dlg;
-    setCommonStyleSheet(&dlg);
-    dlg.setText(tr("Varmistus"));
-    dlg.setInformativeText(
-        tr("<br>Haluatko varmasti poistaa henkilön:<br>"
-        "<br>"
-        "<b>'%1, %2'</b> <i>(ID #%3)</i>?<br>"
-        "<br>"
-        "Tämä poistaa sekä henkilön ja hänen koko tapahtumahistoriansa PYSYVÄSTI!<br>").
-        arg(info.lastName).arg(info.firstName).arg(info.id));
-
-    dlg.setTextFormat(Qt::RichText);
-    dlg.setIcon(QMessageBox::Question);
-    dlg.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
-    dlg.setButtonText(QMessageBox::Yes, tr("Kyllä"));
-    dlg.setButtonText(QMessageBox::No, tr("Ei / peruuta"));
-    dlg.setDefaultButton(QMessageBox::No);
-
-    if (dlg.exec() == QMessageBox::Yes)
-    {
-        int rv = model_People->deletePerson(info.id);
-        updatePersonList();
-        setActivePerson(-1);
-        if (rv != 0)
-        {
-            errorMsg(tr("SQL-tietokantavirhe"),
-                tr("Henkilön tietoja poistettaessa tapahtui virhe #%1.").
-                arg(rv));
-        }
-        else
-        {
-            statusMsg(tr("Henkilö '%1 %2' (ID #%3) poistettu.").
-                arg(info.firstName).arg(info.lastName).
-                arg(info.id));
-        }
-    }
-}
-
-
-void SyntilistaMainWindow::on_button_AddPerson_clicked()
-{
-    EditPerson *person = new EditPerson(this);
-    person->setPerson(-1);
-}
-
-
-void SyntilistaMainWindow::on_button_EditPerson_clicked()
-{
-    if (currPerson.id >= 0)
-    {
-        EditPerson *person = new EditPerson(this);
-        person->setPerson(currPerson.id);
-    }
-}
-
-
-void SyntilistaMainWindow::on_tableview_People_doubleClicked(const QModelIndex &curr)
-{
-    int row = curr.row();
-    if (row >= 0)
-    {
-        const QAbstractItemModel *model = curr.model();
-        setActivePerson(model->data(model->index(row, 0)).toInt());
-
-        EditPerson *person = new EditPerson(this);
-        person->setPerson(currPerson.id);
-    }
-    else
-        setActivePerson(-1);
-}
-
-
-void SyntilistaMainWindow::on_button_ClearFilter_clicked()
-{
-    ui->edit_PersonFilter->clear();
-    ui->edit_PersonFilter->setFocus(Qt::ShortcutFocusReason);
-}
-
-
-void SyntilistaMainWindow::focusDebtEdit()
-{
-    if (currPerson.id >= 0)
-        ui->edit_Amount->setFocus(Qt::ShortcutFocusReason);
-}
-
-
-void SyntilistaMainWindow::selectRowPrev()
-{
-    QItemSelectionModel *sel = ui->tableview_People->selectionModel();
-    int row = sel->currentIndex().row() - 1;
-    if (row < 0)
-        row = 0;
-
-    sel->setCurrentIndex(model_People->index(row, 0),
-        QItemSelectionModel::ClearAndSelect|QItemSelectionModel::Rows);
-}
-
-
-void SyntilistaMainWindow::selectRowNext()
-{
-    QItemSelectionModel *sel = ui->tableview_People->selectionModel();
-    int row = sel->currentIndex().row() + 1;
-    if (row >= model_People->rowCount())
-        row = model_People->rowCount() - 1;
-    
-    sel->setCurrentIndex(model_People->index(row, 0),
-        QItemSelectionModel::ClearAndSelect|QItemSelectionModel::Rows);
-}
-
-
-//
-// Update visible person list/query based on the current
-// filtering and sorting settings.
-//
-void SyntilistaMainWindow::updatePersonList()
-{
-    static QString queryBase =
-        "SELECT id,last_name,first_name,"
-        "(SELECT SUM(value) FROM transactions WHERE transactions.person=people.id) AS balance,"
-        "updated FROM people";
-
-    QSqlQuery query;
-    QString queryOrderDir, queryOrderBy;
-
-    // Sort order
-    if (peopleSortOrder == Qt::AscendingOrder)
-        queryOrderDir = QStringLiteral("ASC");
-    else
-        queryOrderDir = QStringLiteral("DESC");
-
-    // Sort by which column
-    switch (peopleSortIndex)
-    {
-        case 1:
-        case 2:
-            queryOrderBy = QStringLiteral(" ORDER BY last_name ") + queryOrderDir + QStringLiteral(",first_name ") + queryOrderDir;
-            break;
-
-        case 3:
-            queryOrderBy = QStringLiteral(" ORDER BY balance ") + queryOrderDir;
-            break;
-
-        case 4:
-            queryOrderBy = QStringLiteral(" ORDER BY updated ") + queryOrderDir;
-            break;
-
-        default:
-            queryOrderBy = "";
-    }
-
-    // Are we filtering or not?
-    if (peopleFilter != "")
-    {
-        // Filter by name(s)
-        QString tmp = "%"+ peopleFilter +"%";
-        query.prepare(queryBase +" WHERE first_name LIKE ? OR last_name LIKE ?" + queryOrderBy);
-
-        query.addBindValue(tmp);
-        query.addBindValue(tmp);
-    }
-    else
-    {
-        // No filter
-        query.prepare(queryBase + queryOrderBy);
-    }
-
-    // Execute the query and update model
-    checkAndReportSQLError("updatePersonList() before exec", query.lastError());
-    query.exec();
-    checkAndReportSQLError("updatePersonList() after exec", query.lastError());
-
-    model_People->setQuery(query);
-
-    model_People->setHeaderData(0, Qt::Horizontal, tr("ID"));
-    model_People->setHeaderData(1, Qt::Horizontal, tr("Sukunimi"));
-    model_People->setHeaderData(2, Qt::Horizontal, tr("Etunimi"));
-    model_People->setHeaderData(3, Qt::Horizontal, tr("Tase"));
-    model_People->setHeaderData(4, Qt::Horizontal, tr("Muutettu"));
-}
-
-
-//
-// Update the list of people when filter parameter changes
-//
-void SyntilistaMainWindow::on_edit_PersonFilter_textChanged(const QString &str)
-{
-    peopleFilter = cleanupStr(str);
-    updatePersonList();
-}
-
-
-//
-// Add one transaction to given person id
-//
-int SyntilistaMainWindow::addTransaction(qint64 id, double value, PersonInfo &info)
-{
-    if (!getPersonInfo(id, info))
-        return -1;
-
-    QSqlDatabase::database().transaction();
-
-    QSqlQuery query;
-    query.prepare("INSERT INTO transactions (person,value,added) VALUES (?,?,?)");
-    query.addBindValue(id);
-    query.addBindValue(value);
-    query.addBindValue(QDateTime::currentDateTimeUtc());
-    query.exec();
-    if (!checkAndReportSQLError("addTransaction()", query.lastError()))
-    {
-        QSqlDatabase::database().rollback();
-        return -2;
-    }
-
-    query.prepare("UPDATE people SET updated=? WHERE id=?");
-    query.addBindValue(QDateTime::currentDateTimeUtc());
-    query.addBindValue(id);
-    query.exec();
-    if (!checkAndReportSQLError("addTransaction update timestamp", query.lastError()))
-    {
-        QSqlDatabase::database().rollback();
-        return -3;
-    }
-
-    QSqlDatabase::database().commit();
-
-    return 0;
-}
-
-
-int SyntilistaMainWindow::addTransactionGUI(qint64 id, bool debt, double value)
-{
-    PersonInfo info;
-
-    // Check if person is selected
-    if (id <= 0)
-        return -1;
-
-    // Check value
-    if (value == 0)
-    {
-        QString tmp = (debt ? "lisätty" : "vähennetty");
-        statusMsg("Velkaa ei "+ tmp +" koska summaa ei määritetty.");
-        return 1;
-    }
-
-    // Perform transaction insert
-    int ret = addTransaction(id, debt ? -value : value, info);
-    if (ret == 0)
-    {
-        // All ok, clear amount entry and update person data
-        ui->edit_Amount->clear();
-        if (info.id == currPerson.id)
-            setActivePerson(info.id);
-
-        model_People->updateModel();
-
-        QString str;
-        if (debt)
-        {
-            str = tr("Lisättiin velkaa %1 EUR henkilölle '%2 %3' (#%4).").
-                arg(moneyValueToStr(value)).
-                arg(info.firstName).
-                arg(info.lastName).
-                arg(info.id);
-        }
-        else
-        {
-            str = tr("Vähennettiin velkaa %1 EUR henkilöltä '%2 %3' (#%4).").
-                arg(moneyValueToStr(value)).
-                arg(info.firstName).
-                arg(info.lastName).
-                arg(info.id);
-        }
-        statusMsg(str);
-    }
-    else
-    {
-        errorMsg(
-            tr("SQL-tietokantavirhe"),
-            tr("Tietokantaan tapahtumaa lisättäessa tapahtui virhe #%1.").
-            arg(ret));
-    }
-
-    return ret;
-}
-
-
-void SyntilistaMainWindow::on_button_AddDebt_clicked()
-{
-    addTransactionGUI(currPerson.id, true, moneyStrToValue(ui->edit_Amount->text()));
-}
-
-
-void SyntilistaMainWindow::on_button_PayDebt_clicked()
-{
-    addTransactionGUI(currPerson.id, false, moneyStrToValue(ui->edit_Amount->text()));
-}
-
-
-void SyntilistaMainWindow::on_button_PayFullDebt_clicked()
-{
-    if (currPerson.balance < 0)
-        addTransactionGUI(currPerson.id, false, -currPerson.balance);
-    else
-    {
-        statusMsg(
-            tr("Valitulla henkilöllä '%1, %2' ei ole velkaa.").
-            arg(currPerson.lastName).
-            arg(currPerson.firstName));
-    }
-}
-
-
-//
-// Edit person dialog
-//
-EditPerson::EditPerson(QWidget *parent) :
-    QDialog(parent),
-    ui(new Ui::EditPerson)
-{
-    ui->setupUi(this);
-
-    setCommonStyleSheet(this);
-
-    setModal(true);
-    setAttribute(Qt::WA_DeleteOnClose);
-    show();
-    activateWindow();
-    raise();
-    setFocus();
-
-    model_Transactions = new TransactionSQLModel();
-    ui->tableview_Transactions->setModel(model_Transactions);
-    ui->tableview_Transactions->setItemDelegate(new QSqlRelationalDelegate(ui->tableview_Transactions));
-    ui->tableview_Transactions->verticalHeader()->setVisible(false);
-    ui->tableview_Transactions->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
-
-    validateForm();
-}
-
-
-EditPerson::~EditPerson()
-{
-    delete ui;
-    delete model_Transactions;
-}
-
-
-void EditPerson::statusMsg(const QString &msg)
-{
-    dynamic_cast<SyntilistaMainWindow *>(parent())->statusMsg(msg);
-}
-
-
-bool EditPerson::validateForm()
-{
-    selPerson.firstName = cleanupStr(ui->edit_FirstName->text());
-    selPerson.lastName = cleanupStr(ui->edit_LastName->text());
-    selPerson.extraInfo = ui->textedit_ExtraInfo->document()->toPlainText();
-
-    ui->edit_FirstName->setStyleSheet(selPerson.firstName == "" ? "background-color: red;" : NULL);
-    ui->edit_LastName->setStyleSheet(selPerson.lastName == "" ? "background-color: red;" : NULL);
-
-    return selPerson.firstName != "" && selPerson.lastName != "";
-}
-
-
-void EditPerson::on_button_Cancel_clicked()
-{
-    close();
-}
-
-
-void EditPerson::on_button_OK_clicked()
-{
-    if (!validateForm())
-    {
-        errorMsg(
-            tr("Virhe!"),
-            tr("Vaaditut kentät (etunimi, sukunimi) eivät ole täytetty."));
-
-        return;
-    }
-
-    if (selPerson.id >= 0)
-    {
-        QSqlQuery person;
-        person.prepare("SELECT * FROM people WHERE id <> ? AND first_name=? AND last_name=?");
-        person.addBindValue(selPerson.id);
-        person.addBindValue(selPerson.firstName);
-        person.addBindValue(selPerson.lastName);
-        person.exec();
-
-        checkAndReportSQLError("SELECT check for existing person by same name (UPDATE)", person.lastError());
-
-        if (person.next())
-        {
-            errorMsg(
-                tr("Virhe!"),
-                tr("Ei pysty! Samalla nimellä '%1 %2' on olemassa jo henkilö!").
-                arg(selPerson.firstName).arg(selPerson.lastName));
-            return;
-        }
-
-        dynamic_cast<SyntilistaMainWindow *>(parent())->model_People->updatePerson(selPerson);
-        dynamic_cast<SyntilistaMainWindow *>(parent())->setActivePerson(selPerson.id);
-
-        statusMsg(tr("Päivitettiin henkilö '%1 %2' (#%3).").
-            arg(selPerson.firstName).arg(selPerson.lastName).arg(selPerson.id));
-    }
-    else
-    {
-        QSqlQuery person;
-        person.prepare("SELECT * FROM people WHERE first_name=? AND last_name=?");
-        person.addBindValue(selPerson.firstName);
-        person.addBindValue(selPerson.lastName);
-        person.exec();
-
-        checkAndReportSQLError("SELECT check for existing person by same name (ADD)", person.lastError());
-
-        if (person.next())
-        {
-            errorMsg(
-                tr("Virhe!"),
-                tr("Ei pysty! Samalla nimellä '%1 %2' on olemassa jo henkilö!").
-                arg(selPerson.firstName).arg(selPerson.lastName));
-
-            return;
-        }
-
-        dynamic_cast<SyntilistaMainWindow *>(parent())->model_People->addPerson(selPerson);
-        dynamic_cast<SyntilistaMainWindow *>(parent())->updatePersonList();
-
-        statusMsg(tr("Lisättiin uusi henkilö '%1 %2'.").
-            arg(selPerson.firstName).arg(selPerson.lastName));
-    }
-
-    close();
-}
-
-
-void EditPerson::on_edit_FirstName_textChanged(const QString &arg1)
-{
-    (void) arg1;
-    validateForm();
-}
-
-
-void EditPerson::on_edit_LastName_textChanged(const QString &arg1)
-{
-    (void) arg1;
-    validateForm();
-}
-
-
-void EditPerson::clearForm()
-{
-    ui->edit_FirstName->clear();
-    ui->edit_LastName->clear();
-    ui->textedit_ExtraInfo->document()->clear();
-    ui->edit_FirstName->setFocus();
-}
-
-
-void EditPerson::setPerson(qint64 id)
-{
-    selPerson.id = id;
-
-    if (id >= 0)
-    {
-        PersonInfo pinfo;
-        if (!getPersonInfo(id, pinfo))
-        {
-            statusMsg(tr("Virhe! Ei henkilöä ID:llä #%1").arg(id));
-        }
-        else
-        {
-            ui->edit_FirstName->setText(pinfo.firstName);
-            ui->edit_LastName->setText(pinfo.lastName);
-            ui->textedit_ExtraInfo->document()->setPlainText(pinfo.extraInfo);
-
-            QSqlQuery query;
-            query.prepare("SELECT id,value,added FROM transactions WHERE person=? ORDER BY added DESC");
-            query.addBindValue(pinfo.id);
-            query.exec();
-            checkAndReportSQLError("SELECT transactions for tableview_Transactions", query.lastError());
-
-            model_Transactions->setQuery(query);
-
-            model_Transactions->setHeaderData(0, Qt::Horizontal, tr("ID"));
-            model_Transactions->setHeaderData(1, Qt::Horizontal, tr("Summa"));
-            model_Transactions->setHeaderData(2, Qt::Horizontal, tr("Aika"));
-
-            ui->tableview_Transactions->setModel(model_Transactions);
-            ui->tableview_Transactions->setColumnHidden(0, true);
-
-            return; // Ugly
-        }
-    }
-
-    // In case of id < 0 or errors ..
-    clearForm();
-    ui->tableview_Transactions->setModel(NULL);
-}
-
-
-//
-// Custom SQL models
-//
-PersonSQLModel::PersonSQLModel(QObject *parent) : QSqlQueryModel(parent)
-{
-}
-
-
-QVariant PersonSQLModel::data(const QModelIndex &index, int role) const
-{
-    QVariant value = QSqlQueryModel::data(index, role);
-
-    if (value.isValid() && role == Qt::DisplayRole)
-    {
-        switch (index.column())
-        {
-            case 3:
-                return moneyValueToStr(value.toDouble());
-
-            case 4:
-                return dateTimeToStr(value.toDateTime());
-        }
-    }
-
-    if (index.column() == 3 && role == Qt::ForegroundRole)
-    {
-        double val = QSqlQueryModel::data(index, Qt::DisplayRole).toDouble();
-        if (val < 0)
-            return QVariant::fromValue(QColor(Qt::red));
-        else
-            return QVariant::fromValue(QColor(Qt::green));
-    }
-
-    return value;
-}
-
-
-int PersonSQLModel::updatePerson(const PersonInfo &info)
-{
-    QSqlQuery np;
-
-    np.prepare("UPDATE people SET first_name=?,last_name=?,extra_info=?,updated=? WHERE id=?");
-    np.addBindValue(info.firstName);
-    np.addBindValue(info.lastName);
-    np.addBindValue(info.extraInfo);
-    np.addBindValue(QDateTime::currentDateTimeUtc());
-    np.addBindValue(info.id);
-    np.exec();
-
-    if (!checkAndReportSQLError("PersonSQLModel::updatePerson()", np.lastError()))
-        return -1;
-
-    QSqlDatabase::database().commit();
-
-    updateModel();
-    return 0;
-}
-
-
-int PersonSQLModel::addPerson(const PersonInfo &info)
-{
-//    beginInsertRows(QModelIndex(), rowCount(), rowCount());
-
-    QSqlQuery np;
-    np.prepare("INSERT INTO people (first_name,last_name,extra_info,added,updated) VALUES (?,?,?,?,?)");
-    np.addBindValue(info.firstName);
-    np.addBindValue(info.lastName);
-    np.addBindValue(info.extraInfo);
-    np.addBindValue(QDateTime::currentDateTimeUtc());
-    np.addBindValue(QDateTime::currentDateTimeUtc());
-    np.exec();
-
-    if (!checkAndReportSQLError("PersonSQLModel::addPerson()", np.lastError()))
-        return -1;
-
-    QSqlDatabase::database().commit();
-
-//    endInsertRows();
-    updateModel();
-    return 0;
-}
-
-
-int PersonSQLModel::deletePerson(qint64 id)
-{
-    QSqlDatabase::database().transaction();
-    QSqlQuery del;
-
-    del.prepare("DELETE FROM people WHERE id=?");
-    del.addBindValue(id);
-    del.exec();
-
-    if (!checkAndReportSQLError("delete user", del.lastError()))
-    {
-        QSqlDatabase::database().rollback();
-        return -1;
-    }
-
-    del.prepare("DELETE FROM transactions WHERE person=?");
-    del.addBindValue(id);
-    del.exec();
-
-    if (!checkAndReportSQLError("delete user transactions", del.lastError()))
-    {
-        QSqlDatabase::database().rollback();
-        return -2;
-    }
-
-    QSqlDatabase::database().commit();
-    updateModel();
-    return 0;
-}
-
-
-void PersonSQLModel::updateModel()
-{
-    query().exec();
-    emit dataChanged(index(0, 0), index(rowCount(), columnCount()));
-}
-
-
-TransactionSQLModel::TransactionSQLModel(QObject *parent) : QSqlQueryModel(parent)
-{
-}
-
-
-QVariant TransactionSQLModel::data(const QModelIndex &index, int role) const
-{
-    QVariant value = QSqlQueryModel::data(index, role);
-
-    if (value.isValid() && role == Qt::DisplayRole)
-    {
-        switch (index.column())
-        {
-            case 1:
-                return moneyValueToStr(value.toDouble());
-
-            case 2:
-                return dateTimeToStr(value.toDateTime());
-        }
-    }
-
-    if (index.column() == 1 && role == Qt::ForegroundRole)
-    {
-        double val = QSqlQueryModel::data(index, Qt::DisplayRole).toDouble();
-        if (val < 0)
-            return QVariant::fromValue(QColor(Qt::red));
-        else
-            return QVariant::fromValue(QColor(Qt::green));
-    }
-
-    return value;
-}
-
-
-void TransactionSQLModel::updateModel()
-{
-    query().exec();
-    emit dataChanged(QModelIndex(), QModelIndex());
-}
--- a/main.h	Wed Apr 12 12:16:00 2017 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,197 +0,0 @@
-//
-// Syntilista - velkalistasovellus Kampus-kahvilaan
-// Programmed and designed by Matti Hämäläinen <ccr@tnsp.org>
-// (C) Copyright 2017 Tecnic Software productions (TNSP)
-//
-// Distributed under 3-clause BSD style license, refer to
-// included file "COPYING" for exact terms.
-//
-#ifndef SYNTILISTA_H
-#define SYNTILISTA_H
-
-#include <QMainWindow>
-#include <QShortcut>
-#include <QDialog>
-#include <QtSql>
-#include <QSqlQueryModel>
-
-
-//
-// Global application defines
-//
-#define APP_VENDOR        "TNSP"                    // Vendor ID (for settings, etc.)
-#define APP_ID            "Kampus Syntilista"       // Application ID (for settings)
-#define APP_NAME          "Café Kampus Syntilista"  // Application title/name
-#define APP_SQLITE_FILE   "syntilista.sqlite3"      // SQLite3 database file name (without path)
-
-
-//
-// Custom SQL models
-//
-class PersonInfo : public QObject
-{
-    Q_OBJECT
-    
-public:
-    explicit PersonInfo()
-    {
-        id = -1;
-        firstName = "";
-        lastName = "";
-        extraInfo = "";
-        balance = 0;
-    }
-
-    ~PersonInfo()
-    {
-    }
-
-    void dump();
-
-    qint64 id;
-    QString firstName, lastName, extraInfo;
-    double balance;
-    QDateTime added, updated;
-};
-
-
-
-class PersonSQLModel : public QSqlQueryModel
-{
-    Q_OBJECT
-
-private:
-
-public:
-    PersonSQLModel(QObject *parent = 0);
-
-    QVariant data(const QModelIndex &item, int role) const Q_DECL_OVERRIDE;
-
-    int  updatePerson(const PersonInfo &person);
-    int  addPerson(const PersonInfo &person);
-    int  deletePerson(qint64 id);
-    void updateModel();
-};
-
-
-
-class TransactionSQLModel : public QSqlQueryModel
-{
-    Q_OBJECT
-
-private:
-
-public:
-    TransactionSQLModel(QObject *parent = 0);
-
-    QVariant data(const QModelIndex &item, int role) const Q_DECL_OVERRIDE;
-
-    void updateModel();
-};
-
-
-
-//
-// Main window
-//
-namespace Ui {
-class SyntilistaMainWindow;
-class EditPerson;
-}
-
-class SyntilistaMainWindow : public QMainWindow
-{
-    Q_OBJECT
-
-public:
-    explicit SyntilistaMainWindow(QWidget *parent = 0);
-    ~SyntilistaMainWindow();
-
-    void statusMsg(const QString &msg);
-
-    void readSettings();
-    void saveSettings();
-    void setActivePerson(qint64 id);
-    int  addTransaction(qint64 id, double value, PersonInfo &info);
-    int  addTransactionGUI(qint64 id, bool debt, double value);
-    void updatePersonList();
-
-    PersonSQLModel *model_People;
-
-private slots:
-    void on_button_AddPerson_clicked();
-    void on_button_EditPerson_clicked();
-    void on_button_DeletePerson_clicked();
-
-    void on_edit_PersonFilter_textChanged(const QString &arg1);
-    void on_button_ClearFilter_clicked();
-
-    void on_button_Quit_clicked();
-    void on_button_About_clicked();
-    void on_button_Help_clicked();
-
-    void on_button_AddDebt_clicked();
-    void on_button_PayDebt_clicked();
-    void on_button_PayFullDebt_clicked();
-
-    void on_tableview_People_doubleClicked(const QModelIndex &index);
-
-    void selectedPersonChanged(const QModelIndex &, const QModelIndex &);
-
-    void focusDebtEdit();
-    void selectRowPrev();
-    void selectRowNext();
-
-    void changeUIZoomIn();
-    void changeUIZoomOut();
-    void changeUIZoomReset();
-    
-    void updateSortOrder(int index, Qt::SortOrder order);
-
-
-private:
-    Ui::SyntilistaMainWindow *ui;
-
-    TransactionSQLModel *model_Latest;
-    PersonInfo currPerson;
-
-    int peopleSortIndex;
-    Qt::SortOrder peopleSortOrder;
-    QString peopleFilter;
-};
-
-
-//
-// Person edit / new person dialog
-//
-class EditPerson : public QDialog
-{
-    Q_OBJECT
-
-public:
-    explicit EditPerson(QWidget *parent = 0);
-    ~EditPerson();
-
-    void statusMsg(const QString &msg);
-
-    void clearForm();
-    bool validateForm();
-    void setPerson(qint64 id);
-
-private slots:
-    void on_button_OK_clicked();
-
-    void on_button_Cancel_clicked();
-
-    void on_edit_FirstName_textChanged(const QString &arg1);
-
-    void on_edit_LastName_textChanged(const QString &arg1);
-
-private:
-    Ui::EditPerson *ui;
-
-    PersonInfo selPerson;
-    TransactionSQLModel *model_Transactions;
-};
-
-#endif // SYNTILISTA_H
--- a/mainwindow.ui	Wed Apr 12 12:16:00 2017 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,309 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>SyntilistaMainWindow</class>
- <widget class="QMainWindow" name="SyntilistaMainWindow">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>835</width>
-    <height>646</height>
-   </rect>
-  </property>
-  <widget class="QWidget" name="centralwidget">
-   <layout class="QHBoxLayout" name="horizontalLayout_2">
-    <item>
-     <widget class="QGroupBox" name="henkilotGB">
-      <property name="title">
-       <string>Henkilöt</string>
-      </property>
-      <layout class="QVBoxLayout" name="verticalLayout_2">
-       <item>
-        <layout class="QHBoxLayout" name="horizontalLayout_3">
-         <item>
-          <widget class="QLabel" name="label">
-           <property name="text">
-            <string>Etsi / suodata</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QLineEdit" name="edit_PersonFilter"/>
-         </item>
-         <item>
-          <widget class="QPushButton" name="button_ClearFilter">
-           <property name="text">
-            <string>Tyhjennä suodatin</string>
-           </property>
-          </widget>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <widget class="QTableView" name="tableview_People">
-         <property name="selectionMode">
-          <enum>QAbstractItemView::SingleSelection</enum>
-         </property>
-         <property name="selectionBehavior">
-          <enum>QAbstractItemView::SelectRows</enum>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <layout class="QHBoxLayout" name="horizontalLayout">
-         <item>
-          <widget class="QPushButton" name="button_DeletePerson">
-           <property name="text">
-            <string>Poista henkilö</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <spacer name="horizontalSpacer">
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>40</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-         <item>
-          <widget class="QPushButton" name="button_AddPerson">
-           <property name="text">
-            <string>Lisää uusi henkilö</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QPushButton" name="button_EditPerson">
-           <property name="text">
-            <string>Muokkaa henkilöä</string>
-           </property>
-          </widget>
-         </item>
-        </layout>
-       </item>
-      </layout>
-     </widget>
-    </item>
-    <item>
-     <layout class="QVBoxLayout" name="verticalLayout">
-      <property name="sizeConstraint">
-       <enum>QLayout::SetMinimumSize</enum>
-      </property>
-      <item>
-       <widget class="QGroupBox" name="personGB">
-        <property name="enabled">
-         <bool>true</bool>
-        </property>
-        <property name="title">
-         <string>Henkilön syntilista</string>
-        </property>
-        <property name="alignment">
-         <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
-        </property>
-        <property name="flat">
-         <bool>false</bool>
-        </property>
-        <layout class="QVBoxLayout" name="verticalLayout_3">
-         <property name="sizeConstraint">
-          <enum>QLayout::SetMinimumSize</enum>
-         </property>
-         <item>
-          <widget class="QLabel" name="label_PersonName">
-           <property name="text">
-            <string>Henkilön nimi</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="Line" name="line">
-           <property name="lineWidth">
-            <number>4</number>
-           </property>
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <layout class="QHBoxLayout" name="horizontalLayout_6">
-           <item>
-            <widget class="QLabel" name="label_CurrentBalance">
-             <property name="text">
-              <string>Nykyinen tase:</string>
-             </property>
-            </widget>
-           </item>
-           <item>
-            <widget class="QLabel" name="label_BalanceValue">
-             <property name="text">
-              <string>12345</string>
-             </property>
-             <property name="alignment">
-              <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-             </property>
-            </widget>
-           </item>
-           <item>
-            <widget class="QLabel" name="label_EUR">
-             <property name="text">
-              <string>EUR</string>
-             </property>
-             <property name="alignment">
-              <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-             </property>
-            </widget>
-           </item>
-          </layout>
-         </item>
-         <item>
-          <widget class="Line" name="line_2">
-           <property name="lineWidth">
-            <number>4</number>
-           </property>
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QLineEdit" name="edit_Amount">
-           <property name="text">
-            <string/>
-           </property>
-           <property name="alignment">
-            <set>Qt::AlignCenter</set>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <layout class="QHBoxLayout" name="horizontalLayout_5">
-           <item>
-            <widget class="QPushButton" name="button_AddDebt">
-             <property name="text">
-              <string>Lisää velkaa</string>
-             </property>
-            </widget>
-           </item>
-           <item>
-            <widget class="QPushButton" name="button_PayDebt">
-             <property name="text">
-              <string>Maksa velkaa</string>
-             </property>
-            </widget>
-           </item>
-          </layout>
-         </item>
-         <item>
-          <widget class="QPushButton" name="button_PayFullDebt">
-           <property name="text">
-            <string>Maksa koko velka</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QLabel" name="label_2">
-           <property name="text">
-            <string>Viimeisimmät tapahtumat:</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QTableView" name="tableview_Latest">
-           <property name="selectionMode">
-            <enum>QAbstractItemView::SingleSelection</enum>
-           </property>
-           <property name="selectionBehavior">
-            <enum>QAbstractItemView::SelectRows</enum>
-           </property>
-          </widget>
-         </item>
-        </layout>
-       </widget>
-      </item>
-      <item>
-       <widget class="QLabel" name="button_LogoImage">
-        <property name="sizePolicy">
-         <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
-          <horstretch>0</horstretch>
-          <verstretch>0</verstretch>
-         </sizepolicy>
-        </property>
-        <property name="text">
-         <string/>
-        </property>
-       </widget>
-      </item>
-      <item>
-       <layout class="QHBoxLayout" name="horizontalLayout_4">
-        <property name="sizeConstraint">
-         <enum>QLayout::SetMinimumSize</enum>
-        </property>
-        <item>
-         <widget class="QPushButton" name="button_About">
-          <property name="text">
-           <string/>
-          </property>
-          <property name="icon">
-           <iconset resource="resources.qrc">
-            <normaloff>:/img/icon-64.png</normaloff>:/img/icon-64.png</iconset>
-          </property>
-          <property name="iconSize">
-           <size>
-            <width>32</width>
-            <height>32</height>
-           </size>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QPushButton" name="button_Help">
-          <property name="text">
-           <string>?</string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <spacer name="horizontalSpacer_2">
-          <property name="orientation">
-           <enum>Qt::Horizontal</enum>
-          </property>
-          <property name="sizeHint" stdset="0">
-           <size>
-            <width>40</width>
-            <height>20</height>
-           </size>
-          </property>
-         </spacer>
-        </item>
-        <item>
-         <widget class="QPushButton" name="button_Quit">
-          <property name="text">
-           <string>Poistu ohjelmasta</string>
-          </property>
-         </widget>
-        </item>
-       </layout>
-      </item>
-     </layout>
-    </item>
-   </layout>
-  </widget>
-  <widget class="QStatusBar" name="statusbar"/>
- </widget>
- <tabstops>
-  <tabstop>edit_PersonFilter</tabstop>
-  <tabstop>button_ClearFilter</tabstop>
-  <tabstop>button_AddPerson</tabstop>
-  <tabstop>button_Quit</tabstop>
- </tabstops>
- <resources>
-  <include location="resources.qrc"/>
- </resources>
- <connections/>
-</ui>
--- a/resources.qrc	Wed Apr 12 12:16:00 2017 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-<RCC>
-  <qresource prefix="img">
-    <file>logo.png</file>
-    <file>icon-64.png</file>
-  </qresource>
-</RCC>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/editperson.ui	Mon Apr 24 12:12:39 2017 +0300
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>EditPerson</class>
+ <widget class="QDialog" name="EditPerson">
+  <property name="windowModality">
+   <enum>Qt::NonModal</enum>
+  </property>
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>564</width>
+    <height>500</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Muokkaa henkilöä</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QGroupBox" name="groupBox_2">
+     <property name="title">
+      <string>Henkilön perustiedot</string>
+     </property>
+     <layout class="QFormLayout" name="formLayout">
+      <item row="0" column="0">
+       <widget class="QLabel" name="label_FirstName">
+        <property name="text">
+         <string>Etunimi</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="1">
+       <widget class="QLabel" name="label_LastName">
+        <property name="text">
+         <string>Sukunimi</string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="1">
+       <widget class="QLineEdit" name="edit_LastName"/>
+      </item>
+      <item row="1" column="0">
+       <widget class="QLineEdit" name="edit_FirstName"/>
+      </item>
+      <item row="2" column="0">
+       <widget class="QLabel" name="label_ExtraInfo">
+        <property name="text">
+         <string>Lisätietoja:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="0" colspan="2">
+       <widget class="QPlainTextEdit" name="textedit_ExtraInfo"/>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QGroupBox" name="groupBox">
+     <property name="title">
+      <string>Tapahtumat:</string>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_2">
+      <item>
+       <widget class="QTableView" name="tableview_Transactions">
+        <property name="contextMenuPolicy">
+         <enum>Qt::DefaultContextMenu</enum>
+        </property>
+        <property name="selectionBehavior">
+         <enum>QAbstractItemView::SelectRows</enum>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QPushButton" name="button_Cancel">
+       <property name="text">
+        <string>Peruuta</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="button_OK">
+       <property name="text">
+        <string>Talleta / OK</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <tabstops>
+  <tabstop>edit_FirstName</tabstop>
+  <tabstop>edit_LastName</tabstop>
+  <tabstop>textedit_ExtraInfo</tabstop>
+  <tabstop>button_OK</tabstop>
+  <tabstop>button_Cancel</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main.cpp	Mon Apr 24 12:12:39 2017 +0300
@@ -0,0 +1,1189 @@
+//
+// Syntilista - velkalistasovellus Kampus-kahvilaan
+// Programmed and designed by Matti Hämäläinen <ccr@tnsp.org>
+// (C) Copyright 2017 Tecnic Software productions (TNSP)
+//
+// Distributed under 3-clause BSD style license, refer to
+// included file "COPYING" for exact terms.
+//
+#include <QApplication>
+#include <QMessageBox>
+#include <QSettings>
+#include "main.h"
+#include "ui_mainwindow.h"
+#include "ui_editperson.h"
+
+double setScale;
+
+
+int errorMsg(QString title, QString msg)
+{
+    QMessageBox dlg;
+
+    dlg.setText(title);
+    dlg.setInformativeText(msg);
+    dlg.setTextFormat(Qt::RichText);
+    dlg.setIcon(QMessageBox::Critical);
+    dlg.setStandardButtons(QMessageBox::Ok);
+    dlg.setDefaultButton(QMessageBox::Ok);
+
+    return dlg.exec();
+}
+
+
+double moneyStrToValue(const QString &str)
+{
+    QString str2 = str;
+    return str2.replace(",", ".").toDouble();
+}
+
+
+QString moneyValueToStr(double val)
+{
+    return QStringLiteral("%1").arg(val, 1, 'f', 2);
+}
+
+
+QString cleanupStr(const QString &str)
+{
+    return str.simplified().trimmed();
+}
+
+
+const QString dateTimeToStr(const QDateTime &val)
+{
+    QDateTime tmp = val;
+    tmp.setOffsetFromUtc(0);
+    return tmp.toLocalTime().toString(QStringLiteral("yyyy-MM-dd hh:mm"));
+}
+
+
+bool checkAndReportSQLError(const QString where, const QSqlError &err)
+{
+    if (err.isValid())
+    {
+        printf("SQL Error in %s: %s\n",
+            where.toUtf8().constData(),
+            err.text().toUtf8().constData());
+        return false;
+    }
+    else
+        return true;
+}
+
+
+void PersonInfo::dump()
+{
+    printf("PersonInfo() #%lld '%s %s' (added=%s, updated=%s, balance %1.2f)\n#%s#\n",
+        id,
+        firstName.toUtf8().constData(),
+        lastName.toUtf8().constData(),
+        dateTimeToStr(added).toUtf8().constData(),
+        dateTimeToStr(updated).toUtf8().constData(),
+        balance,
+        extraInfo.toUtf8().constData());
+}
+
+
+//
+// Get PersonInfo record from SQL database for specified persn ID #
+//
+bool getPersonInfo(qint64 id, PersonInfo &info)
+{
+    QSqlQuery person;
+    person.prepare(
+        "SELECT id,first_name,last_name,extra_info,added,updated, "
+        "(SELECT SUM(value) FROM transactions WHERE transactions.person=people.id) AS balance "
+        "FROM people WHERE id=?");
+
+    person.addBindValue(id);
+    person.exec();
+    if (!person.next())
+        return false;
+
+    info.id         = person.value(0).toInt();
+    info.firstName  = person.value(1).toString();
+    info.lastName   = person.value(2).toString();
+    info.extraInfo  = person.value(3).toString();
+    info.added      = person.value(4).toDateTime();
+    info.updated    = person.value(5).toDateTime();
+    info.balance    = person.value(6).toDouble();
+
+    person.finish();
+
+    return true;
+}
+
+
+void setCommonStyleSheet(QWidget *widget)
+{
+    // Clamp scale value
+    if (setScale < 0.5f)
+        setScale = 0.5f;
+    if (setScale > 3.0f)
+        setScale = 3.0f;
+
+    // Set the stylesheet
+    widget->setStyleSheet(
+        QStringLiteral(
+        "* { font-size: %1pt; }"
+        "QPushButton { font-size: %2pt; padding: 0.25em; }"
+        "#button_AddDebt[enabled='true'] { font-size: %3pt; background-color: #900; color: white; }"
+        "#button_PayDebt[enabled='true'] { font-size: %3pt; background-color: #090; color: white; }"
+        "#button_PayFullDebt[enabled='true'] { background-color: #060; color: white; }"
+
+        "#button_AddDebt[enabled='false'] { font-size: %3pt; background-color: #622; color: black; }"
+        "#button_PayDebt[enabled='false'] { font-size: %3pt; background-color: #262; color: black; }"
+        "#button_PayFullDebt[enabled='false'] { background-color: #131; color: black; }"
+
+        "#label_PersonName { font-size: %5pt; font-weight: bold;  }"
+        "#label_BalanceValue { font-size: %4pt; font-weight: bold; }"
+        "#label_EUR { font-size: %4pt; font-weight: bold; }"
+        "#edit_Amount { font-size: %4pt; margin: 0.5em; padding: 0.5em; }"
+        ).
+        arg(12 * setScale).
+        arg(14 * setScale).
+        arg(16 * setScale).
+        arg(18 * setScale).
+        arg(20 * setScale)
+        );
+}
+
+
+int main(int argc, char *argv[])
+{
+    QApplication sapp(argc, argv);
+
+    //
+    // Initialize / open SQL database connection
+    //
+    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
+    db.setDatabaseName(qApp->applicationDirPath() +
+        QDir::separator() + APP_SQLITE_FILE);
+
+    if (!db.open())
+    {
+        errorMsg(
+            QObject::tr("Tietokantaa ei voitu avata"),
+            QObject::tr("Yhteyttä SQL-tietokantaan ei saatu.<br><br>Virhe: %1<br><br>").
+            arg(db.lastError().text())
+            );
+        return 1;
+    }
+
+    QSqlQuery query;
+    if (!db.tables().contains("people"))
+    {
+        query.exec(QStringLiteral(
+            "CREATE TABLE people (id INTEGER PRIMARY KEY, "
+            "first_name VARCHAR(128) NOT NULL, "
+            "last_name VARCHAR(128) NOT NULL, "
+            "extra_info VARCHAR(2048), "
+            "added DATETIME NOT NULL, "
+            "updated DATETIME NOT NULL)"));
+
+        checkAndReportSQLError("CREATE TABLE people", query.lastError());
+    }
+
+    if (!db.tables().contains("transactions"))
+    {
+        query.exec(QStringLiteral(
+            "CREATE TABLE transactions ("
+            "id INTEGER PRIMARY KEY, "
+            "person INT NOT NULL, "
+            "value REAL, "
+            "added DATETIME NOT NULL)"));
+
+        checkAndReportSQLError("CREATE TABLE transactions", query.lastError());
+    }
+
+    SyntilistaMainWindow swin;
+    swin.show();
+    return sapp.exec();
+}
+
+
+//
+// Main application window code
+//
+SyntilistaMainWindow::SyntilistaMainWindow(QWidget *parent) :
+    QMainWindow(parent),
+    ui(new Ui::SyntilistaMainWindow)
+{
+    // Setup UI
+    ui->setupUi(this);
+
+    // Read config
+    readSettings();
+
+    // Setup other UI things
+    setWindowIcon(QIcon(QPixmap(":/img/icon-64.png")));
+    setWindowTitle(tr("%1 versio %3").
+        arg(tr(APP_NAME)).
+        arg(tr(APP_VERSION)));
+
+    QPixmap logoImage(":/img/logo.png");
+    ui->button_LogoImage->setPixmap(logoImage);
+    ui->button_LogoImage->setAlignment(Qt::AlignCenter);
+
+    setCommonStyleSheet(this);
+
+    // Validator for amount input
+    //ui->edit_Amount->setValidator(new QDoubleValidator(0, 1000, 2, this));
+    QRegExp vregex("\\d{0,4}[,.]\\d{0,2}|\\d{0,4}");
+    ui->edit_Amount->setValidator(new QRegExpValidator(vregex, this));
+
+    // Setup person list filtering and sorting
+    peopleSortIndex = 1;
+    peopleSortOrder = Qt::AscendingOrder;
+    peopleFilter = "";
+
+    model_People = new PersonSQLModel();
+    updatePersonList();
+
+    ui->tableview_People->setModel(model_People);
+    ui->tableview_People->setColumnHidden(0, true);
+    ui->tableview_People->setItemDelegate(new QSqlRelationalDelegate(ui->tableview_People));
+    ui->tableview_People->verticalHeader()->setVisible(false);
+    ui->tableview_People->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
+    ui->tableview_People->setSortingEnabled(true);
+    ui->tableview_People->sortByColumn(peopleSortIndex, peopleSortOrder);
+
+    connect(
+        ui->tableview_People->selectionModel(),
+        SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)),
+        this,
+        SLOT(selectedPersonChanged(const QModelIndex &, const QModelIndex &)));
+
+    connect(
+        ui->tableview_People->horizontalHeader(),
+        SIGNAL(sortIndicatorChanged(int, Qt::SortOrder)),
+        this,
+        SLOT(updateSortOrder(int, Qt::SortOrder)));
+
+    ui->tableview_People->horizontalHeader()->setSortIndicator(1, Qt::AscendingOrder);
+
+    model_Latest = new TransactionSQLModel();
+    ui->tableview_Latest->setModel(model_Latest);
+    ui->tableview_Latest->setItemDelegate(new QSqlRelationalDelegate(ui->tableview_Latest));
+    ui->tableview_Latest->verticalHeader()->setVisible(false);
+    ui->tableview_Latest->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
+
+    setActivePerson(-1);
+
+    // Keyboard shortcuts
+    ui->button_Quit->setShortcut(QKeySequence(Qt::Key_F10));
+    new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q), this, SLOT(on_button_Quit_clicked()));
+
+    ui->button_AddPerson->setShortcut(QKeySequence(Qt::Key_F5));
+    ui->button_DeletePerson->setShortcut(QKeySequence(Qt::Key_F8));
+    ui->button_EditPerson->setShortcut(QKeySequence(Qt::Key_F6));
+    ui->button_ClearFilter->setShortcut(QKeySequence(Qt::Key_Escape));
+    ui->button_Help->setShortcut(QKeySequence(Qt::Key_F1));
+    ui->button_About->setShortcut(QKeySequence(Qt::Key_F2));
+
+    new QShortcut(QKeySequence(QKeySequence::ZoomIn), this, SLOT(changeUIZoomIn()));
+    new QShortcut(QKeySequence(QKeySequence::ZoomOut), this, SLOT(changeUIZoomOut()));
+    new QShortcut(QKeySequence(Qt::CTRL + Qt::KeypadModifier + Qt::Key_Plus), this, SLOT(changeUIZoomIn()));
+    new QShortcut(QKeySequence(Qt::CTRL + Qt::KeypadModifier + Qt::Key_Minus), this, SLOT(changeUIZoomOut()));
+    new QShortcut(QKeySequence(Qt::CTRL + Qt::KeypadModifier + Qt::Key_0), this, SLOT(changeUIZoomReset()));
+    new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_0), this, SLOT(changeUIZoomReset()));
+
+    new QShortcut(QKeySequence(Qt::Key_PageUp), this, SLOT(selectRowPrev()));
+    new QShortcut(QKeySequence(Qt::Key_PageDown), this, SLOT(selectRowNext()));
+
+    new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Return), this, SLOT(focusDebtEdit()));
+}
+
+
+SyntilistaMainWindow::~SyntilistaMainWindow()
+{
+    saveSettings();
+
+    delete ui;
+    delete model_People;
+    delete model_Latest;
+}
+
+
+void SyntilistaMainWindow::statusMsg(const QString &msg)
+{
+    ui->statusbar->showMessage(msg);
+}
+
+
+void SyntilistaMainWindow::readSettings()
+{
+    QSettings settings(APP_VENDOR, APP_ID);
+    move(settings.value("pos", QPoint(100, 100)).toPoint());
+    resize(settings.value("size", QSize(1000, 600)).toSize());
+    setScale = settings.value("scale", 1.0f).toDouble();
+}
+
+
+void SyntilistaMainWindow::saveSettings()
+{
+    QSettings settings(APP_VENDOR, APP_ID);
+    settings.setValue("pos", pos());
+    settings.setValue("size", size());
+    settings.setValue("scale", setScale);
+}
+
+
+void SyntilistaMainWindow::changeUIZoomIn()
+{
+    setScale += 0.1f;
+    setCommonStyleSheet(this);
+}
+
+
+void SyntilistaMainWindow::changeUIZoomOut()
+{
+    setScale -= 0.1f;
+    setCommonStyleSheet(this);
+}
+
+
+void SyntilistaMainWindow::changeUIZoomReset()
+{
+    setScale = 1.0f;
+    setCommonStyleSheet(this);
+}
+
+
+void SyntilistaMainWindow::selectedPersonChanged(const QModelIndex &curr, const QModelIndex &prev)
+{
+    (void) prev;
+    int row = curr.row();
+    if (row >= 0)
+    {
+        const QAbstractItemModel *model = curr.model();
+        setActivePerson(model->data(model->index(row, 0)).toInt());
+    }
+    else
+        setActivePerson(-1);
+}
+
+
+void SyntilistaMainWindow::updateSortOrder(int index, Qt::SortOrder order)
+{
+    peopleSortIndex = index;
+    peopleSortOrder = order;
+    updatePersonList();
+}
+
+
+void SyntilistaMainWindow::setActivePerson(qint64 id)
+{
+    currPerson.id = id;
+
+    ui->button_EditPerson->setEnabled(id >= 0);
+
+    if (id >= 0)
+    {
+        if (!getPersonInfo(id, currPerson))
+        {
+            statusMsg(tr("Virhe! Ei henkilöä ID:llä #%1").arg(id));
+        }
+        else
+        {
+            ui->personGB->setEnabled(true);
+            ui->label_PersonName->setText(currPerson.lastName +", "+ currPerson.firstName);
+
+            ui->label_BalanceValue->setText(moneyValueToStr(currPerson.balance));
+            ui->label_BalanceValue->setStyleSheet(currPerson.balance < 0 ? "color: red;" : "color: green;");
+            ui->button_PayFullDebt->setEnabled(currPerson.balance < 0);
+
+            QSqlQuery query;
+            query.prepare("SELECT id,value,added FROM transactions WHERE person=? ORDER BY added DESC LIMIT 5");
+            query.addBindValue(id);
+            query.exec();
+            checkAndReportSQLError("SELECT transactions for tableview_Latest", query.lastError());
+
+            model_Latest->setQuery(query);
+
+            model_Latest->setHeaderData(0, Qt::Horizontal, tr("ID"));
+            model_Latest->setHeaderData(1, Qt::Horizontal, tr("Summa"));
+            model_Latest->setHeaderData(2, Qt::Horizontal, tr("Aika"));
+
+            ui->tableview_Latest->setModel(model_Latest);
+            ui->tableview_Latest->setColumnHidden(0, true);
+            ui->tableview_Latest->verticalHeader()->setVisible(false);
+            ui->tableview_Latest->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
+
+            setCommonStyleSheet(this);
+            return; // Ugly
+        }
+    }
+
+    // In case of id < 0 or errors ..
+    ui->personGB->setEnabled(false);
+    ui->edit_Amount->clear();
+    ui->label_BalanceValue->setText("--");
+    ui->label_BalanceValue->setStyleSheet(NULL);
+    ui->label_PersonName->setText("???");
+    ui->tableview_Latest->setModel(NULL);
+    setCommonStyleSheet(this);
+}
+
+
+//
+// Widget slot handlers
+//
+void SyntilistaMainWindow::on_button_Quit_clicked()
+{
+    close();
+}
+
+
+void SyntilistaMainWindow::on_button_About_clicked()
+{
+    QMessageBox dlg;
+
+    setCommonStyleSheet(&dlg);
+    dlg.setWindowTitle(tr("Tietoja ohjelmasta"));
+    dlg.setTextFormat(Qt::RichText);
+    dlg.setIconPixmap(QPixmap(":/img/icon-64.png"));
+    dlg.setStandardButtons(QMessageBox::Ok);
+    dlg.setDefaultButton(QMessageBox::Ok);
+
+    //dlg.setInformativeText(tr(
+    dlg.setText(tr(
+        "<h1>%1 v%2</h1>"
+        "<p>"
+        "<b>Ohjelmoinut ja kehittänyt Matti Hämäläinen &lt;ccr@tnsp.org&gt;<br>"
+        "(C) Copyright 2017 Tecnic Software productions (TNSP)</b><br>"
+        "<br>"
+        "Kehitetty Raahen kaupungin Hanketoiminta ja Kehittäminen -yksikön "
+        "alaisuudessa Café Kampuksen käyttöön.<br>"
+        "</p>"
+        "<p>"
+        "Ohjelma ja sen lähdekoodi ovat uudemman BSD-tyylisen lisenssin alaisia. "
+        "Lue ohjelman mukana tullut tiedosto \"COPYING\" (tai \"COPYING.txt\") "
+        "nähdäksesi täydelliset lisenssiehdot."
+        "</p>"
+        ).
+        arg(tr(APP_NAME)).
+        arg(tr(APP_VERSION))
+        );
+
+    dlg.exec();
+}
+
+
+void SyntilistaMainWindow::on_button_Help_clicked()
+{
+    QMessageBox dlg;
+
+    setCommonStyleSheet(&dlg);
+    dlg.setWindowTitle(tr("Tietoja ohjelmasta"));
+    dlg.setTextFormat(Qt::RichText);
+    dlg.setIconPixmap(QPixmap(":/img/icon-64.png"));
+    dlg.setStandardButtons(QMessageBox::Ok);
+    dlg.setDefaultButton(QMessageBox::Ok);
+
+    dlg.setText(tr(
+        "<h1>Pikanäppäimet</h1>"
+        "<table>"
+        "<tr><td><b>F1</b></td><td>Tämä tietoikkuna</td></tr>"
+        "<tr><td><b>F2</b></td><td>Tietoja ohjelmasta</td></tr>"
+        "<tr><td><b>CTRL + Q</b></td><td>Ohjelman lopetus</td></tr>"
+        "<tr><td><b>CTRL + Page Up</b></td><td>Suurenna ohjelman tekstejä/käyttöliittymää</td></tr>"
+        "<tr><td><b>CTRL + Page Down</b></td><td>Pienennä ohjelman tekstejä/käyttöliittymää</td></tr>"
+        "<tr></tr>"
+        "<tr><td><b>Esc</b></td><td>Tyhjennä 'Etsi / suodata' kenttä ja siirry siihen</td></tr>"
+        "<tr><td><b>CTRL + Enter</b></td><td>Siirry summan syöttökenttään</td></tr>"
+        "<tr><td><b>Page Up</b></td><td>Siirry ylös henkilölistassa</td></tr>"
+        "<tr><td><b>Page Down</b></td><td>Siirry alas henkilölistassa</td></tr>"
+        "<tr></tr>"
+        "<tr><td><b>F5</b></td><td>Lisää uusi henkilö</td></tr>"
+        "<tr><td><b>F6</b></td><td>Muokkaa henkilöä</td></tr>"
+        "<tr><td><b>F8</b></td><td>Poista henkilö</td></tr>"
+        "</table>"
+        ));
+
+    dlg.exec();
+}
+
+
+void SyntilistaMainWindow::on_button_DeletePerson_clicked()
+{
+    if (currPerson.id <= 0)
+    {
+        statusMsg(tr("Ei valittua henkilöä!"));
+        return;
+    }
+
+    PersonInfo info;
+    if (!getPersonInfo(currPerson.id, info))
+    {
+        statusMsg(tr("Virhe! Ei henkilöä ID:llä #%1").arg(currPerson.id));
+        return;
+    }
+
+    QMessageBox dlg;
+    setCommonStyleSheet(&dlg);
+    dlg.setText(tr("Varmistus"));
+    dlg.setInformativeText(
+        tr("<br>Haluatko varmasti poistaa henkilön:<br>"
+        "<br>"
+        "<b>'%1, %2'</b> <i>(ID #%3)</i>?<br>"
+        "<br>"
+        "Tämä poistaa sekä henkilön ja hänen koko tapahtumahistoriansa PYSYVÄSTI!<br>").
+        arg(info.lastName).arg(info.firstName).arg(info.id));
+
+    dlg.setTextFormat(Qt::RichText);
+    dlg.setIcon(QMessageBox::Question);
+    dlg.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
+    dlg.setButtonText(QMessageBox::Yes, tr("Kyllä"));
+    dlg.setButtonText(QMessageBox::No, tr("Ei / peruuta"));
+    dlg.setDefaultButton(QMessageBox::No);
+
+    if (dlg.exec() == QMessageBox::Yes)
+    {
+        int rv = model_People->deletePerson(info.id);
+        updatePersonList();
+        setActivePerson(-1);
+        if (rv != 0)
+        {
+            errorMsg(tr("SQL-tietokantavirhe"),
+                tr("Henkilön tietoja poistettaessa tapahtui virhe #%1.").
+                arg(rv));
+        }
+        else
+        {
+            statusMsg(tr("Henkilö '%1 %2' (ID #%3) poistettu.").
+                arg(info.firstName).arg(info.lastName).
+                arg(info.id));
+        }
+    }
+}
+
+
+void SyntilistaMainWindow::on_button_AddPerson_clicked()
+{
+    EditPerson *person = new EditPerson(this);
+    person->setPerson(-1);
+}
+
+
+void SyntilistaMainWindow::on_button_EditPerson_clicked()
+{
+    if (currPerson.id >= 0)
+    {
+        EditPerson *person = new EditPerson(this);
+        person->setPerson(currPerson.id);
+    }
+}
+
+
+void SyntilistaMainWindow::on_tableview_People_doubleClicked(const QModelIndex &curr)
+{
+    int row = curr.row();
+    if (row >= 0)
+    {
+        const QAbstractItemModel *model = curr.model();
+        setActivePerson(model->data(model->index(row, 0)).toInt());
+
+        EditPerson *person = new EditPerson(this);
+        person->setPerson(currPerson.id);
+    }
+    else
+        setActivePerson(-1);
+}
+
+
+void SyntilistaMainWindow::on_button_ClearFilter_clicked()
+{
+    ui->edit_PersonFilter->clear();
+    ui->edit_PersonFilter->setFocus(Qt::ShortcutFocusReason);
+}
+
+
+void SyntilistaMainWindow::focusDebtEdit()
+{
+    if (currPerson.id >= 0)
+        ui->edit_Amount->setFocus(Qt::ShortcutFocusReason);
+}
+
+
+void SyntilistaMainWindow::selectRowPrev()
+{
+    QItemSelectionModel *sel = ui->tableview_People->selectionModel();
+    int row = sel->currentIndex().row() - 1;
+    if (row < 0)
+        row = 0;
+
+    sel->setCurrentIndex(model_People->index(row, 0),
+        QItemSelectionModel::ClearAndSelect|QItemSelectionModel::Rows);
+}
+
+
+void SyntilistaMainWindow::selectRowNext()
+{
+    QItemSelectionModel *sel = ui->tableview_People->selectionModel();
+    int row = sel->currentIndex().row() + 1;
+    if (row >= model_People->rowCount())
+        row = model_People->rowCount() - 1;
+    
+    sel->setCurrentIndex(model_People->index(row, 0),
+        QItemSelectionModel::ClearAndSelect|QItemSelectionModel::Rows);
+}
+
+
+//
+// Update visible person list/query based on the current
+// filtering and sorting settings.
+//
+void SyntilistaMainWindow::updatePersonList()
+{
+    static QString queryBase =
+        "SELECT id,last_name,first_name,"
+        "(SELECT SUM(value) FROM transactions WHERE transactions.person=people.id) AS balance,"
+        "updated FROM people";
+
+    QSqlQuery query;
+    QString queryOrderDir, queryOrderBy;
+
+    // Sort order
+    if (peopleSortOrder == Qt::AscendingOrder)
+        queryOrderDir = QStringLiteral("ASC");
+    else
+        queryOrderDir = QStringLiteral("DESC");
+
+    // Sort by which column
+    switch (peopleSortIndex)
+    {
+        case 1:
+        case 2:
+            queryOrderBy = QStringLiteral(" ORDER BY last_name ") + queryOrderDir + QStringLiteral(",first_name ") + queryOrderDir;
+            break;
+
+        case 3:
+            queryOrderBy = QStringLiteral(" ORDER BY balance ") + queryOrderDir;
+            break;
+
+        case 4:
+            queryOrderBy = QStringLiteral(" ORDER BY updated ") + queryOrderDir;
+            break;
+
+        default:
+            queryOrderBy = "";
+    }
+
+    // Are we filtering or not?
+    if (peopleFilter != "")
+    {
+        // Filter by name(s)
+        QString tmp = "%"+ peopleFilter +"%";
+        query.prepare(queryBase +" WHERE first_name LIKE ? OR last_name LIKE ?" + queryOrderBy);
+
+        query.addBindValue(tmp);
+        query.addBindValue(tmp);
+    }
+    else
+    {
+        // No filter
+        query.prepare(queryBase + queryOrderBy);
+    }
+
+    // Execute the query and update model
+    checkAndReportSQLError("updatePersonList() before exec", query.lastError());
+    query.exec();
+    checkAndReportSQLError("updatePersonList() after exec", query.lastError());
+
+    model_People->setQuery(query);
+
+    model_People->setHeaderData(0, Qt::Horizontal, tr("ID"));
+    model_People->setHeaderData(1, Qt::Horizontal, tr("Sukunimi"));
+    model_People->setHeaderData(2, Qt::Horizontal, tr("Etunimi"));
+    model_People->setHeaderData(3, Qt::Horizontal, tr("Tase"));
+    model_People->setHeaderData(4, Qt::Horizontal, tr("Muutettu"));
+}
+
+
+//
+// Update the list of people when filter parameter changes
+//
+void SyntilistaMainWindow::on_edit_PersonFilter_textChanged(const QString &str)
+{
+    peopleFilter = cleanupStr(str);
+    updatePersonList();
+}
+
+
+//
+// Add one transaction to given person id
+//
+int SyntilistaMainWindow::addTransaction(qint64 id, double value, PersonInfo &info)
+{
+    if (!getPersonInfo(id, info))
+        return -1;
+
+    QSqlDatabase::database().transaction();
+
+    QSqlQuery query;
+    query.prepare("INSERT INTO transactions (person,value,added) VALUES (?,?,?)");
+    query.addBindValue(id);
+    query.addBindValue(value);
+    query.addBindValue(QDateTime::currentDateTimeUtc());
+    query.exec();
+    if (!checkAndReportSQLError("addTransaction()", query.lastError()))
+    {
+        QSqlDatabase::database().rollback();
+        return -2;
+    }
+
+    query.prepare("UPDATE people SET updated=? WHERE id=?");
+    query.addBindValue(QDateTime::currentDateTimeUtc());
+    query.addBindValue(id);
+    query.exec();
+    if (!checkAndReportSQLError("addTransaction update timestamp", query.lastError()))
+    {
+        QSqlDatabase::database().rollback();
+        return -3;
+    }
+
+    QSqlDatabase::database().commit();
+
+    return 0;
+}
+
+
+int SyntilistaMainWindow::addTransactionGUI(qint64 id, bool debt, double value)
+{
+    PersonInfo info;
+
+    // Check if person is selected
+    if (id <= 0)
+        return -1;
+
+    // Check value
+    if (value == 0)
+    {
+        QString tmp = (debt ? "lisätty" : "vähennetty");
+        statusMsg("Velkaa ei "+ tmp +" koska summaa ei määritetty.");
+        return 1;
+    }
+
+    // Perform transaction insert
+    int ret = addTransaction(id, debt ? -value : value, info);
+    if (ret == 0)
+    {
+        // All ok, clear amount entry and update person data
+        ui->edit_Amount->clear();
+        if (info.id == currPerson.id)
+            setActivePerson(info.id);
+
+        model_People->updateModel();
+
+        QString str;
+        if (debt)
+        {
+            str = tr("Lisättiin velkaa %1 EUR henkilölle '%2 %3' (#%4).").
+                arg(moneyValueToStr(value)).
+                arg(info.firstName).
+                arg(info.lastName).
+                arg(info.id);
+        }
+        else
+        {
+            str = tr("Vähennettiin velkaa %1 EUR henkilöltä '%2 %3' (#%4).").
+                arg(moneyValueToStr(value)).
+                arg(info.firstName).
+                arg(info.lastName).
+                arg(info.id);
+        }
+        statusMsg(str);
+    }
+    else
+    {
+        errorMsg(
+            tr("SQL-tietokantavirhe"),
+            tr("Tietokantaan tapahtumaa lisättäessa tapahtui virhe #%1.").
+            arg(ret));
+    }
+
+    return ret;
+}
+
+
+void SyntilistaMainWindow::on_button_AddDebt_clicked()
+{
+    addTransactionGUI(currPerson.id, true, moneyStrToValue(ui->edit_Amount->text()));
+}
+
+
+void SyntilistaMainWindow::on_button_PayDebt_clicked()
+{
+    addTransactionGUI(currPerson.id, false, moneyStrToValue(ui->edit_Amount->text()));
+}
+
+
+void SyntilistaMainWindow::on_button_PayFullDebt_clicked()
+{
+    if (currPerson.balance < 0)
+        addTransactionGUI(currPerson.id, false, -currPerson.balance);
+    else
+    {
+        statusMsg(
+            tr("Valitulla henkilöllä '%1, %2' ei ole velkaa.").
+            arg(currPerson.lastName).
+            arg(currPerson.firstName));
+    }
+}
+
+
+//
+// Edit person dialog
+//
+EditPerson::EditPerson(QWidget *parent) :
+    QDialog(parent),
+    ui(new Ui::EditPerson)
+{
+    ui->setupUi(this);
+
+    setCommonStyleSheet(this);
+
+    setModal(true);
+    setAttribute(Qt::WA_DeleteOnClose);
+    show();
+    activateWindow();
+    raise();
+    setFocus();
+
+    model_Transactions = new TransactionSQLModel();
+    ui->tableview_Transactions->setModel(model_Transactions);
+    ui->tableview_Transactions->setItemDelegate(new QSqlRelationalDelegate(ui->tableview_Transactions));
+    ui->tableview_Transactions->verticalHeader()->setVisible(false);
+    ui->tableview_Transactions->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
+
+    validateForm();
+}
+
+
+EditPerson::~EditPerson()
+{
+    delete ui;
+    delete model_Transactions;
+}
+
+
+void EditPerson::statusMsg(const QString &msg)
+{
+    dynamic_cast<SyntilistaMainWindow *>(parent())->statusMsg(msg);
+}
+
+
+bool EditPerson::validateForm()
+{
+    selPerson.firstName = cleanupStr(ui->edit_FirstName->text());
+    selPerson.lastName = cleanupStr(ui->edit_LastName->text());
+    selPerson.extraInfo = ui->textedit_ExtraInfo->document()->toPlainText();
+
+    ui->edit_FirstName->setStyleSheet(selPerson.firstName == "" ? "background-color: red;" : NULL);
+    ui->edit_LastName->setStyleSheet(selPerson.lastName == "" ? "background-color: red;" : NULL);
+
+    return selPerson.firstName != "" && selPerson.lastName != "";
+}
+
+
+void EditPerson::on_button_Cancel_clicked()
+{
+    close();
+}
+
+
+void EditPerson::on_button_OK_clicked()
+{
+    if (!validateForm())
+    {
+        errorMsg(
+            tr("Virhe!"),
+            tr("Vaaditut kentät (etunimi, sukunimi) eivät ole täytetty."));
+
+        return;
+    }
+
+    if (selPerson.id >= 0)
+    {
+        QSqlQuery person;
+        person.prepare("SELECT * FROM people WHERE id <> ? AND first_name=? AND last_name=?");
+        person.addBindValue(selPerson.id);
+        person.addBindValue(selPerson.firstName);
+        person.addBindValue(selPerson.lastName);
+        person.exec();
+
+        checkAndReportSQLError("SELECT check for existing person by same name (UPDATE)", person.lastError());
+
+        if (person.next())
+        {
+            errorMsg(
+                tr("Virhe!"),
+                tr("Ei pysty! Samalla nimellä '%1 %2' on olemassa jo henkilö!").
+                arg(selPerson.firstName).arg(selPerson.lastName));
+            return;
+        }
+
+        dynamic_cast<SyntilistaMainWindow *>(parent())->model_People->updatePerson(selPerson);
+        dynamic_cast<SyntilistaMainWindow *>(parent())->setActivePerson(selPerson.id);
+
+        statusMsg(tr("Päivitettiin henkilö '%1 %2' (#%3).").
+            arg(selPerson.firstName).arg(selPerson.lastName).arg(selPerson.id));
+    }
+    else
+    {
+        QSqlQuery person;
+        person.prepare("SELECT * FROM people WHERE first_name=? AND last_name=?");
+        person.addBindValue(selPerson.firstName);
+        person.addBindValue(selPerson.lastName);
+        person.exec();
+
+        checkAndReportSQLError("SELECT check for existing person by same name (ADD)", person.lastError());
+
+        if (person.next())
+        {
+            errorMsg(
+                tr("Virhe!"),
+                tr("Ei pysty! Samalla nimellä '%1 %2' on olemassa jo henkilö!").
+                arg(selPerson.firstName).arg(selPerson.lastName));
+
+            return;
+        }
+
+        dynamic_cast<SyntilistaMainWindow *>(parent())->model_People->addPerson(selPerson);
+        dynamic_cast<SyntilistaMainWindow *>(parent())->updatePersonList();
+
+        statusMsg(tr("Lisättiin uusi henkilö '%1 %2'.").
+            arg(selPerson.firstName).arg(selPerson.lastName));
+    }
+
+    close();
+}
+
+
+void EditPerson::on_edit_FirstName_textChanged(const QString &arg1)
+{
+    (void) arg1;
+    validateForm();
+}
+
+
+void EditPerson::on_edit_LastName_textChanged(const QString &arg1)
+{
+    (void) arg1;
+    validateForm();
+}
+
+
+void EditPerson::clearForm()
+{
+    ui->edit_FirstName->clear();
+    ui->edit_LastName->clear();
+    ui->textedit_ExtraInfo->document()->clear();
+    ui->edit_FirstName->setFocus();
+}
+
+
+void EditPerson::setPerson(qint64 id)
+{
+    selPerson.id = id;
+
+    if (id >= 0)
+    {
+        PersonInfo pinfo;
+        if (!getPersonInfo(id, pinfo))
+        {
+            statusMsg(tr("Virhe! Ei henkilöä ID:llä #%1").arg(id));
+        }
+        else
+        {
+            ui->edit_FirstName->setText(pinfo.firstName);
+            ui->edit_LastName->setText(pinfo.lastName);
+            ui->textedit_ExtraInfo->document()->setPlainText(pinfo.extraInfo);
+
+            QSqlQuery query;
+            query.prepare("SELECT id,value,added FROM transactions WHERE person=? ORDER BY added DESC");
+            query.addBindValue(pinfo.id);
+            query.exec();
+            checkAndReportSQLError("SELECT transactions for tableview_Transactions", query.lastError());
+
+            model_Transactions->setQuery(query);
+
+            model_Transactions->setHeaderData(0, Qt::Horizontal, tr("ID"));
+            model_Transactions->setHeaderData(1, Qt::Horizontal, tr("Summa"));
+            model_Transactions->setHeaderData(2, Qt::Horizontal, tr("Aika"));
+
+            ui->tableview_Transactions->setModel(model_Transactions);
+            ui->tableview_Transactions->setColumnHidden(0, true);
+
+            return; // Ugly
+        }
+    }
+
+    // In case of id < 0 or errors ..
+    clearForm();
+    ui->tableview_Transactions->setModel(NULL);
+}
+
+
+//
+// Custom SQL models
+//
+PersonSQLModel::PersonSQLModel(QObject *parent) : QSqlQueryModel(parent)
+{
+}
+
+
+QVariant PersonSQLModel::data(const QModelIndex &index, int role) const
+{
+    QVariant value = QSqlQueryModel::data(index, role);
+
+    if (value.isValid() && role == Qt::DisplayRole)
+    {
+        switch (index.column())
+        {
+            case 3:
+                return moneyValueToStr(value.toDouble());
+
+            case 4:
+                return dateTimeToStr(value.toDateTime());
+        }
+    }
+
+    if (index.column() == 3 && role == Qt::ForegroundRole)
+    {
+        double val = QSqlQueryModel::data(index, Qt::DisplayRole).toDouble();
+        if (val < 0)
+            return QVariant::fromValue(QColor(Qt::red));
+        else
+            return QVariant::fromValue(QColor(Qt::green));
+    }
+
+    return value;
+}
+
+
+int PersonSQLModel::updatePerson(const PersonInfo &info)
+{
+    QSqlQuery np;
+
+    np.prepare("UPDATE people SET first_name=?,last_name=?,extra_info=?,updated=? WHERE id=?");
+    np.addBindValue(info.firstName);
+    np.addBindValue(info.lastName);
+    np.addBindValue(info.extraInfo);
+    np.addBindValue(QDateTime::currentDateTimeUtc());
+    np.addBindValue(info.id);
+    np.exec();
+
+    if (!checkAndReportSQLError("PersonSQLModel::updatePerson()", np.lastError()))
+        return -1;
+
+    QSqlDatabase::database().commit();
+
+    updateModel();
+    return 0;
+}
+
+
+int PersonSQLModel::addPerson(const PersonInfo &info)
+{
+//    beginInsertRows(QModelIndex(), rowCount(), rowCount());
+
+    QSqlQuery np;
+    np.prepare("INSERT INTO people (first_name,last_name,extra_info,added,updated) VALUES (?,?,?,?,?)");
+    np.addBindValue(info.firstName);
+    np.addBindValue(info.lastName);
+    np.addBindValue(info.extraInfo);
+    np.addBindValue(QDateTime::currentDateTimeUtc());
+    np.addBindValue(QDateTime::currentDateTimeUtc());
+    np.exec();
+
+    if (!checkAndReportSQLError("PersonSQLModel::addPerson()", np.lastError()))
+        return -1;
+
+    QSqlDatabase::database().commit();
+
+//    endInsertRows();
+    updateModel();
+    return 0;
+}
+
+
+int PersonSQLModel::deletePerson(qint64 id)
+{
+    QSqlDatabase::database().transaction();
+    QSqlQuery del;
+
+    del.prepare("DELETE FROM people WHERE id=?");
+    del.addBindValue(id);
+    del.exec();
+
+    if (!checkAndReportSQLError("delete user", del.lastError()))
+    {
+        QSqlDatabase::database().rollback();
+        return -1;
+    }
+
+    del.prepare("DELETE FROM transactions WHERE person=?");
+    del.addBindValue(id);
+    del.exec();
+
+    if (!checkAndReportSQLError("delete user transactions", del.lastError()))
+    {
+        QSqlDatabase::database().rollback();
+        return -2;
+    }
+
+    QSqlDatabase::database().commit();
+    updateModel();
+    return 0;
+}
+
+
+void PersonSQLModel::updateModel()
+{
+    query().exec();
+    emit dataChanged(index(0, 0), index(rowCount(), columnCount()));
+}
+
+
+TransactionSQLModel::TransactionSQLModel(QObject *parent) : QSqlQueryModel(parent)
+{
+}
+
+
+QVariant TransactionSQLModel::data(const QModelIndex &index, int role) const
+{
+    QVariant value = QSqlQueryModel::data(index, role);
+
+    if (value.isValid() && role == Qt::DisplayRole)
+    {
+        switch (index.column())
+        {
+            case 1:
+                return moneyValueToStr(value.toDouble());
+
+            case 2:
+                return dateTimeToStr(value.toDateTime());
+        }
+    }
+
+    if (index.column() == 1 && role == Qt::ForegroundRole)
+    {
+        double val = QSqlQueryModel::data(index, Qt::DisplayRole).toDouble();
+        if (val < 0)
+            return QVariant::fromValue(QColor(Qt::red));
+        else
+            return QVariant::fromValue(QColor(Qt::green));
+    }
+
+    return value;
+}
+
+
+void TransactionSQLModel::updateModel()
+{
+    query().exec();
+    emit dataChanged(QModelIndex(), QModelIndex());
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main.h	Mon Apr 24 12:12:39 2017 +0300
@@ -0,0 +1,197 @@
+//
+// Syntilista - velkalistasovellus Kampus-kahvilaan
+// Programmed and designed by Matti Hämäläinen <ccr@tnsp.org>
+// (C) Copyright 2017 Tecnic Software productions (TNSP)
+//
+// Distributed under 3-clause BSD style license, refer to
+// included file "COPYING" for exact terms.
+//
+#ifndef SYNTILISTA_H
+#define SYNTILISTA_H
+
+#include <QMainWindow>
+#include <QShortcut>
+#include <QDialog>
+#include <QtSql>
+#include <QSqlQueryModel>
+
+
+//
+// Global application defines
+//
+#define APP_VENDOR        "TNSP"                    // Vendor ID (for settings, etc.)
+#define APP_ID            "Kampus Syntilista"       // Application ID (for settings)
+#define APP_NAME          "Café Kampus Syntilista"  // Application title/name
+#define APP_SQLITE_FILE   "syntilista.sqlite3"      // SQLite3 database file name (without path)
+
+
+//
+// Custom SQL models
+//
+class PersonInfo : public QObject
+{
+    Q_OBJECT
+    
+public:
+    explicit PersonInfo()
+    {
+        id = -1;
+        firstName = "";
+        lastName = "";
+        extraInfo = "";
+        balance = 0;
+    }
+
+    ~PersonInfo()
+    {
+    }
+
+    void dump();
+
+    qint64 id;
+    QString firstName, lastName, extraInfo;
+    double balance;
+    QDateTime added, updated;
+};
+
+
+
+class PersonSQLModel : public QSqlQueryModel
+{
+    Q_OBJECT
+
+private:
+
+public:
+    PersonSQLModel(QObject *parent = 0);
+
+    QVariant data(const QModelIndex &item, int role) const Q_DECL_OVERRIDE;
+
+    int  updatePerson(const PersonInfo &person);
+    int  addPerson(const PersonInfo &person);
+    int  deletePerson(qint64 id);
+    void updateModel();
+};
+
+
+
+class TransactionSQLModel : public QSqlQueryModel
+{
+    Q_OBJECT
+
+private:
+
+public:
+    TransactionSQLModel(QObject *parent = 0);
+
+    QVariant data(const QModelIndex &item, int role) const Q_DECL_OVERRIDE;
+
+    void updateModel();
+};
+
+
+
+//
+// Main window
+//
+namespace Ui {
+class SyntilistaMainWindow;
+class EditPerson;
+}
+
+class SyntilistaMainWindow : public QMainWindow
+{
+    Q_OBJECT
+
+public:
+    explicit SyntilistaMainWindow(QWidget *parent = 0);
+    ~SyntilistaMainWindow();
+
+    void statusMsg(const QString &msg);
+
+    void readSettings();
+    void saveSettings();
+    void setActivePerson(qint64 id);
+    int  addTransaction(qint64 id, double value, PersonInfo &info);
+    int  addTransactionGUI(qint64 id, bool debt, double value);
+    void updatePersonList();
+
+    PersonSQLModel *model_People;
+
+private slots:
+    void on_button_AddPerson_clicked();
+    void on_button_EditPerson_clicked();
+    void on_button_DeletePerson_clicked();
+
+    void on_edit_PersonFilter_textChanged(const QString &arg1);
+    void on_button_ClearFilter_clicked();
+
+    void on_button_Quit_clicked();
+    void on_button_About_clicked();
+    void on_button_Help_clicked();
+
+    void on_button_AddDebt_clicked();
+    void on_button_PayDebt_clicked();
+    void on_button_PayFullDebt_clicked();
+
+    void on_tableview_People_doubleClicked(const QModelIndex &index);
+
+    void selectedPersonChanged(const QModelIndex &, const QModelIndex &);
+
+    void focusDebtEdit();
+    void selectRowPrev();
+    void selectRowNext();
+
+    void changeUIZoomIn();
+    void changeUIZoomOut();
+    void changeUIZoomReset();
+    
+    void updateSortOrder(int index, Qt::SortOrder order);
+
+
+private:
+    Ui::SyntilistaMainWindow *ui;
+
+    TransactionSQLModel *model_Latest;
+    PersonInfo currPerson;
+
+    int peopleSortIndex;
+    Qt::SortOrder peopleSortOrder;
+    QString peopleFilter;
+};
+
+
+//
+// Person edit / new person dialog
+//
+class EditPerson : public QDialog
+{
+    Q_OBJECT
+
+public:
+    explicit EditPerson(QWidget *parent = 0);
+    ~EditPerson();
+
+    void statusMsg(const QString &msg);
+
+    void clearForm();
+    bool validateForm();
+    void setPerson(qint64 id);
+
+private slots:
+    void on_button_OK_clicked();
+
+    void on_button_Cancel_clicked();
+
+    void on_edit_FirstName_textChanged(const QString &arg1);
+
+    void on_edit_LastName_textChanged(const QString &arg1);
+
+private:
+    Ui::EditPerson *ui;
+
+    PersonInfo selPerson;
+    TransactionSQLModel *model_Transactions;
+};
+
+#endif // SYNTILISTA_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mainwindow.ui	Mon Apr 24 12:12:39 2017 +0300
@@ -0,0 +1,309 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SyntilistaMainWindow</class>
+ <widget class="QMainWindow" name="SyntilistaMainWindow">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>835</width>
+    <height>646</height>
+   </rect>
+  </property>
+  <widget class="QWidget" name="centralwidget">
+   <layout class="QHBoxLayout" name="horizontalLayout_2">
+    <item>
+     <widget class="QGroupBox" name="henkilotGB">
+      <property name="title">
+       <string>Henkilöt</string>
+      </property>
+      <layout class="QVBoxLayout" name="verticalLayout_2">
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_3">
+         <item>
+          <widget class="QLabel" name="label">
+           <property name="text">
+            <string>Etsi / suodata</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QLineEdit" name="edit_PersonFilter"/>
+         </item>
+         <item>
+          <widget class="QPushButton" name="button_ClearFilter">
+           <property name="text">
+            <string>Tyhjennä suodatin</string>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <widget class="QTableView" name="tableview_People">
+         <property name="selectionMode">
+          <enum>QAbstractItemView::SingleSelection</enum>
+         </property>
+         <property name="selectionBehavior">
+          <enum>QAbstractItemView::SelectRows</enum>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout">
+         <item>
+          <widget class="QPushButton" name="button_DeletePerson">
+           <property name="text">
+            <string>Poista henkilö</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <spacer name="horizontalSpacer">
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>40</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+         <item>
+          <widget class="QPushButton" name="button_AddPerson">
+           <property name="text">
+            <string>Lisää uusi henkilö</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QPushButton" name="button_EditPerson">
+           <property name="text">
+            <string>Muokkaa henkilöä</string>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+      </layout>
+     </widget>
+    </item>
+    <item>
+     <layout class="QVBoxLayout" name="verticalLayout">
+      <property name="sizeConstraint">
+       <enum>QLayout::SetMinimumSize</enum>
+      </property>
+      <item>
+       <widget class="QGroupBox" name="personGB">
+        <property name="enabled">
+         <bool>true</bool>
+        </property>
+        <property name="title">
+         <string>Henkilön syntilista</string>
+        </property>
+        <property name="alignment">
+         <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+        </property>
+        <property name="flat">
+         <bool>false</bool>
+        </property>
+        <layout class="QVBoxLayout" name="verticalLayout_3">
+         <property name="sizeConstraint">
+          <enum>QLayout::SetMinimumSize</enum>
+         </property>
+         <item>
+          <widget class="QLabel" name="label_PersonName">
+           <property name="text">
+            <string>Henkilön nimi</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="Line" name="line">
+           <property name="lineWidth">
+            <number>4</number>
+           </property>
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <layout class="QHBoxLayout" name="horizontalLayout_6">
+           <item>
+            <widget class="QLabel" name="label_CurrentBalance">
+             <property name="text">
+              <string>Nykyinen tase:</string>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <widget class="QLabel" name="label_BalanceValue">
+             <property name="text">
+              <string>12345</string>
+             </property>
+             <property name="alignment">
+              <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <widget class="QLabel" name="label_EUR">
+             <property name="text">
+              <string>EUR</string>
+             </property>
+             <property name="alignment">
+              <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+             </property>
+            </widget>
+           </item>
+          </layout>
+         </item>
+         <item>
+          <widget class="Line" name="line_2">
+           <property name="lineWidth">
+            <number>4</number>
+           </property>
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QLineEdit" name="edit_Amount">
+           <property name="text">
+            <string/>
+           </property>
+           <property name="alignment">
+            <set>Qt::AlignCenter</set>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <layout class="QHBoxLayout" name="horizontalLayout_5">
+           <item>
+            <widget class="QPushButton" name="button_AddDebt">
+             <property name="text">
+              <string>Lisää velkaa</string>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <widget class="QPushButton" name="button_PayDebt">
+             <property name="text">
+              <string>Maksa velkaa</string>
+             </property>
+            </widget>
+           </item>
+          </layout>
+         </item>
+         <item>
+          <widget class="QPushButton" name="button_PayFullDebt">
+           <property name="text">
+            <string>Maksa koko velka</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QLabel" name="label_2">
+           <property name="text">
+            <string>Viimeisimmät tapahtumat:</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QTableView" name="tableview_Latest">
+           <property name="selectionMode">
+            <enum>QAbstractItemView::SingleSelection</enum>
+           </property>
+           <property name="selectionBehavior">
+            <enum>QAbstractItemView::SelectRows</enum>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </widget>
+      </item>
+      <item>
+       <widget class="QLabel" name="button_LogoImage">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="text">
+         <string/>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <layout class="QHBoxLayout" name="horizontalLayout_4">
+        <property name="sizeConstraint">
+         <enum>QLayout::SetMinimumSize</enum>
+        </property>
+        <item>
+         <widget class="QPushButton" name="button_About">
+          <property name="text">
+           <string/>
+          </property>
+          <property name="icon">
+           <iconset resource="resources.qrc">
+            <normaloff>:/img/icon-64.png</normaloff>:/img/icon-64.png</iconset>
+          </property>
+          <property name="iconSize">
+           <size>
+            <width>32</width>
+            <height>32</height>
+           </size>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QPushButton" name="button_Help">
+          <property name="text">
+           <string>?</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="horizontalSpacer_2">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item>
+         <widget class="QPushButton" name="button_Quit">
+          <property name="text">
+           <string>Poistu ohjelmasta</string>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
+     </layout>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QStatusBar" name="statusbar"/>
+ </widget>
+ <tabstops>
+  <tabstop>edit_PersonFilter</tabstop>
+  <tabstop>button_ClearFilter</tabstop>
+  <tabstop>button_AddPerson</tabstop>
+  <tabstop>button_Quit</tabstop>
+ </tabstops>
+ <resources>
+  <include location="resources.qrc"/>
+ </resources>
+ <connections/>
+</ui>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/resources.qrc	Mon Apr 24 12:12:39 2017 +0300
@@ -0,0 +1,6 @@
+<RCC>
+  <qresource prefix="img">
+    <file>../img/logo.png</file>
+    <file>../img/icon-64.png</file>
+  </qresource>
+</RCC>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/winres.rc.in	Mon Apr 24 12:12:39 2017 +0300
@@ -0,0 +1,20 @@
+MAINICON ICON "icon.ico"
+1 VERSIONINFO
+FILEVERSION     1,0,0,0
+PRODUCTVERSION  @APP_VERSION_COM@
+BEGIN
+  BLOCK "StringFileInfo"
+  BEGIN
+    BLOCK "040904E4"
+    BEGIN
+      VALUE "CompanyName", "TNSP"
+      VALUE "FileDescription", "Cafe Kampus Syntilista"
+      VALUE "FileVersion", "1.0"
+      VALUE "InternalName", "Syntilista"
+      VALUE "LegalCopyright", "(C) Copyright 2017 Tecnic Software productions"
+      VALUE "OriginalFilename", "@APP_EXE@"
+      VALUE "ProductName", "Syntilista"
+      VALUE "ProductVersion", "@APP_VERSION@"
+    END
+  END
+END
--- a/winres.rc.in	Wed Apr 12 12:16:00 2017 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-MAINICON ICON "icon.ico"
-1 VERSIONINFO
-FILEVERSION     1,0,0,0
-PRODUCTVERSION  @APP_VERSION_COM@
-BEGIN
-  BLOCK "StringFileInfo"
-  BEGIN
-    BLOCK "040904E4"
-    BEGIN
-      VALUE "CompanyName", "TNSP"
-      VALUE "FileDescription", "Cafe Kampus Syntilista"
-      VALUE "FileVersion", "1.0"
-      VALUE "InternalName", "Syntilista"
-      VALUE "LegalCopyright", "(C) Copyright 2017 Tecnic Software productions"
-      VALUE "OriginalFilename", "@APP_EXE@"
-      VALUE "ProductName", "Syntilista"
-      VALUE "ProductVersion", "@APP_VERSION@"
-    END
-  END
-END