diff --git a/README.md b/README.md
index 4e06456..fcef5b3 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,21 @@
-# Saeterprosjekt
+# Sæterprosjekt
-A very simple project management system. Supports multithreading and data is stored in a flat binary file database.
\ No newline at end of file
+A very simple project management system. Uses a custom flat binary file database implementation for storing data and uses multithreading.
+
+## Features
+
+At it's current state it has a few very simple features tailored for a specific use set. Features include:
+
+- Create, load, store and manage a list of customers and their contact data
+- Create, load, store and manage a list of projects and project details
+- Able to sort customers under individual projects
+- Able to set notification thresholds that reminds you before a project starts and/or project ends
+ - Thresholds are coded "green","yellow", and "red". The notification thresholds can be adjusted individually per project or globaly through the application settings
+
+## About
+
+I threw this program together over the weekend (version 0.1), because a friend needed project manager such as this. Coincidentally, the program is named after him :)
+
+## License
+
+The program it's source and derivatives are licensed under GNU general public license (version 3) and copyrighted by me (Helge-Mikael Nordgård). See file "LICENSE" for more details.
diff --git a/Saeterprosjekt.pro b/Saeterprosjekt.pro
new file mode 100644
index 0000000..c9b10d2
--- /dev/null
+++ b/Saeterprosjekt.pro
@@ -0,0 +1,5 @@
+TEMPLATE = subdirs
+
+CONFIG += ordered
+
+SUBDIRS += src
\ No newline at end of file
diff --git a/Saeterprosjekt.pro.user b/Saeterprosjekt.pro.user
new file mode 100644
index 0000000..029d496
--- /dev/null
+++ b/Saeterprosjekt.pro.user
@@ -0,0 +1,322 @@
+
+
+
+
+
+ EnvironmentId
+ {d7c8b74b-4415-4b08-aa92-0f975907c8ea}
+
+
+ ProjectExplorer.Project.ActiveTarget
+ 0
+
+
+ ProjectExplorer.Project.EditorSettings
+
+ true
+ false
+ true
+
+ Cpp
+
+ CppGlobal
+
+
+
+ QmlJS
+
+ QmlJSGlobal
+
+
+ 2
+ UTF-8
+ false
+ 4
+ false
+ 80
+ true
+ true
+ 1
+ false
+ true
+ false
+ 0
+ true
+ true
+ 0
+ 8
+ true
+ false
+ 1
+ true
+ true
+ true
+ *.md, *.MD, Makefile
+ false
+ true
+
+
+
+ ProjectExplorer.Project.PluginSettings
+
+
+ true
+ false
+ true
+ true
+ true
+ true
+
+
+ 0
+ true
+
+ -fno-delayed-template-parsing
+
+ true
+ Builtin.BuildSystem
+
+ true
+ true
+ Builtin.DefaultTidyAndClazy
+ 2
+
+
+
+ true
+
+
+
+
+ ProjectExplorer.Project.Target.0
+
+ Desktop
+ Desktop Qt 5.15.2 MinGW 64-bit
+ Desktop Qt 5.15.2 MinGW 64-bit
+ qt.qt5.5152.win64_mingw81_kit
+ 0
+ 0
+ 0
+
+ 0
+ C:\Users\heno\Documents\build-Saeterprosjekt-Desktop_Qt_5_15_2_MinGW_64_bit-Debug
+ C:/Users/heno/Documents/build-Saeterprosjekt-Desktop_Qt_5_15_2_MinGW_64_bit-Debug
+
+
+ true
+ QtProjectManager.QMakeBuildStep
+ false
+
+
+
+ true
+ Qt4ProjectManager.MakeStep
+
+ 2
+ Build
+ Build
+ ProjectExplorer.BuildSteps.Build
+
+
+
+ true
+ Qt4ProjectManager.MakeStep
+ clean
+
+ 1
+ Clean
+ Clean
+ ProjectExplorer.BuildSteps.Clean
+
+ 2
+ false
+
+
+ Debug
+ Qt4ProjectManager.Qt4BuildConfiguration
+ 2
+
+
+ C:\Users\heno\Documents\build-Saeterprosjekt-Desktop_Qt_5_15_2_MinGW_64_bit-Release
+ C:/Users/heno/Documents/build-Saeterprosjekt-Desktop_Qt_5_15_2_MinGW_64_bit-Release
+
+
+ true
+ QtProjectManager.QMakeBuildStep
+ false
+
+
+
+ true
+ Qt4ProjectManager.MakeStep
+
+ 2
+ Build
+ Build
+ ProjectExplorer.BuildSteps.Build
+
+
+
+ true
+ Qt4ProjectManager.MakeStep
+ clean
+
+ 1
+ Clean
+ Clean
+ ProjectExplorer.BuildSteps.Clean
+
+ 2
+ false
+
+
+ Release
+ Qt4ProjectManager.Qt4BuildConfiguration
+ 0
+ 0
+
+
+ 0
+ C:\Users\heno\Documents\build-Saeterprosjekt-Desktop_Qt_5_15_2_MinGW_64_bit-Profile
+ C:/Users/heno/Documents/build-Saeterprosjekt-Desktop_Qt_5_15_2_MinGW_64_bit-Profile
+
+
+ true
+ QtProjectManager.QMakeBuildStep
+ false
+
+
+
+ true
+ Qt4ProjectManager.MakeStep
+
+ 2
+ Build
+ Build
+ ProjectExplorer.BuildSteps.Build
+
+
+
+ true
+ Qt4ProjectManager.MakeStep
+ clean
+
+ 1
+ Clean
+ Clean
+ ProjectExplorer.BuildSteps.Clean
+
+ 2
+ false
+
+
+ Profile
+ Qt4ProjectManager.Qt4BuildConfiguration
+ 0
+ 0
+ 0
+
+ 3
+
+
+ 0
+ Deploy
+ Deploy
+ ProjectExplorer.BuildSteps.Deploy
+
+ 1
+
+ false
+ ProjectExplorer.DefaultDeployConfiguration
+
+ 1
+
+ dwarf
+
+ cpu-cycles
+
+
+ 250
+
+ -e
+ cpu-cycles
+ --call-graph
+ dwarf,4096
+ -F
+ 250
+
+ -F
+ true
+ 4096
+ false
+ false
+ 1000
+
+ true
+
+
+ false
+ false
+ false
+ false
+ true
+ 0.01
+ 10
+ true
+ kcachegrind
+ 1
+
+ 25
+
+ 1
+ true
+ false
+ true
+
+ valgrind
+
+ 0
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ 11
+ 12
+ 13
+ 14
+
+
+ 2
+
+ core2
+ Qt4ProjectManager.Qt4RunConfiguration:C:/Users/heno/Nextcloud/Div QT Projects/saeterprosjekt/src/core/core.pro
+ C:/Users/heno/Nextcloud/Div QT Projects/saeterprosjekt/src/core/core.pro
+ false
+ true
+ true
+ false
+ true
+ C:/Users/heno/Documents/build-Saeterprosjekt-Desktop_Qt_5_15_2_MinGW_64_bit-Debug/src/core
+
+ 1
+
+
+
+ ProjectExplorer.Project.TargetCount
+ 1
+
+
+ ProjectExplorer.Project.Updater.FileVersion
+ 22
+
+
+ Version
+ 22
+
+
diff --git a/res/activity.svg b/res/activity.svg
new file mode 100644
index 0000000..669a57a
--- /dev/null
+++ b/res/activity.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/airplay.svg b/res/airplay.svg
new file mode 100644
index 0000000..7ce7302
--- /dev/null
+++ b/res/airplay.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/alert-circle.svg b/res/alert-circle.svg
new file mode 100644
index 0000000..8d02b7d
--- /dev/null
+++ b/res/alert-circle.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/alert-octagon.svg b/res/alert-octagon.svg
new file mode 100644
index 0000000..de9b03f
--- /dev/null
+++ b/res/alert-octagon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/alert-triangle.svg b/res/alert-triangle.svg
new file mode 100644
index 0000000..6dcb096
--- /dev/null
+++ b/res/alert-triangle.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/align-center.svg b/res/align-center.svg
new file mode 100644
index 0000000..5b8842e
--- /dev/null
+++ b/res/align-center.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/align-justify.svg b/res/align-justify.svg
new file mode 100644
index 0000000..0539876
--- /dev/null
+++ b/res/align-justify.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/align-left.svg b/res/align-left.svg
new file mode 100644
index 0000000..9ac852a
--- /dev/null
+++ b/res/align-left.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/align-right.svg b/res/align-right.svg
new file mode 100644
index 0000000..ef139ff
--- /dev/null
+++ b/res/align-right.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/anchor.svg b/res/anchor.svg
new file mode 100644
index 0000000..e01627a
--- /dev/null
+++ b/res/anchor.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/aperture.svg b/res/aperture.svg
new file mode 100644
index 0000000..9936e86
--- /dev/null
+++ b/res/aperture.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/archive.svg b/res/archive.svg
new file mode 100644
index 0000000..428882c
--- /dev/null
+++ b/res/archive.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/arrow-down-circle.svg b/res/arrow-down-circle.svg
new file mode 100644
index 0000000..3238091
--- /dev/null
+++ b/res/arrow-down-circle.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/arrow-down-left.svg b/res/arrow-down-left.svg
new file mode 100644
index 0000000..7248358
--- /dev/null
+++ b/res/arrow-down-left.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/arrow-down-right.svg b/res/arrow-down-right.svg
new file mode 100644
index 0000000..81d9822
--- /dev/null
+++ b/res/arrow-down-right.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/arrow-down.svg b/res/arrow-down.svg
new file mode 100644
index 0000000..4f84f62
--- /dev/null
+++ b/res/arrow-down.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/arrow-left-circle.svg b/res/arrow-left-circle.svg
new file mode 100644
index 0000000..3b19ff8
--- /dev/null
+++ b/res/arrow-left-circle.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/arrow-left.svg b/res/arrow-left.svg
new file mode 100644
index 0000000..a5058fc
--- /dev/null
+++ b/res/arrow-left.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/arrow-right-circle.svg b/res/arrow-right-circle.svg
new file mode 100644
index 0000000..ff01dd5
--- /dev/null
+++ b/res/arrow-right-circle.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/arrow-right.svg b/res/arrow-right.svg
new file mode 100644
index 0000000..939b57c
--- /dev/null
+++ b/res/arrow-right.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/arrow-up-circle.svg b/res/arrow-up-circle.svg
new file mode 100644
index 0000000..044a75d
--- /dev/null
+++ b/res/arrow-up-circle.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/arrow-up-left.svg b/res/arrow-up-left.svg
new file mode 100644
index 0000000..cea55e8
--- /dev/null
+++ b/res/arrow-up-left.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/arrow-up-right.svg b/res/arrow-up-right.svg
new file mode 100644
index 0000000..95678e0
--- /dev/null
+++ b/res/arrow-up-right.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/arrow-up.svg b/res/arrow-up.svg
new file mode 100644
index 0000000..16b13ab
--- /dev/null
+++ b/res/arrow-up.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/at-sign.svg b/res/at-sign.svg
new file mode 100644
index 0000000..5a5e5d0
--- /dev/null
+++ b/res/at-sign.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/award.svg b/res/award.svg
new file mode 100644
index 0000000..be70d5a
--- /dev/null
+++ b/res/award.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/bar-chart-2.svg b/res/bar-chart-2.svg
new file mode 100644
index 0000000..864167a
--- /dev/null
+++ b/res/bar-chart-2.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/bar-chart.svg b/res/bar-chart.svg
new file mode 100644
index 0000000..074d7c1
--- /dev/null
+++ b/res/bar-chart.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/battery-charging.svg b/res/battery-charging.svg
new file mode 100644
index 0000000..644cb59
--- /dev/null
+++ b/res/battery-charging.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/battery.svg b/res/battery.svg
new file mode 100644
index 0000000..7fe8771
--- /dev/null
+++ b/res/battery.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/bell-off.svg b/res/bell-off.svg
new file mode 100644
index 0000000..4b07c84
--- /dev/null
+++ b/res/bell-off.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/bell.svg b/res/bell.svg
new file mode 100644
index 0000000..bba561c
--- /dev/null
+++ b/res/bell.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/bluetooth.svg b/res/bluetooth.svg
new file mode 100644
index 0000000..cebed7b
--- /dev/null
+++ b/res/bluetooth.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/bold.svg b/res/bold.svg
new file mode 100644
index 0000000..d1a4efd
--- /dev/null
+++ b/res/bold.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/book-open.svg b/res/book-open.svg
new file mode 100644
index 0000000..5e0ca0a
--- /dev/null
+++ b/res/book-open.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/book.svg b/res/book.svg
new file mode 100644
index 0000000..12ffcbc
--- /dev/null
+++ b/res/book.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/bookmark.svg b/res/bookmark.svg
new file mode 100644
index 0000000..2239cc5
--- /dev/null
+++ b/res/bookmark.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/box.svg b/res/box.svg
new file mode 100644
index 0000000..d89be30
--- /dev/null
+++ b/res/box.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/briefcase.svg b/res/briefcase.svg
new file mode 100644
index 0000000..e3af050
--- /dev/null
+++ b/res/briefcase.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/calendar.svg b/res/calendar.svg
new file mode 100644
index 0000000..6c7fd87
--- /dev/null
+++ b/res/calendar.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/camera-off.svg b/res/camera-off.svg
new file mode 100644
index 0000000..daa3e25
--- /dev/null
+++ b/res/camera-off.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/camera.svg b/res/camera.svg
new file mode 100644
index 0000000..0e7f060
--- /dev/null
+++ b/res/camera.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/cast.svg b/res/cast.svg
new file mode 100644
index 0000000..63c954d
--- /dev/null
+++ b/res/cast.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/check-circle.svg b/res/check-circle.svg
new file mode 100644
index 0000000..f2f4fd1
--- /dev/null
+++ b/res/check-circle.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/check-square.svg b/res/check-square.svg
new file mode 100644
index 0000000..72ab7a8
--- /dev/null
+++ b/res/check-square.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/check.svg b/res/check.svg
new file mode 100644
index 0000000..1c20989
--- /dev/null
+++ b/res/check.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/chevron-down.svg b/res/chevron-down.svg
new file mode 100644
index 0000000..278c6a3
--- /dev/null
+++ b/res/chevron-down.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/chevron-left.svg b/res/chevron-left.svg
new file mode 100644
index 0000000..747d46d
--- /dev/null
+++ b/res/chevron-left.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/chevron-right.svg b/res/chevron-right.svg
new file mode 100644
index 0000000..258de41
--- /dev/null
+++ b/res/chevron-right.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/chevron-up.svg b/res/chevron-up.svg
new file mode 100644
index 0000000..4eb5ecc
--- /dev/null
+++ b/res/chevron-up.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/chevrons-down.svg b/res/chevrons-down.svg
new file mode 100644
index 0000000..e67ef2f
--- /dev/null
+++ b/res/chevrons-down.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/chevrons-left.svg b/res/chevrons-left.svg
new file mode 100644
index 0000000..c32e398
--- /dev/null
+++ b/res/chevrons-left.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/chevrons-right.svg b/res/chevrons-right.svg
new file mode 100644
index 0000000..f506814
--- /dev/null
+++ b/res/chevrons-right.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/chevrons-up.svg b/res/chevrons-up.svg
new file mode 100644
index 0000000..0eaf518
--- /dev/null
+++ b/res/chevrons-up.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/chrome.svg b/res/chrome.svg
new file mode 100644
index 0000000..9189815
--- /dev/null
+++ b/res/chrome.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/circle.svg b/res/circle.svg
new file mode 100644
index 0000000..b009088
--- /dev/null
+++ b/res/circle.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/clipboard.svg b/res/clipboard.svg
new file mode 100644
index 0000000..ccee454
--- /dev/null
+++ b/res/clipboard.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/clock.svg b/res/clock.svg
new file mode 100644
index 0000000..ea3f5e5
--- /dev/null
+++ b/res/clock.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/cloud-drizzle.svg b/res/cloud-drizzle.svg
new file mode 100644
index 0000000..13af6bb
--- /dev/null
+++ b/res/cloud-drizzle.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/cloud-lightning.svg b/res/cloud-lightning.svg
new file mode 100644
index 0000000..32d154c
--- /dev/null
+++ b/res/cloud-lightning.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/cloud-off.svg b/res/cloud-off.svg
new file mode 100644
index 0000000..1e1e7d6
--- /dev/null
+++ b/res/cloud-off.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/cloud-rain.svg b/res/cloud-rain.svg
new file mode 100644
index 0000000..3e0b85b
--- /dev/null
+++ b/res/cloud-rain.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/cloud-snow.svg b/res/cloud-snow.svg
new file mode 100644
index 0000000..e4eb820
--- /dev/null
+++ b/res/cloud-snow.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/cloud.svg b/res/cloud.svg
new file mode 100644
index 0000000..0ee0c63
--- /dev/null
+++ b/res/cloud.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/code.svg b/res/code.svg
new file mode 100644
index 0000000..c4954b5
--- /dev/null
+++ b/res/code.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/codepen.svg b/res/codepen.svg
new file mode 100644
index 0000000..ab2a815
--- /dev/null
+++ b/res/codepen.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/codesandbox.svg b/res/codesandbox.svg
new file mode 100644
index 0000000..49848f5
--- /dev/null
+++ b/res/codesandbox.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/coffee.svg b/res/coffee.svg
new file mode 100644
index 0000000..32905e5
--- /dev/null
+++ b/res/coffee.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/columns.svg b/res/columns.svg
new file mode 100644
index 0000000..d264b55
--- /dev/null
+++ b/res/columns.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/command.svg b/res/command.svg
new file mode 100644
index 0000000..93f554c
--- /dev/null
+++ b/res/command.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/compass.svg b/res/compass.svg
new file mode 100644
index 0000000..3296260
--- /dev/null
+++ b/res/compass.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/copy.svg b/res/copy.svg
new file mode 100644
index 0000000..4e0b09f
--- /dev/null
+++ b/res/copy.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/corner-down-left.svg b/res/corner-down-left.svg
new file mode 100644
index 0000000..9fffb3e
--- /dev/null
+++ b/res/corner-down-left.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/corner-down-right.svg b/res/corner-down-right.svg
new file mode 100644
index 0000000..b27d408
--- /dev/null
+++ b/res/corner-down-right.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/corner-left-down.svg b/res/corner-left-down.svg
new file mode 100644
index 0000000..24b8375
--- /dev/null
+++ b/res/corner-left-down.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/corner-left-up.svg b/res/corner-left-up.svg
new file mode 100644
index 0000000..e54527c
--- /dev/null
+++ b/res/corner-left-up.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/corner-right-down.svg b/res/corner-right-down.svg
new file mode 100644
index 0000000..a49e6d6
--- /dev/null
+++ b/res/corner-right-down.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/corner-right-up.svg b/res/corner-right-up.svg
new file mode 100644
index 0000000..a5c5dce
--- /dev/null
+++ b/res/corner-right-up.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/corner-up-left.svg b/res/corner-up-left.svg
new file mode 100644
index 0000000..0a1ffd6
--- /dev/null
+++ b/res/corner-up-left.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/corner-up-right.svg b/res/corner-up-right.svg
new file mode 100644
index 0000000..0b8f961
--- /dev/null
+++ b/res/corner-up-right.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/cpu.svg b/res/cpu.svg
new file mode 100644
index 0000000..2ed16ef
--- /dev/null
+++ b/res/cpu.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/credit-card.svg b/res/credit-card.svg
new file mode 100644
index 0000000..1b7fd02
--- /dev/null
+++ b/res/credit-card.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/crop.svg b/res/crop.svg
new file mode 100644
index 0000000..ffbfd04
--- /dev/null
+++ b/res/crop.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/crosshair.svg b/res/crosshair.svg
new file mode 100644
index 0000000..ba39401
--- /dev/null
+++ b/res/crosshair.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/database.svg b/res/database.svg
new file mode 100644
index 0000000..c296fbc
--- /dev/null
+++ b/res/database.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/delete.svg b/res/delete.svg
new file mode 100644
index 0000000..8c6074b
--- /dev/null
+++ b/res/delete.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/disc.svg b/res/disc.svg
new file mode 100644
index 0000000..2595b44
--- /dev/null
+++ b/res/disc.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/divide-circle.svg b/res/divide-circle.svg
new file mode 100644
index 0000000..03a50b7
--- /dev/null
+++ b/res/divide-circle.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/divide-square.svg b/res/divide-square.svg
new file mode 100644
index 0000000..852f776
--- /dev/null
+++ b/res/divide-square.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/divide.svg b/res/divide.svg
new file mode 100644
index 0000000..3cbff3a
--- /dev/null
+++ b/res/divide.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/dollar-sign.svg b/res/dollar-sign.svg
new file mode 100644
index 0000000..1a124d2
--- /dev/null
+++ b/res/dollar-sign.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/download-cloud.svg b/res/download-cloud.svg
new file mode 100644
index 0000000..f3126fc
--- /dev/null
+++ b/res/download-cloud.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/download.svg b/res/download.svg
new file mode 100644
index 0000000..76767a9
--- /dev/null
+++ b/res/download.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/dribbble.svg b/res/dribbble.svg
new file mode 100644
index 0000000..bb8577d
--- /dev/null
+++ b/res/dribbble.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/droplet.svg b/res/droplet.svg
new file mode 100644
index 0000000..ca09301
--- /dev/null
+++ b/res/droplet.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/edit-2.svg b/res/edit-2.svg
new file mode 100644
index 0000000..06830c9
--- /dev/null
+++ b/res/edit-2.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/edit-3.svg b/res/edit-3.svg
new file mode 100644
index 0000000..d728efc
--- /dev/null
+++ b/res/edit-3.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/edit.svg b/res/edit.svg
new file mode 100644
index 0000000..ec7b4ca
--- /dev/null
+++ b/res/edit.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/external-link.svg b/res/external-link.svg
new file mode 100644
index 0000000..6236df3
--- /dev/null
+++ b/res/external-link.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/eye-off.svg b/res/eye-off.svg
new file mode 100644
index 0000000..77c54cb
--- /dev/null
+++ b/res/eye-off.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/eye.svg b/res/eye.svg
new file mode 100644
index 0000000..9cde243
--- /dev/null
+++ b/res/eye.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/facebook.svg b/res/facebook.svg
new file mode 100644
index 0000000..2570f56
--- /dev/null
+++ b/res/facebook.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/fast-forward.svg b/res/fast-forward.svg
new file mode 100644
index 0000000..fa39877
--- /dev/null
+++ b/res/fast-forward.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/feather.svg b/res/feather.svg
new file mode 100644
index 0000000..ac3b868
--- /dev/null
+++ b/res/feather.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/figma.svg b/res/figma.svg
new file mode 100644
index 0000000..66fd217
--- /dev/null
+++ b/res/figma.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/file-minus.svg b/res/file-minus.svg
new file mode 100644
index 0000000..345756e
--- /dev/null
+++ b/res/file-minus.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/file-plus.svg b/res/file-plus.svg
new file mode 100644
index 0000000..eed1200
--- /dev/null
+++ b/res/file-plus.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/file-text.svg b/res/file-text.svg
new file mode 100644
index 0000000..4197ddd
--- /dev/null
+++ b/res/file-text.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/file.svg b/res/file.svg
new file mode 100644
index 0000000..378519a
--- /dev/null
+++ b/res/file.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/film.svg b/res/film.svg
new file mode 100644
index 0000000..ac46360
--- /dev/null
+++ b/res/film.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/filter.svg b/res/filter.svg
new file mode 100644
index 0000000..38a47e0
--- /dev/null
+++ b/res/filter.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/flag.svg b/res/flag.svg
new file mode 100644
index 0000000..037737c
--- /dev/null
+++ b/res/flag.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/folder-minus.svg b/res/folder-minus.svg
new file mode 100644
index 0000000..d5b7af6
--- /dev/null
+++ b/res/folder-minus.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/folder-plus.svg b/res/folder-plus.svg
new file mode 100644
index 0000000..898f2fc
--- /dev/null
+++ b/res/folder-plus.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/folder.svg b/res/folder.svg
new file mode 100644
index 0000000..134458b
--- /dev/null
+++ b/res/folder.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/framer.svg b/res/framer.svg
new file mode 100644
index 0000000..3e66347
--- /dev/null
+++ b/res/framer.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/frown.svg b/res/frown.svg
new file mode 100644
index 0000000..f312254
--- /dev/null
+++ b/res/frown.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/gift.svg b/res/gift.svg
new file mode 100644
index 0000000..d2c14bd
--- /dev/null
+++ b/res/gift.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/git-branch.svg b/res/git-branch.svg
new file mode 100644
index 0000000..4400372
--- /dev/null
+++ b/res/git-branch.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/git-commit.svg b/res/git-commit.svg
new file mode 100644
index 0000000..e959d72
--- /dev/null
+++ b/res/git-commit.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/git-merge.svg b/res/git-merge.svg
new file mode 100644
index 0000000..c65fffd
--- /dev/null
+++ b/res/git-merge.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/git-pull-request.svg b/res/git-pull-request.svg
new file mode 100644
index 0000000..fc80bdf
--- /dev/null
+++ b/res/git-pull-request.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/github.svg b/res/github.svg
new file mode 100644
index 0000000..ff0af48
--- /dev/null
+++ b/res/github.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/gitlab.svg b/res/gitlab.svg
new file mode 100644
index 0000000..85d54a1
--- /dev/null
+++ b/res/gitlab.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/globe.svg b/res/globe.svg
new file mode 100644
index 0000000..0a0586d
--- /dev/null
+++ b/res/globe.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/grid.svg b/res/grid.svg
new file mode 100644
index 0000000..8ef2e9d
--- /dev/null
+++ b/res/grid.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/hard-drive.svg b/res/hard-drive.svg
new file mode 100644
index 0000000..8e90fa1
--- /dev/null
+++ b/res/hard-drive.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/hash.svg b/res/hash.svg
new file mode 100644
index 0000000..c9c8d41
--- /dev/null
+++ b/res/hash.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/headphones.svg b/res/headphones.svg
new file mode 100644
index 0000000..fd8915b
--- /dev/null
+++ b/res/headphones.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/heart.svg b/res/heart.svg
new file mode 100644
index 0000000..a083b7e
--- /dev/null
+++ b/res/heart.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/help-circle.svg b/res/help-circle.svg
new file mode 100644
index 0000000..51fddd8
--- /dev/null
+++ b/res/help-circle.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/hexagon.svg b/res/hexagon.svg
new file mode 100644
index 0000000..eae7f25
--- /dev/null
+++ b/res/hexagon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/home.svg b/res/home.svg
new file mode 100644
index 0000000..7bb31b2
--- /dev/null
+++ b/res/home.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/image.svg b/res/image.svg
new file mode 100644
index 0000000..a7d84b9
--- /dev/null
+++ b/res/image.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/inbox.svg b/res/inbox.svg
new file mode 100644
index 0000000..03a13b4
--- /dev/null
+++ b/res/inbox.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/info.svg b/res/info.svg
new file mode 100644
index 0000000..a09fa5f
--- /dev/null
+++ b/res/info.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/instagram.svg b/res/instagram.svg
new file mode 100644
index 0000000..9fdb8e3
--- /dev/null
+++ b/res/instagram.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/italic.svg b/res/italic.svg
new file mode 100644
index 0000000..a123d37
--- /dev/null
+++ b/res/italic.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/key.svg b/res/key.svg
new file mode 100644
index 0000000..e778e74
--- /dev/null
+++ b/res/key.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/layers.svg b/res/layers.svg
new file mode 100644
index 0000000..ea788c2
--- /dev/null
+++ b/res/layers.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/layout.svg b/res/layout.svg
new file mode 100644
index 0000000..28743d9
--- /dev/null
+++ b/res/layout.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/life-buoy.svg b/res/life-buoy.svg
new file mode 100644
index 0000000..54c2bd7
--- /dev/null
+++ b/res/life-buoy.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/link-2.svg b/res/link-2.svg
new file mode 100644
index 0000000..8cc7f6d
--- /dev/null
+++ b/res/link-2.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/link.svg b/res/link.svg
new file mode 100644
index 0000000..c89dd41
--- /dev/null
+++ b/res/link.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/linkedin.svg b/res/linkedin.svg
new file mode 100644
index 0000000..3953109
--- /dev/null
+++ b/res/linkedin.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/list.svg b/res/list.svg
new file mode 100644
index 0000000..5ce38ea
--- /dev/null
+++ b/res/list.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/loader.svg b/res/loader.svg
new file mode 100644
index 0000000..e1a70c1
--- /dev/null
+++ b/res/loader.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/lock.svg b/res/lock.svg
new file mode 100644
index 0000000..de09d9d
--- /dev/null
+++ b/res/lock.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/log-in.svg b/res/log-in.svg
new file mode 100644
index 0000000..ba0da59
--- /dev/null
+++ b/res/log-in.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/log-out.svg b/res/log-out.svg
new file mode 100644
index 0000000..c9002c9
--- /dev/null
+++ b/res/log-out.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/mail.svg b/res/mail.svg
new file mode 100644
index 0000000..2af169e
--- /dev/null
+++ b/res/mail.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/map-pin.svg b/res/map-pin.svg
new file mode 100644
index 0000000..d5548e9
--- /dev/null
+++ b/res/map-pin.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/map.svg b/res/map.svg
new file mode 100644
index 0000000..ecebd7b
--- /dev/null
+++ b/res/map.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/maximize-2.svg b/res/maximize-2.svg
new file mode 100644
index 0000000..e41fc0b
--- /dev/null
+++ b/res/maximize-2.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/maximize.svg b/res/maximize.svg
new file mode 100644
index 0000000..fc30518
--- /dev/null
+++ b/res/maximize.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/meh.svg b/res/meh.svg
new file mode 100644
index 0000000..6f57fff
--- /dev/null
+++ b/res/meh.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/menu.svg b/res/menu.svg
new file mode 100644
index 0000000..e8a84a9
--- /dev/null
+++ b/res/menu.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/message-circle.svg b/res/message-circle.svg
new file mode 100644
index 0000000..4b21b32
--- /dev/null
+++ b/res/message-circle.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/message-square.svg b/res/message-square.svg
new file mode 100644
index 0000000..6a2e4e5
--- /dev/null
+++ b/res/message-square.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/mic-off.svg b/res/mic-off.svg
new file mode 100644
index 0000000..0786219
--- /dev/null
+++ b/res/mic-off.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/mic.svg b/res/mic.svg
new file mode 100644
index 0000000..dc5f780
--- /dev/null
+++ b/res/mic.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/minimize-2.svg b/res/minimize-2.svg
new file mode 100644
index 0000000..a720fa6
--- /dev/null
+++ b/res/minimize-2.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/minimize.svg b/res/minimize.svg
new file mode 100644
index 0000000..46d6119
--- /dev/null
+++ b/res/minimize.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/minus-circle.svg b/res/minus-circle.svg
new file mode 100644
index 0000000..80c0de1
--- /dev/null
+++ b/res/minus-circle.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/minus-square.svg b/res/minus-square.svg
new file mode 100644
index 0000000..4862832
--- /dev/null
+++ b/res/minus-square.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/minus.svg b/res/minus.svg
new file mode 100644
index 0000000..93cc734
--- /dev/null
+++ b/res/minus.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/monitor.svg b/res/monitor.svg
new file mode 100644
index 0000000..6c3556d
--- /dev/null
+++ b/res/monitor.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/moon.svg b/res/moon.svg
new file mode 100644
index 0000000..dbf7c6c
--- /dev/null
+++ b/res/moon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/more-horizontal.svg b/res/more-horizontal.svg
new file mode 100644
index 0000000..dc6a855
--- /dev/null
+++ b/res/more-horizontal.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/more-vertical.svg b/res/more-vertical.svg
new file mode 100644
index 0000000..cba6958
--- /dev/null
+++ b/res/more-vertical.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/mouse-pointer.svg b/res/mouse-pointer.svg
new file mode 100644
index 0000000..f5af559
--- /dev/null
+++ b/res/mouse-pointer.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/move.svg b/res/move.svg
new file mode 100644
index 0000000..4e251b5
--- /dev/null
+++ b/res/move.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/music.svg b/res/music.svg
new file mode 100644
index 0000000..7bee2f7
--- /dev/null
+++ b/res/music.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/navigation-2.svg b/res/navigation-2.svg
new file mode 100644
index 0000000..ae31db9
--- /dev/null
+++ b/res/navigation-2.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/navigation.svg b/res/navigation.svg
new file mode 100644
index 0000000..f600a41
--- /dev/null
+++ b/res/navigation.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/octagon.svg b/res/octagon.svg
new file mode 100644
index 0000000..124c548
--- /dev/null
+++ b/res/octagon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/package.svg b/res/package.svg
new file mode 100644
index 0000000..f1e09ee
--- /dev/null
+++ b/res/package.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/paperclip.svg b/res/paperclip.svg
new file mode 100644
index 0000000..b1f69b7
--- /dev/null
+++ b/res/paperclip.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/pause-circle.svg b/res/pause-circle.svg
new file mode 100644
index 0000000..f6b1a8d
--- /dev/null
+++ b/res/pause-circle.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/pause.svg b/res/pause.svg
new file mode 100644
index 0000000..4e78038
--- /dev/null
+++ b/res/pause.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/pen-tool.svg b/res/pen-tool.svg
new file mode 100644
index 0000000..0d26fa1
--- /dev/null
+++ b/res/pen-tool.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/percent.svg b/res/percent.svg
new file mode 100644
index 0000000..2cb9719
--- /dev/null
+++ b/res/percent.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/phone-call.svg b/res/phone-call.svg
new file mode 100644
index 0000000..8b86660
--- /dev/null
+++ b/res/phone-call.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/phone-forwarded.svg b/res/phone-forwarded.svg
new file mode 100644
index 0000000..aa21bef
--- /dev/null
+++ b/res/phone-forwarded.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/phone-incoming.svg b/res/phone-incoming.svg
new file mode 100644
index 0000000..b2d523a
--- /dev/null
+++ b/res/phone-incoming.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/phone-missed.svg b/res/phone-missed.svg
new file mode 100644
index 0000000..4950f09
--- /dev/null
+++ b/res/phone-missed.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/phone-off.svg b/res/phone-off.svg
new file mode 100644
index 0000000..4d00fb3
--- /dev/null
+++ b/res/phone-off.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/phone-outgoing.svg b/res/phone-outgoing.svg
new file mode 100644
index 0000000..fea27a3
--- /dev/null
+++ b/res/phone-outgoing.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/phone.svg b/res/phone.svg
new file mode 100644
index 0000000..2a35154
--- /dev/null
+++ b/res/phone.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/pie-chart.svg b/res/pie-chart.svg
new file mode 100644
index 0000000..b5bbe67
--- /dev/null
+++ b/res/pie-chart.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/play-circle.svg b/res/play-circle.svg
new file mode 100644
index 0000000..8766dc7
--- /dev/null
+++ b/res/play-circle.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/play.svg b/res/play.svg
new file mode 100644
index 0000000..fd76e30
--- /dev/null
+++ b/res/play.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/plus-circle.svg b/res/plus-circle.svg
new file mode 100644
index 0000000..4291ff0
--- /dev/null
+++ b/res/plus-circle.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/plus-square.svg b/res/plus-square.svg
new file mode 100644
index 0000000..c380e24
--- /dev/null
+++ b/res/plus-square.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/plus.svg b/res/plus.svg
new file mode 100644
index 0000000..703c5b7
--- /dev/null
+++ b/res/plus.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/pocket.svg b/res/pocket.svg
new file mode 100644
index 0000000..a3b2561
--- /dev/null
+++ b/res/pocket.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/power.svg b/res/power.svg
new file mode 100644
index 0000000..598308f
--- /dev/null
+++ b/res/power.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/printer.svg b/res/printer.svg
new file mode 100644
index 0000000..8a9a7ac
--- /dev/null
+++ b/res/printer.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/radio.svg b/res/radio.svg
new file mode 100644
index 0000000..5abfcd1
--- /dev/null
+++ b/res/radio.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/refresh-ccw.svg b/res/refresh-ccw.svg
new file mode 100644
index 0000000..10cff0e
--- /dev/null
+++ b/res/refresh-ccw.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/refresh-cw.svg b/res/refresh-cw.svg
new file mode 100644
index 0000000..06c358d
--- /dev/null
+++ b/res/refresh-cw.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/repeat.svg b/res/repeat.svg
new file mode 100644
index 0000000..c7657b0
--- /dev/null
+++ b/res/repeat.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/rewind.svg b/res/rewind.svg
new file mode 100644
index 0000000..7b0fa3d
--- /dev/null
+++ b/res/rewind.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/rotate-ccw.svg b/res/rotate-ccw.svg
new file mode 100644
index 0000000..ade5dc4
--- /dev/null
+++ b/res/rotate-ccw.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/rotate-cw.svg b/res/rotate-cw.svg
new file mode 100644
index 0000000..83dca35
--- /dev/null
+++ b/res/rotate-cw.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/rss.svg b/res/rss.svg
new file mode 100644
index 0000000..c9a1368
--- /dev/null
+++ b/res/rss.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/saeter.jpg b/res/saeter.jpg
new file mode 100644
index 0000000..f5ded53
Binary files /dev/null and b/res/saeter.jpg differ
diff --git a/res/save.svg b/res/save.svg
new file mode 100644
index 0000000..46c7299
--- /dev/null
+++ b/res/save.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/scissors.svg b/res/scissors.svg
new file mode 100644
index 0000000..fd0647f
--- /dev/null
+++ b/res/scissors.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/search.svg b/res/search.svg
new file mode 100644
index 0000000..8710306
--- /dev/null
+++ b/res/search.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/send.svg b/res/send.svg
new file mode 100644
index 0000000..42ef2a2
--- /dev/null
+++ b/res/send.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/server.svg b/res/server.svg
new file mode 100644
index 0000000..54ce094
--- /dev/null
+++ b/res/server.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/settings.svg b/res/settings.svg
new file mode 100644
index 0000000..19c2726
--- /dev/null
+++ b/res/settings.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/share-2.svg b/res/share-2.svg
new file mode 100644
index 0000000..09b1c7b
--- /dev/null
+++ b/res/share-2.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/share.svg b/res/share.svg
new file mode 100644
index 0000000..df38c14
--- /dev/null
+++ b/res/share.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/shield-off.svg b/res/shield-off.svg
new file mode 100644
index 0000000..18692dd
--- /dev/null
+++ b/res/shield-off.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/shield.svg b/res/shield.svg
new file mode 100644
index 0000000..c7c4841
--- /dev/null
+++ b/res/shield.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/shopping-bag.svg b/res/shopping-bag.svg
new file mode 100644
index 0000000..eaa39e8
--- /dev/null
+++ b/res/shopping-bag.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/shopping-cart.svg b/res/shopping-cart.svg
new file mode 100644
index 0000000..17a40bf
--- /dev/null
+++ b/res/shopping-cart.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/shuffle.svg b/res/shuffle.svg
new file mode 100644
index 0000000..8cfb5db
--- /dev/null
+++ b/res/shuffle.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/sidebar.svg b/res/sidebar.svg
new file mode 100644
index 0000000..8ba817e
--- /dev/null
+++ b/res/sidebar.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/skip-back.svg b/res/skip-back.svg
new file mode 100644
index 0000000..88d024e
--- /dev/null
+++ b/res/skip-back.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/skip-forward.svg b/res/skip-forward.svg
new file mode 100644
index 0000000..f3fdac3
--- /dev/null
+++ b/res/skip-forward.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/slack.svg b/res/slack.svg
new file mode 100644
index 0000000..5d97346
--- /dev/null
+++ b/res/slack.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/slash.svg b/res/slash.svg
new file mode 100644
index 0000000..f4131b8
--- /dev/null
+++ b/res/slash.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/sliders.svg b/res/sliders.svg
new file mode 100644
index 0000000..19c9385
--- /dev/null
+++ b/res/sliders.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/smartphone.svg b/res/smartphone.svg
new file mode 100644
index 0000000..0171a95
--- /dev/null
+++ b/res/smartphone.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/smile.svg b/res/smile.svg
new file mode 100644
index 0000000..24dc8a2
--- /dev/null
+++ b/res/smile.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/speaker.svg b/res/speaker.svg
new file mode 100644
index 0000000..75d5ff9
--- /dev/null
+++ b/res/speaker.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/square.svg b/res/square.svg
new file mode 100644
index 0000000..6eabc77
--- /dev/null
+++ b/res/square.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/star.svg b/res/star.svg
new file mode 100644
index 0000000..bcdc31a
--- /dev/null
+++ b/res/star.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/stop-circle.svg b/res/stop-circle.svg
new file mode 100644
index 0000000..c10d9d4
--- /dev/null
+++ b/res/stop-circle.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/sun.svg b/res/sun.svg
new file mode 100644
index 0000000..7f51b94
--- /dev/null
+++ b/res/sun.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/sunrise.svg b/res/sunrise.svg
new file mode 100644
index 0000000..eff4b1e
--- /dev/null
+++ b/res/sunrise.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/sunset.svg b/res/sunset.svg
new file mode 100644
index 0000000..a5a2221
--- /dev/null
+++ b/res/sunset.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/tablet.svg b/res/tablet.svg
new file mode 100644
index 0000000..9c80b40
--- /dev/null
+++ b/res/tablet.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/tag.svg b/res/tag.svg
new file mode 100644
index 0000000..7219b15
--- /dev/null
+++ b/res/tag.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/target.svg b/res/target.svg
new file mode 100644
index 0000000..be84b17
--- /dev/null
+++ b/res/target.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/terminal.svg b/res/terminal.svg
new file mode 100644
index 0000000..af459c0
--- /dev/null
+++ b/res/terminal.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/thermometer.svg b/res/thermometer.svg
new file mode 100644
index 0000000..33142cc
--- /dev/null
+++ b/res/thermometer.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/thumbs-down.svg b/res/thumbs-down.svg
new file mode 100644
index 0000000..3e7bcd6
--- /dev/null
+++ b/res/thumbs-down.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/thumbs-up.svg b/res/thumbs-up.svg
new file mode 100644
index 0000000..226c44d
--- /dev/null
+++ b/res/thumbs-up.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/toggle-left.svg b/res/toggle-left.svg
new file mode 100644
index 0000000..240be29
--- /dev/null
+++ b/res/toggle-left.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/toggle-right.svg b/res/toggle-right.svg
new file mode 100644
index 0000000..fc6e81c
--- /dev/null
+++ b/res/toggle-right.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/tool.svg b/res/tool.svg
new file mode 100644
index 0000000..f3cbf3d
--- /dev/null
+++ b/res/tool.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/trash-2.svg b/res/trash-2.svg
new file mode 100644
index 0000000..f24d55b
--- /dev/null
+++ b/res/trash-2.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/trash.svg b/res/trash.svg
new file mode 100644
index 0000000..55650bd
--- /dev/null
+++ b/res/trash.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/trello.svg b/res/trello.svg
new file mode 100644
index 0000000..b2f599b
--- /dev/null
+++ b/res/trello.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/trending-down.svg b/res/trending-down.svg
new file mode 100644
index 0000000..a9d4cfa
--- /dev/null
+++ b/res/trending-down.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/trending-up.svg b/res/trending-up.svg
new file mode 100644
index 0000000..52026a4
--- /dev/null
+++ b/res/trending-up.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/triangle.svg b/res/triangle.svg
new file mode 100644
index 0000000..274b652
--- /dev/null
+++ b/res/triangle.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/truck.svg b/res/truck.svg
new file mode 100644
index 0000000..3389837
--- /dev/null
+++ b/res/truck.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/tv.svg b/res/tv.svg
new file mode 100644
index 0000000..955bbff
--- /dev/null
+++ b/res/tv.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/twitch.svg b/res/twitch.svg
new file mode 100644
index 0000000..1706249
--- /dev/null
+++ b/res/twitch.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/twitter.svg b/res/twitter.svg
new file mode 100644
index 0000000..f8886ec
--- /dev/null
+++ b/res/twitter.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/type.svg b/res/type.svg
new file mode 100644
index 0000000..c6b2de3
--- /dev/null
+++ b/res/type.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/umbrella.svg b/res/umbrella.svg
new file mode 100644
index 0000000..dc77c0c
--- /dev/null
+++ b/res/umbrella.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/underline.svg b/res/underline.svg
new file mode 100644
index 0000000..044945d
--- /dev/null
+++ b/res/underline.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/unlock.svg b/res/unlock.svg
new file mode 100644
index 0000000..01dc359
--- /dev/null
+++ b/res/unlock.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/upload-cloud.svg b/res/upload-cloud.svg
new file mode 100644
index 0000000..a1db297
--- /dev/null
+++ b/res/upload-cloud.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/upload.svg b/res/upload.svg
new file mode 100644
index 0000000..91eaff7
--- /dev/null
+++ b/res/upload.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/user-check.svg b/res/user-check.svg
new file mode 100644
index 0000000..42f91b2
--- /dev/null
+++ b/res/user-check.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/user-minus.svg b/res/user-minus.svg
new file mode 100644
index 0000000..44b75f5
--- /dev/null
+++ b/res/user-minus.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/user-plus.svg b/res/user-plus.svg
new file mode 100644
index 0000000..21460f6
--- /dev/null
+++ b/res/user-plus.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/user-x.svg b/res/user-x.svg
new file mode 100644
index 0000000..0c41a48
--- /dev/null
+++ b/res/user-x.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/user.svg b/res/user.svg
new file mode 100644
index 0000000..7bb5f29
--- /dev/null
+++ b/res/user.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/users.svg b/res/users.svg
new file mode 100644
index 0000000..aacf6b0
--- /dev/null
+++ b/res/users.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/video-off.svg b/res/video-off.svg
new file mode 100644
index 0000000..08ec697
--- /dev/null
+++ b/res/video-off.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/video.svg b/res/video.svg
new file mode 100644
index 0000000..8ff156a
--- /dev/null
+++ b/res/video.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/voicemail.svg b/res/voicemail.svg
new file mode 100644
index 0000000..5d78a8e
--- /dev/null
+++ b/res/voicemail.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/volume-1.svg b/res/volume-1.svg
new file mode 100644
index 0000000..150e875
--- /dev/null
+++ b/res/volume-1.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/volume-2.svg b/res/volume-2.svg
new file mode 100644
index 0000000..03d521c
--- /dev/null
+++ b/res/volume-2.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/volume-x.svg b/res/volume-x.svg
new file mode 100644
index 0000000..be44240
--- /dev/null
+++ b/res/volume-x.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/volume.svg b/res/volume.svg
new file mode 100644
index 0000000..53bfe15
--- /dev/null
+++ b/res/volume.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/watch.svg b/res/watch.svg
new file mode 100644
index 0000000..a1099da
--- /dev/null
+++ b/res/watch.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/wifi-off.svg b/res/wifi-off.svg
new file mode 100644
index 0000000..35eae43
--- /dev/null
+++ b/res/wifi-off.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/wifi.svg b/res/wifi.svg
new file mode 100644
index 0000000..748c285
--- /dev/null
+++ b/res/wifi.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/wind.svg b/res/wind.svg
new file mode 100644
index 0000000..82b3646
--- /dev/null
+++ b/res/wind.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/x-circle.svg b/res/x-circle.svg
new file mode 100644
index 0000000..94aad5e
--- /dev/null
+++ b/res/x-circle.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/x-octagon.svg b/res/x-octagon.svg
new file mode 100644
index 0000000..8543198
--- /dev/null
+++ b/res/x-octagon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/x-square.svg b/res/x-square.svg
new file mode 100644
index 0000000..7677c38
--- /dev/null
+++ b/res/x-square.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/x.svg b/res/x.svg
new file mode 100644
index 0000000..7d5875c
--- /dev/null
+++ b/res/x.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/youtube.svg b/res/youtube.svg
new file mode 100644
index 0000000..c482438
--- /dev/null
+++ b/res/youtube.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/zap-off.svg b/res/zap-off.svg
new file mode 100644
index 0000000..c636f8b
--- /dev/null
+++ b/res/zap-off.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/zap.svg b/res/zap.svg
new file mode 100644
index 0000000..8fdafa9
--- /dev/null
+++ b/res/zap.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/zoom-in.svg b/res/zoom-in.svg
new file mode 100644
index 0000000..da4572d
--- /dev/null
+++ b/res/zoom-in.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/res/zoom-out.svg b/res/zoom-out.svg
new file mode 100644
index 0000000..fd678d7
--- /dev/null
+++ b/res/zoom-out.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources.qrc b/resources.qrc
new file mode 100644
index 0000000..529b574
--- /dev/null
+++ b/resources.qrc
@@ -0,0 +1,290 @@
+
+
+ res/activity.svg
+ res/airplay.svg
+ res/alert-circle.svg
+ res/alert-octagon.svg
+ res/alert-triangle.svg
+ res/align-center.svg
+ res/align-justify.svg
+ res/align-left.svg
+ res/align-right.svg
+ res/anchor.svg
+ res/aperture.svg
+ res/archive.svg
+ res/arrow-down.svg
+ res/arrow-down-circle.svg
+ res/arrow-down-left.svg
+ res/arrow-down-right.svg
+ res/arrow-left.svg
+ res/arrow-left-circle.svg
+ res/arrow-right.svg
+ res/arrow-right-circle.svg
+ res/arrow-up.svg
+ res/arrow-up-circle.svg
+ res/arrow-up-left.svg
+ res/arrow-up-right.svg
+ res/at-sign.svg
+ res/award.svg
+ res/bar-chart.svg
+ res/bar-chart-2.svg
+ res/battery.svg
+ res/battery-charging.svg
+ res/bell.svg
+ res/bell-off.svg
+ res/bluetooth.svg
+ res/bold.svg
+ res/book.svg
+ res/bookmark.svg
+ res/book-open.svg
+ res/box.svg
+ res/briefcase.svg
+ res/calendar.svg
+ res/camera.svg
+ res/camera-off.svg
+ res/cast.svg
+ res/check.svg
+ res/check-circle.svg
+ res/check-square.svg
+ res/chevron-down.svg
+ res/chevron-left.svg
+ res/chevron-right.svg
+ res/chevrons-down.svg
+ res/chevrons-left.svg
+ res/chevrons-right.svg
+ res/chevrons-up.svg
+ res/chevron-up.svg
+ res/chrome.svg
+ res/circle.svg
+ res/clipboard.svg
+ res/clock.svg
+ res/cloud.svg
+ res/cloud-drizzle.svg
+ res/cloud-lightning.svg
+ res/cloud-off.svg
+ res/cloud-rain.svg
+ res/cloud-snow.svg
+ res/code.svg
+ res/codepen.svg
+ res/codesandbox.svg
+ res/coffee.svg
+ res/columns.svg
+ res/command.svg
+ res/compass.svg
+ res/copy.svg
+ res/corner-down-left.svg
+ res/corner-down-right.svg
+ res/corner-left-down.svg
+ res/corner-left-up.svg
+ res/corner-right-down.svg
+ res/corner-right-up.svg
+ res/corner-up-left.svg
+ res/corner-up-right.svg
+ res/cpu.svg
+ res/credit-card.svg
+ res/crop.svg
+ res/crosshair.svg
+ res/database.svg
+ res/delete.svg
+ res/disc.svg
+ res/divide.svg
+ res/divide-circle.svg
+ res/divide-square.svg
+ res/dollar-sign.svg
+ res/download.svg
+ res/download-cloud.svg
+ res/dribbble.svg
+ res/droplet.svg
+ res/edit.svg
+ res/edit-2.svg
+ res/edit-3.svg
+ res/external-link.svg
+ res/eye.svg
+ res/eye-off.svg
+ res/facebook.svg
+ res/fast-forward.svg
+ res/feather.svg
+ res/figma.svg
+ res/file.svg
+ res/file-minus.svg
+ res/file-plus.svg
+ res/file-text.svg
+ res/film.svg
+ res/filter.svg
+ res/flag.svg
+ res/folder.svg
+ res/folder-minus.svg
+ res/folder-plus.svg
+ res/framer.svg
+ res/frown.svg
+ res/gift.svg
+ res/git-branch.svg
+ res/git-commit.svg
+ res/github.svg
+ res/gitlab.svg
+ res/git-merge.svg
+ res/git-pull-request.svg
+ res/globe.svg
+ res/grid.svg
+ res/hard-drive.svg
+ res/hash.svg
+ res/headphones.svg
+ res/heart.svg
+ res/help-circle.svg
+ res/hexagon.svg
+ res/home.svg
+ res/image.svg
+ res/inbox.svg
+ res/info.svg
+ res/instagram.svg
+ res/italic.svg
+ res/key.svg
+ res/layers.svg
+ res/layout.svg
+ res/life-buoy.svg
+ res/link.svg
+ res/link-2.svg
+ res/linkedin.svg
+ res/list.svg
+ res/loader.svg
+ res/lock.svg
+ res/log-in.svg
+ res/log-out.svg
+ res/mail.svg
+ res/map.svg
+ res/map-pin.svg
+ res/maximize.svg
+ res/maximize-2.svg
+ res/meh.svg
+ res/menu.svg
+ res/message-circle.svg
+ res/message-square.svg
+ res/mic.svg
+ res/mic-off.svg
+ res/minimize.svg
+ res/minimize-2.svg
+ res/minus.svg
+ res/minus-circle.svg
+ res/minus-square.svg
+ res/monitor.svg
+ res/moon.svg
+ res/more-horizontal.svg
+ res/more-vertical.svg
+ res/mouse-pointer.svg
+ res/move.svg
+ res/music.svg
+ res/navigation.svg
+ res/navigation-2.svg
+ res/octagon.svg
+ res/package.svg
+ res/paperclip.svg
+ res/pause.svg
+ res/pause-circle.svg
+ res/pen-tool.svg
+ res/percent.svg
+ res/phone.svg
+ res/phone-call.svg
+ res/phone-forwarded.svg
+ res/phone-incoming.svg
+ res/phone-missed.svg
+ res/phone-off.svg
+ res/phone-outgoing.svg
+ res/pie-chart.svg
+ res/play.svg
+ res/play-circle.svg
+ res/plus.svg
+ res/plus-circle.svg
+ res/plus-square.svg
+ res/pocket.svg
+ res/power.svg
+ res/printer.svg
+ res/radio.svg
+ res/refresh-ccw.svg
+ res/refresh-cw.svg
+ res/repeat.svg
+ res/rewind.svg
+ res/rotate-ccw.svg
+ res/rotate-cw.svg
+ res/rss.svg
+ res/save.svg
+ res/scissors.svg
+ res/search.svg
+ res/send.svg
+ res/server.svg
+ res/settings.svg
+ res/share.svg
+ res/share-2.svg
+ res/shield.svg
+ res/shield-off.svg
+ res/shopping-bag.svg
+ res/shopping-cart.svg
+ res/shuffle.svg
+ res/sidebar.svg
+ res/skip-back.svg
+ res/skip-forward.svg
+ res/slack.svg
+ res/slash.svg
+ res/sliders.svg
+ res/smartphone.svg
+ res/smile.svg
+ res/speaker.svg
+ res/square.svg
+ res/star.svg
+ res/stop-circle.svg
+ res/sun.svg
+ res/sunrise.svg
+ res/sunset.svg
+ res/tablet.svg
+ res/tag.svg
+ res/target.svg
+ res/terminal.svg
+ res/thermometer.svg
+ res/thumbs-down.svg
+ res/thumbs-up.svg
+ res/toggle-left.svg
+ res/toggle-right.svg
+ res/tool.svg
+ res/trash.svg
+ res/trash-2.svg
+ res/trello.svg
+ res/trending-down.svg
+ res/trending-up.svg
+ res/triangle.svg
+ res/truck.svg
+ res/tv.svg
+ res/twitch.svg
+ res/twitter.svg
+ res/type.svg
+ res/umbrella.svg
+ res/underline.svg
+ res/unlock.svg
+ res/upload.svg
+ res/upload-cloud.svg
+ res/user.svg
+ res/user-check.svg
+ res/user-minus.svg
+ res/user-plus.svg
+ res/users.svg
+ res/user-x.svg
+ res/video.svg
+ res/video-off.svg
+ res/voicemail.svg
+ res/volume.svg
+ res/volume-1.svg
+ res/volume-2.svg
+ res/volume-x.svg
+ res/watch.svg
+ res/wifi.svg
+ res/wifi-off.svg
+ res/wind.svg
+ res/x.svg
+ res/x-circle.svg
+ res/x-octagon.svg
+ res/x-square.svg
+ res/youtube.svg
+ res/zap.svg
+ res/zap-off.svg
+ res/zoom-in.svg
+ res/zoom-out.svg
+
+
diff --git a/src/core/arbeidshest.cpp b/src/core/arbeidshest.cpp
new file mode 100644
index 0000000..40f6c44
--- /dev/null
+++ b/src/core/arbeidshest.cpp
@@ -0,0 +1,110 @@
+#include "arbeidshest.h"
+
+ArbeidsHest::ArbeidsHest(QObject *parent) : QThread(parent) {
+ millisekunder = 1000; // Standardverdi for tidtaging
+
+ QCoreApplication::setOrganizationName("Arctic Software");
+ QCoreApplication::setOrganizationDomain("arcticsoftware.no");
+ QCoreApplication::setApplicationName("Saeterprosjekt");
+}
+
+void ArbeidsHest::setTidTaging(int millisekunder) {
+ this->millisekunder = millisekunder;
+}
+
+int ArbeidsHest::getTidTaging() {
+ return millisekunder;
+}
+
+void ArbeidsHest::trinn() {
+ QSettings settings;
+ // Reserver plass i minnet for prosjekter som passer kriteriet å sjekke for varsling
+ ProsjektKartotek gyldigeProsjekterVarsleStart, gyldigeProsjekterVarsleSlutt;
+ // Hent varselterskel kondisjoner fra innstillinger
+ int kondisjonGul = settings.value("yellowcondition").toInt();
+ int kondisjonRod = settings.value("redcondition").toInt();
+
+ // Gå igjennom alle lagrede prosjekter og putt prosjekter som passer i kartotek som er reservert tidligere
+ for (int i = 0; i < prosjektKartotek->size(); ++i) {
+ if (prosjektKartotek->at(i).value("active").toBool()
+ && !prosjektKartotek->at(i).value("ferdig").toBool()) {
+ if (prosjektKartotek->at(i).value("varslestart").toBool())
+ gyldigeProsjekterVarsleStart.append(prosjektKartotek->at(i));
+
+ if (prosjektKartotek->at(i).value("varsleslutt").toBool())
+ gyldigeProsjekterVarsleSlutt.append(prosjektKartotek->at(i));
+ }
+ }
+
+ for (int i = 0; i < gyldigeProsjekterVarsleStart.size(); ++i) {
+ quint64 prosjektStart = gyldigeProsjekterVarsleStart.at(i).value("prosjektstart").toULongLong();
+ int antallDognVarsel = gyldigeProsjekterVarsleStart.at(i).value("dognvarselstart").toInt();
+ quint64 antallDognVarselEpoch = antallDognVarsel * 24 * 60 * 60 * 1000;
+ int antallTimerVarsel = gyldigeProsjekterVarsleStart.at(i).value("timervarselstart").toInt();
+ quint64 antallTimerVarselEpoch = antallTimerVarsel * 60 * 60 * 1000;
+ quint64 gronnVarsel = antallDognVarselEpoch + antallTimerVarselEpoch;
+ quint64 gulVarsel = gronnVarsel - (gronnVarsel / 100 * kondisjonGul);
+ quint64 rodVarsel = gronnVarsel - (gronnVarsel / 100 * kondisjonRod);
+ quint64 now = QDateTime::currentMSecsSinceEpoch();
+ if (now >= prosjektStart - gronnVarsel) {
+ if (!gyldigeProsjekterVarsleStart.at(i).contains("varsletgronnstart")) {
+ KundeFil fil = gyldigeProsjekterVarsleStart.at(i);
+ fil.insert("varsletgronnstart", true);
+ emit alert(fil, AlertConditions::CONDITION_GREEN, AlertTypes::START);
+ }
+ } else if (now >= prosjektStart - gulVarsel) {
+ if (!gyldigeProsjekterVarsleStart.at(i).contains("varsletgulstart")) {
+ KundeFil fil = gyldigeProsjekterVarsleStart.at(i);
+ fil.insert("varsletgulstart", true);
+ emit alert(fil, AlertConditions::CONDITION_YELLOW, AlertTypes::START);
+ }
+ } else if (now >= prosjektStart - rodVarsel) {
+ if (!gyldigeProsjekterVarsleStart.at(i).contains("varsletrodstart")) {
+ KundeFil fil = gyldigeProsjekterVarsleStart.at(i);
+ fil.insert("varsletrodstart", true);
+ emit alert(fil, AlertConditions::CONDITION_RED, AlertTypes::START);
+ }
+ }
+ }
+
+ for (int i = 0; i < gyldigeProsjekterVarsleSlutt.size(); ++i) {
+ quint64 prosjektSlutt = gyldigeProsjekterVarsleSlutt.at(i).value("prosjektslutt").toULongLong();
+ int antallDognVarsel = gyldigeProsjekterVarsleSlutt.at(i).value("dognvarselslutt").toInt();
+ quint64 antallDognVarselEpoch = antallDognVarsel * 24 * 60 * 60 * 1000;
+ int antallTimerVarsel = gyldigeProsjekterVarsleSlutt.at(i).value("timervarselslutt").toInt();
+ quint64 antallTimerVarselEpoch = antallTimerVarsel * 60 * 60 * 1000;
+ quint64 gronnVarsel = antallDognVarselEpoch + antallTimerVarselEpoch;
+ quint64 gulVarsel = gronnVarsel - (gronnVarsel / 100 * kondisjonGul);
+ quint64 rodVarsel = gronnVarsel - (gronnVarsel / 100 * kondisjonRod);
+ quint64 now = QDateTime::currentMSecsSinceEpoch();
+ if (now >= prosjektSlutt - gronnVarsel) {
+ if (!gyldigeProsjekterVarsleSlutt.at(i).contains("varsletgronnslutt")) {
+ KundeFil fil = gyldigeProsjekterVarsleSlutt.at(i);
+ fil.insert("varsletgronnslutt", true);
+ emit alert(fil, AlertConditions::CONDITION_GREEN, AlertTypes::SLUTT);
+ }
+ } else if (now >= prosjektSlutt - gulVarsel) {
+ if (!gyldigeProsjekterVarsleSlutt.at(i).contains("varsletgulslutt")) {
+ KundeFil fil = gyldigeProsjekterVarsleSlutt.at(i);
+ fil.insert("varsletgulslutt", true);
+ emit alert(fil, AlertConditions::CONDITION_YELLOW, AlertTypes::SLUTT);
+ }
+ } else if (now >= prosjektSlutt - rodVarsel) {
+ if (!gyldigeProsjekterVarsleSlutt.at(i).contains("varsletrodslutt")) {
+ KundeFil fil = gyldigeProsjekterVarsleSlutt.at(i);
+ fil.insert("varsletrodslutt", true);
+ emit alert(fil, AlertConditions::CONDITION_RED, AlertTypes::SLUTT);
+ }
+ }
+ }
+}
+
+void ArbeidsHest::run() {
+ QTimer *tidTaging = new QTimer(this);
+ connect(tidTaging, SIGNAL(timeout()), this, SLOT(trinn()));
+ tidTaging->start(millisekunder);
+}
+
+void ArbeidsHest::settProsjekt(ProsjektKartotek &kartotek) {
+ prosjektKartotek = &kartotek;
+}
diff --git a/src/core/arbeidshest.h b/src/core/arbeidshest.h
new file mode 100644
index 0000000..a09ed12
--- /dev/null
+++ b/src/core/arbeidshest.h
@@ -0,0 +1,33 @@
+#ifndef ARBEIDSHEST_H
+#define ARBEIDSHEST_H
+
+#include
+#include
+#include
+#include "datatypes.h"
+
+class ArbeidsHest : public QThread
+{
+ Q_OBJECT
+
+public:
+ explicit ArbeidsHest(QObject *parent = nullptr);
+
+ void setTidTaging(int millisekunder);
+ int getTidTaging();
+ void run();
+
+ void settProsjekt(ProsjektKartotek &kartotek);
+
+signals:
+ void alert(ProsjektFil prosjekt, AlertConditions condition, AlertTypes type);
+
+private slots:
+ void trinn();
+
+private:
+ int millisekunder;
+ ProsjektKartotek *prosjektKartotek;
+};
+
+#endif // ARBEIDSHEST_H
diff --git a/src/core/core.pro b/src/core/core.pro
new file mode 100644
index 0000000..c1a111f
--- /dev/null
+++ b/src/core/core.pro
@@ -0,0 +1,65 @@
+QT += core gui
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+CONFIG += c++11
+
+# You can make your code fail to compile if it uses deprecated APIs.
+# In order to do so, uncomment the following line.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += \
+ $$PWD/main.cpp \
+ $$PWD/mainwindow.cpp \
+ arbeidshest.cpp \
+ datahandler.cpp \
+ datatypes.cpp \
+ globals.cpp \
+ innstillingdialog.cpp \
+ kundewidget.cpp \
+ nykundedialog.cpp \
+ nyttprosjektdialog.cpp \
+ omdialog.cpp \
+ prosjektwidget.cpp \
+ redigerkundedialog.cpp \
+ redigerprosjektdialog.cpp \
+ varsledialog.cpp \
+ velgkundeprosjektdialog.cpp
+
+HEADERS += \
+ $$PWD/mainwindow.h \
+ arbeidshest.h \
+ datahandler.h \
+ datatypes.h \
+ globals.h \
+ innstillingdialog.h \
+ kundewidget.h \
+ nykundedialog.h \
+ nyttprosjektdialog.h \
+ omdialog.h \
+ prosjektwidget.h \
+ redigerkundedialog.h \
+ redigerprosjektdialog.h \
+ varsledialog.h \
+ velgkundeprosjektdialog.h
+
+FORMS += \
+ $$PWD/mainwindow.ui \
+ innstillingdialog.ui \
+ kundewidget.ui \
+ nykundedialog.ui \
+ nyttprosjektdialog.ui \
+ omdialog.ui \
+ prosjektwidget.ui \
+ redigerkundedialog.ui \
+ redigerprosjektdialog.ui \
+ varsledialog.ui \
+ velgkundeprosjektdialog.ui
+
+# Default rules for deployment.
+qnx: target.path = /tmp/$${TARGET}/bin
+else: unix:!android: target.path = /opt/$${TARGET}/bin
+!isEmpty(target.path): INSTALLS += target
+
+RESOURCES += \
+ $$PWD/../../resources.qrc
diff --git a/src/core/datahandler.cpp b/src/core/datahandler.cpp
new file mode 100644
index 0000000..37e5701
--- /dev/null
+++ b/src/core/datahandler.cpp
@@ -0,0 +1,72 @@
+#include "datahandler.h"
+
+DataHandler::DataHandler(QObject *parent) : QObject(parent) {
+ errorState = false;
+}
+
+bool DataHandler::lagreFil(QString filSti, KundeKartotek &kartotek, ProsjektKartotek &pKartotek, ProsjektBindinger &bindinger) {
+ QFile fil(filSti);
+ if (!fil.open(QIODevice::WriteOnly)) {
+ errorState = true;
+ errorCode = ErrorCodes::SKRIVEFEIL;
+ return false;
+ }
+
+ QDataStream ut(&fil);
+ ut.setVersion(QDataStream::Qt_5_9);
+ ut << APPLIKASJON_STEMPEL;
+ ut << APP_VERSJON;
+ ut << DB_VERSJON;
+ ut << kartotek;
+ ut << pKartotek;
+ ut << bindinger;
+ fil.flush();
+ fil.close();
+
+ return true;
+}
+
+bool DataHandler::lastFil(QString filSti, KundeKartotek &kartotek, ProsjektKartotek &pKartotek, ProsjektBindinger &bindinger) {
+ QFile fil(filSti);
+ if (!fil.open(QIODevice::ReadOnly)) {
+ errorState = true;
+ errorCode = ErrorCodes::LESEFEIL;
+ return false;
+ }
+
+ QDataStream inn(&fil);
+ inn.setVersion(QDataStream::Qt_5_9);
+ quint64 kontrollStempel;
+ qreal appVersjon, dbVersjon;
+
+ inn >> kontrollStempel;
+ inn >> appVersjon;
+ inn >> dbVersjon;
+
+ if (kontrollStempel != APPLIKASJON_STEMPEL) {
+ errorState = true;
+ errorCode = ErrorCodes::UGYLDIG_FIL;
+ return false;
+ } else if (appVersjon != APP_VERSJON) {
+
+ } else if (dbVersjon != DB_VERSJON) {
+ errorState = true;
+ errorCode = ErrorCodes::DB_VERSJONSKONFLIKT;
+ return false;
+ }
+
+ inn >> kartotek;
+ inn >> pKartotek;
+ inn >> bindinger;
+ fil.close();
+
+ return true;
+}
+
+bool DataHandler::hasError() {
+ return errorState;
+}
+
+ErrorCodes DataHandler::getError() {
+ return errorCode;
+}
diff --git a/src/core/datahandler.h b/src/core/datahandler.h
new file mode 100644
index 0000000..1ce084d
--- /dev/null
+++ b/src/core/datahandler.h
@@ -0,0 +1,29 @@
+#ifndef DATAHANDLER_H
+#define DATAHANDLER_H
+
+#include
+
+#include "datatypes.h"
+#include "globals.h"
+
+typedef QList kundeFil;
+
+class DataHandler : public QObject
+{
+ Q_OBJECT
+public:
+ explicit DataHandler(QObject *parent = nullptr);
+ bool lagreFil(QString filSti, KundeKartotek &kartotek, ProsjektKartotek &pKartotek, ProsjektBindinger &bindinger);
+ bool lastFil(QString filSti, KundeKartotek &kartotek, ProsjektKartotek &pKartotek, ProsjektBindinger &bindinger);
+
+ bool hasError();
+ ErrorCodes getError();
+
+signals:
+
+private:
+ bool errorState;
+ ErrorCodes errorCode;
+};
+
+#endif // DATAHANDLER_H
diff --git a/src/core/datatypes.cpp b/src/core/datatypes.cpp
new file mode 100644
index 0000000..4ea3020
--- /dev/null
+++ b/src/core/datatypes.cpp
@@ -0,0 +1 @@
+#include "datatypes.h"
diff --git a/src/core/datatypes.h b/src/core/datatypes.h
new file mode 100644
index 0000000..b5b867b
--- /dev/null
+++ b/src/core/datatypes.h
@@ -0,0 +1,34 @@
+#ifndef DATATYPES_H
+#define DATATYPES_H
+
+#include
+#include
+
+typedef QList> KundeKartotek;
+typedef QHash KundeFil;
+
+typedef QList> ProsjektKartotek;
+typedef QHash ProsjektFil;
+
+typedef QHash> ProsjektBindinger;
+
+enum ErrorCodes {
+ APP_VERSJONSKONFLIKT,
+ DB_VERSJONSKONFLIKT,
+ UGYLDIG_FIL,
+ LESEFEIL,
+ SKRIVEFEIL
+};
+
+enum AlertConditions {
+ CONDITION_GREEN,
+ CONDITION_YELLOW,
+ CONDITION_RED
+};
+
+enum AlertTypes {
+ START,
+ SLUTT
+};
+
+#endif // DATATYPES_H
diff --git a/src/core/globals.cpp b/src/core/globals.cpp
new file mode 100644
index 0000000..da4df05
--- /dev/null
+++ b/src/core/globals.cpp
@@ -0,0 +1,5 @@
+#include "globals.h"
+
+qreal APP_VERSJON = 0.1;
+qreal DB_VERSJON = 0.1;
+quint64 APPLIKASJON_STEMPEL = (quint64)0xc4b351957b3bcf8;
diff --git a/src/core/globals.h b/src/core/globals.h
new file mode 100644
index 0000000..50d4637
--- /dev/null
+++ b/src/core/globals.h
@@ -0,0 +1,10 @@
+#ifndef GLOBALS_H
+#define GLOBALS_H
+
+#include
+
+extern qreal APP_VERSJON;
+extern qreal DB_VERSJON;
+extern quint64 APPLIKASJON_STEMPEL;
+
+#endif // GLOBALS_H
diff --git a/src/core/innstillingdialog.cpp b/src/core/innstillingdialog.cpp
new file mode 100644
index 0000000..2ac8e09
--- /dev/null
+++ b/src/core/innstillingdialog.cpp
@@ -0,0 +1,55 @@
+#include "innstillingdialog.h"
+#include "ui_innstillingdialog.h"
+
+InnstillingDialog::InnstillingDialog(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::InnstillingDialog) {
+ ui->setupUi(this);
+
+ QCoreApplication::setOrganizationName("Arctic Software");
+ QCoreApplication::setOrganizationDomain("arcticsoftware.no");
+ QCoreApplication::setApplicationName("Saeterprosjekt");
+
+ QSettings settings;
+
+ if (!settings.contains("yellowcondition")) {
+ settings.setValue("yellowcondition", 50);
+ }
+
+ if (!settings.contains("redcondition")) {
+ settings.setValue("redcondition", 90);
+ }
+
+ ui->dialGul->setValue(settings.value("yellowcondition").toInt());
+ ui->dialRod->setValue(settings.value("redcondition").toInt());
+
+ ui->labelGulVerdi->setText(tr("%1% av tiden gått før kondisjon").arg(settings.value("yellowcondition").toString()));
+ ui->labelRodVerdi->setText(tr("%1% av tiden gått før kondisjon").arg(settings.value("redcondition").toString()));
+}
+
+InnstillingDialog::~InnstillingDialog() {
+ delete ui;
+}
+
+void InnstillingDialog::on_dialGul_sliderMoved(int position) {
+ ui->labelGulVerdi->setText(tr("%1% av tiden gått før kondisjon").arg(QString::number(position)));
+}
+
+
+void InnstillingDialog::on_dialRod_sliderMoved(int position) {
+ ui->labelRodVerdi->setText(tr("%1% av tiden gått før kondisjon").arg(QString::number(position)));
+}
+
+
+void InnstillingDialog::on_pushAvbryt_clicked() {
+ QDialog::close();
+}
+
+
+void InnstillingDialog::on_pushLagre_clicked() {
+ QSettings settings;
+ settings.setValue("yellowcondition", ui->dialGul->value());
+ settings.setValue("redcondition", ui->dialRod->value());
+ QDialog::close();
+}
+
diff --git a/src/core/innstillingdialog.h b/src/core/innstillingdialog.h
new file mode 100644
index 0000000..3fc6800
--- /dev/null
+++ b/src/core/innstillingdialog.h
@@ -0,0 +1,33 @@
+#ifndef INNSTILLINGDIALOG_H
+#define INNSTILLINGDIALOG_H
+
+#include
+#include
+#include
+
+namespace Ui {
+class InnstillingDialog;
+}
+
+class InnstillingDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit InnstillingDialog(QWidget *parent = nullptr);
+ ~InnstillingDialog();
+
+private slots:
+ void on_dialGul_sliderMoved(int position);
+
+ void on_dialRod_sliderMoved(int position);
+
+ void on_pushAvbryt_clicked();
+
+ void on_pushLagre_clicked();
+
+private:
+ Ui::InnstillingDialog *ui;
+};
+
+#endif // INNSTILLINGDIALOG_H
diff --git a/src/core/innstillingdialog.ui b/src/core/innstillingdialog.ui
new file mode 100644
index 0000000..891fc16
--- /dev/null
+++ b/src/core/innstillingdialog.ui
@@ -0,0 +1,186 @@
+
+
+ InnstillingDialog
+
+
+
+ 0
+ 0
+ 446
+ 335
+
+
+
+ Juster innstillinger for Sæterprosjekt
+
+
+ -
+
+
+
+ 10
+ 75
+ true
+
+
+
+ Innstillinger for kondisjons terskler
+
+
+ true
+
+
+
-
+
+
-
+
+
+
+ 8
+ 75
+ true
+
+
+
+ Kondisjon gul:
+
+
+ Qt::PlainText
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ 1
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+
+ 10
+ 50
+ false
+
+
+
+ % igjen av varslingstid
+
+
+ Qt::AlignCenter
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 8
+ 75
+ true
+
+
+
+ Kondisjon rød:
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ 1
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+
+ 10
+ 50
+ false
+
+
+
+ % igjen av varslingstid
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Avbryt
+
+
+
+ -
+
+
+ Lagre
+
+
+ true
+
+
+
+
+
+
+
+
+
+
diff --git a/src/core/kundewidget.cpp b/src/core/kundewidget.cpp
new file mode 100644
index 0000000..5d31bad
--- /dev/null
+++ b/src/core/kundewidget.cpp
@@ -0,0 +1,94 @@
+#include "kundewidget.h"
+#include "ui_kundewidget.h"
+
+KundeWidget::KundeWidget(QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::KundeWidget) {
+ ui->setupUi(this);
+}
+
+KundeWidget::~KundeWidget() {
+ delete ui;
+}
+
+void KundeWidget::lagKundeTabell(KundeKartotek &kundeKart) {
+ ui->kundeTabell->clear();
+
+ connect(ui->kundeTabell, SIGNAL(itemClicked(QTableWidgetItem*)), this, SLOT(celleKlikk(QTableWidgetItem*)));
+
+ // Sett aktive poster i et eget kartotek
+ KundeKartotek aktivKartotek;
+ for (int i = 0; i < kundeKart.size(); ++i) {
+ if (kundeKart.at(i).value("active").toBool()) {
+ aktivKartotek << kundeKart.at(i);
+ }
+ }
+
+ QStringList overskrifter;
+ overskrifter << "Kundenummer" << "Fornavn" << "Etternavn" << "Firmanavn" <<"Telefonnr" <<"Epostadresse";
+ ui->kundeTabell->setRowCount(aktivKartotek.size());
+ ui->kundeTabell->setColumnCount(6);
+ ui->kundeTabell->setHorizontalHeaderLabels(overskrifter);
+
+ for (int i = 0; i < aktivKartotek.size(); ++i) {
+ QTableWidgetItem *kundeID = new QTableWidgetItem(aktivKartotek.at(i).value("id").toString());
+ kundeID->setFlags(kundeID->flags() ^ Qt::ItemIsEditable);
+ kundeID->setData(Qt::UserRole, i);
+
+ QTableWidgetItem *fornavn = new QTableWidgetItem(aktivKartotek.at(i).value("fornavn").toString());
+ fornavn->setFlags(fornavn->flags() ^ Qt::ItemIsEditable);
+ fornavn->setData(Qt::UserRole, i);
+
+ QTableWidgetItem *etternavn = new QTableWidgetItem(aktivKartotek.at(i).value("etternavn").toString());
+ etternavn->setFlags(etternavn->flags() ^ Qt::ItemIsEditable);
+ etternavn->setData(Qt::UserRole, i);
+
+ QTableWidgetItem *firmanavn = new QTableWidgetItem(aktivKartotek.at(i).value("firmanavn").toString());
+ firmanavn->setFlags(firmanavn->flags() ^ Qt::ItemIsEditable);
+ firmanavn->setData(Qt::UserRole, i);
+
+ QTableWidgetItem *telefon = new QTableWidgetItem(aktivKartotek.at(i).value("tlf").toString());
+ telefon->setFlags(telefon->flags() ^ Qt::ItemIsEditable);
+ telefon->setData(Qt::UserRole, i);
+
+ QTableWidgetItem *epost = new QTableWidgetItem(aktivKartotek.at(i).value("epost").toString());
+ epost->setFlags(epost->flags() ^ Qt::ItemIsEditable);
+ epost->setData(Qt::UserRole, i);
+
+ ui->kundeTabell->setItem(i, 0, kundeID);
+ ui->kundeTabell->setItem(i, 1, fornavn);
+ ui->kundeTabell->setItem(i, 2, etternavn);
+ ui->kundeTabell->setItem(i, 3, firmanavn);
+ ui->kundeTabell->setItem(i, 4, telefon);
+ ui->kundeTabell->setItem(i, 5, epost);
+ }
+}
+
+void KundeWidget::on_pushNyKunde_clicked() {
+ emit opprettKunde();
+}
+
+void KundeWidget::on_pushRediger_clicked() {
+ emit redigerKunde(kundeKortID);
+}
+
+void KundeWidget::celleKlikk(QTableWidgetItem *celleGjenstand) {
+ kundeKortID = celleGjenstand->data(Qt::UserRole).toInt();
+ int kundeNummer = kundeKortID + 1;
+
+ ui->pushRediger->setEnabled(true);
+ ui->pushSlett->setEnabled(true);
+ ui->pushProsjekt->setEnabled(true);
+
+ ui->labelValgteKundeVerdi->setText(tr("kundenr. %1").arg(QString::number(kundeNummer)));
+}
+
+void KundeWidget::on_pushSlett_clicked() {
+ emit slettKunde(kundeKortID);
+}
+
+
+void KundeWidget::on_pushProsjekt_clicked() {
+ emit tilordneProsjekt(kundeKortID);
+}
+
diff --git a/src/core/kundewidget.h b/src/core/kundewidget.h
new file mode 100644
index 0000000..58912f7
--- /dev/null
+++ b/src/core/kundewidget.h
@@ -0,0 +1,42 @@
+#ifndef KUNDEWIDGET_H
+#define KUNDEWIDGET_H
+
+#include
+#include
+
+#include "datahandler.h"
+#include "datatypes.h"
+
+namespace Ui {
+class KundeWidget;
+}
+
+class KundeWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit KundeWidget(QWidget *parent = nullptr);
+ ~KundeWidget();
+
+ void lagKundeTabell(KundeKartotek &kundeKart);
+
+signals:
+ void opprettKunde();
+ void redigerKunde(int posisjon);
+ void slettKunde(int posisjon);
+ void tilordneProsjekt(int posisjon);
+
+private slots:
+ void on_pushNyKunde_clicked();
+ void celleKlikk(QTableWidgetItem *celleGjenstand);
+ void on_pushRediger_clicked();
+ void on_pushSlett_clicked();
+ void on_pushProsjekt_clicked();
+
+private:
+ Ui::KundeWidget *ui;
+ int kundeKortID;
+};
+
+#endif // KUNDEWIDGET_H
diff --git a/src/core/kundewidget.ui b/src/core/kundewidget.ui
new file mode 100644
index 0000000..0c06bfd
--- /dev/null
+++ b/src/core/kundewidget.ui
@@ -0,0 +1,189 @@
+
+
+ KundeWidget
+
+
+
+ 0
+ 0
+ 543
+ 499
+
+
+
+ Form
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 12
+ 75
+ true
+
+
+
+ Kundeliste
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
+ false
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 75
+ true
+
+
+
+ Valgte kunde:
+
+
+
+ -
+
+
+ Ingen kunde valgt
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Ny kunde
+
+
+
+ -
+
+
+ false
+
+
+ Rediger kunde
+
+
+
+ -
+
+
+ false
+
+
+ Slett kunde
+
+
+
+ -
+
+
+ false
+
+
+ Tilordne prosjekt
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/core/main.cpp b/src/core/main.cpp
new file mode 100644
index 0000000..d08ca40
--- /dev/null
+++ b/src/core/main.cpp
@@ -0,0 +1,10 @@
+#include "mainwindow.h"
+
+#include
+
+int main(int argc, char *argv[]) {
+ QApplication a(argc, argv);
+ MainWindow w;
+ w.show();
+ return a.exec();
+}
diff --git a/src/core/mainwindow.cpp b/src/core/mainwindow.cpp
new file mode 100644
index 0000000..c574751
--- /dev/null
+++ b/src/core/mainwindow.cpp
@@ -0,0 +1,693 @@
+#include "mainwindow.h"
+#include "ui_mainwindow.h"
+
+MainWindow::MainWindow(QWidget *parent)
+ : QMainWindow(parent)
+ , ui(new Ui::MainWindow) {
+ ui->setupUi(this);
+
+ ioHandler = new DataHandler(this);
+ harFil = false;
+ kListe = false;
+ pListe = false;
+ prosjekter = false;
+ utlop = false;
+ oppdaterUI();
+
+ innstillingDlg = new InnstillingDialog(this);
+ connect(innstillingDlg, SIGNAL(rejected()), this, SLOT(barnDialogLukket()));
+
+ hest = new ArbeidsHest(this);
+}
+
+MainWindow::~MainWindow() {
+ delete ui;
+}
+
+/* on_actionNy_triggered():
+ * ------------------------
+ *
+ * Lag en ny databasefil
+ */
+
+void MainWindow::on_actionNy_triggered() {
+ // konstruer stien ved hjelp av QFileDialog
+ filSti = QFileDialog::getSaveFileName(this, "Opprett ny databasefil", "/", "Database fil (*.saeter)");
+ // invokerer lagreFil fra DataHandler klassen der alle IO funksjoner ligger, kontroller om vi kan skrive til filen
+ if (!ioHandler->lagreFil(filSti, kundeKart, prosjektKart, bindinger)) {
+ ErrorCodes error = ioHandler->getError();
+ switch (error) {
+ case ErrorCodes::SKRIVEFEIL:
+ QMessageBox::critical(this, "Feil oppstod", "Kan ikke opprette databasefilen. Kontroller at du har skriverettigheter der du har oppgitt stedet på harddisken.");
+ break;
+ default:
+ break;
+ }
+ } else {
+ // Oppdaterer diverse brytere i klassen for å reflektere endringer i programmet
+ harFil = true;
+ filLagret = true;
+ oppdaterTittel();
+ oppdaterUI();
+
+ delete hest;
+ hest = new ArbeidsHest(this);
+
+ connect(hest, SIGNAL(alert(ProsjektFil,AlertConditions, AlertTypes)), this, SLOT(varsle(ProsjektFil,AlertCondition, AlertTypes)));
+
+ hest->setTidTaging(1000);
+ hest->settProsjekt(prosjektKart);
+ hest->run();
+ }
+}
+
+/* on_action_pne_triggered():
+ * --------------------------
+ *
+ * Åpne en ny databasefil
+ */
+
+void MainWindow::on_action_pne_triggered() {
+ // konstruer stien ved hjelp av QFileDialog
+ filSti = QFileDialog::getOpenFileName(this, "Åpne databasefil", "/", "Database fil (*.saeter)");
+ // invokerer lastFil fra DataHandler klassen der alle IO funksjoner ligger
+ if (!ioHandler->lastFil(filSti, kundeKart, prosjektKart, bindinger)) {
+ ErrorCodes error = ioHandler->getError();
+ switch (error) {
+ case ErrorCodes::UGYLDIG_FIL:
+ QMessageBox::critical(this, "Feil oppstod", "Dette ser ikke ut til å være en gyldig sæterprosjekt databasefil");
+ break;
+ case ErrorCodes::APP_VERSJONSKONFLIKT:
+ QMessageBox::critical(this, "Feil oppstod", "Versjonskonflikt i programmet. Sjekk hjemmesiden for programvareoppdateringer før du prøver å åpne denne filen");
+ break;
+ case ErrorCodes::DB_VERSJONSKONFLIKT:
+ QMessageBox::critical(this, "Feil oppstod", "Versjonskonflikt i databasefilen. Filen du prøver å åpne er enten en eldre eller nyere versjon av hva programmet er skrevet for å håndtere. Sjekk hjemmesiden for programvareoppdateringer før du prøver å åpne denne filen");
+ break;
+ case ErrorCodes::LESEFEIL:
+ QMessageBox::critical(this, "Feil oppstod", "Kunne ikke lese fra disken. Sjekk at du har de nødvenige rettighetene til katalogen og/eller filen før du åpner databasen");
+ break;
+ default:
+ break;
+ }
+
+ harFil = false;
+ filLagret = false;
+ } else { // hvis databasefilen kan åpnes, er alt fryd og gammen. Hvis ikke kan ikke denne filen brukes
+ // oppdater grensesnittet med antall kunder og prosjekter som er lagret i filen
+ oppdaterTellere();
+ // Oppdaterer diverse brytere i klassen for å reflektere endringer i programmet
+ harFil = true;
+ filLagret = true;
+
+ // Sjekk om kundekartoteket allerede er åpnet, hvis ikke trenger vi ikke å foreta oss noe. Hvis den er åpen må vi oppdatere tabellen
+ if (kListe) {
+ kundeW->lagKundeTabell(kundeKart);
+ } else if (pListe) { // Hvis prosjektkartoteket er åpen, oppdater dette grensesnittet
+ prosjektW->oppdaterProsjektListe(prosjektKart, bindinger, kundeKart);
+ }
+
+ delete hest;
+ hest = new ArbeidsHest(this);
+
+ connect(hest, SIGNAL(alert(ProsjektFil,AlertConditions,AlertTypes)), this, SLOT(varsle(ProsjektFil,AlertConditions,AlertTypes)));
+
+ hest->setTidTaging(1000);
+ hest->settProsjekt(prosjektKart);
+ hest->run();
+ }
+
+ // oppdater grensesnittet basert på de boolske verdiene i klassen
+ oppdaterTittel();
+ oppdaterUI();
+}
+
+/* oppdaterTittel():
+ * ------------------------
+ *
+ * Oppdaterer hoved dialogboksens tittel med eventuelt full sti til en allerede åpnet database.
+ * Hvis det er ulagrede endringer i databasen legges det til en stjerne (*) på slutten av tittelen
+ */
+
+void MainWindow::oppdaterTittel() {
+ if (harFil && filLagret) {
+ this->setWindowTitle(tr("Sæterprosjekt [%1]").arg(filSti));
+ } else if (harFil && !filLagret) {
+ this->setWindowTitle(tr("Sæterprosjekt [%1]*").arg(filSti));
+ } else {
+ this->setWindowTitle(tr("Sæterprosjekt"));
+ }
+}
+
+/* oppdaterUI():
+ * ------------------------
+ *
+ * Slår av/på UI elementer basert på hvorvidt vi har en åpnet og aktiv database i programmet, eller ikke
+ */
+
+void MainWindow::oppdaterUI() {
+ ui->commandCustomers->setEnabled(harFil);
+ ui->commandDeadlines->setEnabled(harFil);
+ ui->commandProsjekter->setEnabled(harFil);
+
+ ui->actionL_agre_som->setEnabled(harFil);
+ ui->actionLagre->setEnabled(harFil);
+}
+
+/* oppdaterTellere():
+ * ------------------------
+ *
+ * Itererer gjennom kunde og prosjektliste og teller aktive oppføringer og oppdaterer UI deretter
+ */
+
+void MainWindow::oppdaterTellere() {
+ ui->labelCustomerAmountValue->setText(QString::number(tellKunder()));
+ ui->labelProjectAmountValue->setText(QString::number(tellProsjekter()));
+
+}
+
+/* erstattProsjekt():
+ * ------------------------
+ *
+ * Erstatter eksisterende prosjektfil i kartoteket med argumentet prosjekt
+ */
+
+void MainWindow::erstattProsjekt(ProsjektFil prosjekt) {
+ for (int i = 0; i < prosjektKart.count(); ++i) {
+ if (prosjektKart.at(i).value("ordrenummer").toInt() == prosjekt.value("ordrenummer").toInt()) {
+ prosjektKart.replace(i, prosjekt);
+ }
+ }
+
+ filLagret = false;
+ oppdaterTittel();
+}
+
+/* tellKunder():
+ * ------------------------
+ *
+ * Teller antall aktive kunder i kartoteket og returnerer et siffer med antallet
+ */
+
+int MainWindow::tellKunder() {
+ int kunder = 0;
+
+ for (int i = 0; i < kundeKart.size(); ++i) {
+ bool aktiv = kundeKart.at(i).value("active").toBool();
+ if (aktiv)
+ kunder++;
+ }
+
+ return kunder;
+}
+
+/* tellProsjekter():
+ * ------------------------
+ *
+ * Teller antall aktive prosjekter i kartoteket og returnerer et siffer med antallet
+ */
+
+int MainWindow::tellProsjekter() {
+ int prosjekter = 0;
+
+ for (int i = 0; i < prosjektKart.size(); ++i) {
+ bool aktiv = prosjektKart.at(i).value("active").toBool();
+ if (aktiv)
+ prosjekter++;
+ }
+
+ return prosjekter;
+
+}
+
+/* on_action_Avslutt_triggered():
+ * ------------------------------
+ *
+ * Avslutter programmet
+ *
+ * TODO: Legg til en sjekk om det er noen ulagrede endringer før programmet avsluttes. Må også lage
+ * en event handler for vinduet i tilfelle brukeren trykker 'X' vindusknappen. En event handler
+ * kan lages ved å basere seg på den arvede prototypen til MainWindow
+ */
+
+void MainWindow::on_action_Avslutt_triggered() {
+ QApplication::quit();
+}
+
+/* on_commandCustomers_clicked():
+ * ------------------------------
+ *
+ * Setter inn kundeliste widgeten i hoved dialogboksen.
+ */
+
+void MainWindow::on_commandCustomers_clicked() {
+ if (!kListe) {
+ if (pListe) {
+ delete prosjektW;
+ pListe = false;
+ } else if (utlop) {
+
+ }
+
+ kundeW = new KundeWidget(this);
+
+ connect(kundeW, SIGNAL(opprettKunde()), this, SLOT(visNyKundeDlg()));
+ connect(kundeW, SIGNAL(redigerKunde(int)), this, SLOT(visRedigerKundeDlg(int)));
+ connect(kundeW, SIGNAL(slettKunde(int)), this, SLOT(slettKunde(int)));
+ connect(kundeW, SIGNAL(tilordneProsjekt(int)), this, SLOT(visProsjektListe(int)));
+
+ ui->hovedLayout->insertWidget(0, kundeW);
+ kundeW->lagKundeTabell(kundeKart);
+ kundeW->show();
+ kListe = true;
+ utlop = false;
+ }
+}
+
+/* on_commandProsjekter_clicked():
+ * -------------------------------
+ *
+ * Setter inn prosjektliste widgeten i hoved dialogboksen.
+ */
+
+void MainWindow::on_commandProsjekter_clicked() {
+ if (!pListe) {
+ if (kListe) {
+ delete kundeW;
+ kListe = false;
+ }
+
+ prosjektW = new ProsjektWidget(this);
+
+ connect(prosjektW, SIGNAL(opprettProsjekt()), this, SLOT(visNyttProsjektDlg()));
+ connect(prosjektW, SIGNAL(hentProsjektFil(int)), this, SLOT(sendProsjektFil(int)));
+ connect(prosjektW, SIGNAL(redigerProsjekt(int)), this, SLOT(visRedigerProsjektDialog(int)));
+ connect(prosjektW, SIGNAL(slettProsjekt(int)), this, SLOT(slettProsjekt(int)));
+ connect(prosjektW, SIGNAL(settAktiv(int)), this, SLOT(settAktivInaktiv(int)));
+ connect(prosjektW, SIGNAL(fjernKunde(int,int)), this, SLOT(fjernKundeFraProsjekt(int,int)));
+
+ ui->hovedLayout->insertWidget(0, prosjektW);
+ prosjektW->oppdaterProsjektListe(prosjektKart, bindinger, kundeKart);
+ prosjektW->show();
+ pListe = true;
+ }
+}
+
+/* visNyttProsjektDlg():
+ * -------------------------------
+ *
+ * Viser dialogboksen for å opprette et nytt prosjekt
+ */
+
+void MainWindow::visNyttProsjektDlg() {
+ nyProsjektDlg = new NyttProsjektDialog(this);
+
+ connect(nyProsjektDlg, SIGNAL(leggTilProsjekt(ProsjektFil)), this, SLOT(leggTilNyttProsjekt(ProsjektFil)));
+ connect(nyProsjektDlg, SIGNAL(rejected()), this, SLOT(barnDialogLukket()));
+
+ nyProsjektDlg->opprettOrdreNr(prosjektKart.size() + 1);
+ this->hide();
+ nyProsjektDlg->show();
+ nyProsjektDlg->setFocus();
+ nyProsjektDlg->activateWindow();
+ nyProsjektDlg->fokusStart();
+}
+
+/* leggTilNyttProsjekt():
+ * -------------------------------
+ *
+ * Lagre nytt prosjekt i prosjektarkivet og oppdater prosjektlisten
+ */
+
+void MainWindow::leggTilNyttProsjekt(ProsjektFil prosjekt) {
+ prosjektKart.append(prosjekt);
+ prosjektW->oppdaterProsjektListe(prosjektKart, bindinger, kundeKart);
+
+ oppdaterTellere();
+ nyProsjektDlg->close();
+ delete nyProsjektDlg;
+
+ filLagret = false;
+ oppdaterTittel();
+}
+
+/* sendProsjektFil():
+ * -------------------------------
+ *
+ * Innvokert av hentProsjektFil og henter en prosjektfil og sender den til prosjektwidgeten
+ */
+
+void MainWindow::sendProsjektFil(int kartotekPlassering) {
+ ProsjektFil aktivProsjekt = prosjektKart.at(kartotekPlassering);
+ prosjektW->settGjeldendeProsjekt(aktivProsjekt);
+}
+
+/* visRedigerProsjektDialog():
+ * -------------------------------
+ *
+ * Viser dialogboksen for å redigere et eksisterende prosjekt basert på indeksen i kartoteket
+ */
+
+void MainWindow::visRedigerProsjektDialog(int kartotekPlassering) {
+ ProsjektFil prosjekt = prosjektKart.at(kartotekPlassering);
+ redigerProsjektDlg = new RedigerProsjektDialog(this);
+
+ connect(redigerProsjektDlg, SIGNAL(lagreProsjekt(ProsjektFil)), this, SLOT(lagreProsjektEndringer(ProsjektFil)));
+ connect(redigerProsjektDlg, SIGNAL(rejected()), this, SLOT(barnDialogLukket()));
+
+ redigerProsjektDlg->settProsjektFil(prosjekt);
+ this->hide();
+ redigerProsjektDlg->show();
+ redigerProsjektDlg->setFocus();
+ redigerProsjektDlg->activateWindow();
+ redigerProsjektDlg->fokusStart();
+}
+
+/* visRedigerProsjektDialog():
+ * -------------------------------
+ *
+ * Lagre endringer i det redigerte prosjektet
+ */
+
+void MainWindow::lagreProsjektEndringer(ProsjektFil endringer) {
+ for (int i = 0; i < prosjektKart.size(); ++i) {
+ if (endringer.value("ordrenummer").toInt() == prosjektKart.at(i).value("ordrenummer").toInt()) {
+ prosjektKart.replace(i, endringer);
+ }
+ }
+
+ prosjektW->oppdaterProsjektListe(prosjektKart, bindinger, kundeKart);
+ filLagret = false;
+ oppdaterTittel();
+ redigerProsjektDlg->close();
+ delete redigerProsjektDlg;
+}
+
+
+/* slettProsjekt():
+ * -------------------------------
+ *
+ * Sletter et prosjekt fra kartoteket.
+ */
+
+void MainWindow::slettProsjekt(int kartotekPlassering) {
+ QMessageBox bekreftBoks;
+ bekreftBoks.setText("Er du sikker?");
+ bekreftBoks.setInformativeText("Vil du slette dette prosjektet? Kundene som eventuelt er tilknyttet prosjektet vil ikke bli slettet");
+ bekreftBoks.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
+ bekreftBoks.setDefaultButton(QMessageBox::Cancel);
+
+ int svar = bekreftBoks.exec();
+
+ switch (svar) {
+ case QMessageBox::Ok:
+ ProsjektFil prosjekt = prosjektKart.at(kartotekPlassering);
+ prosjekt.insert("active", false);
+ prosjektKart.replace(kartotekPlassering, prosjekt);
+ prosjektW->oppdaterProsjektListe(prosjektKart, bindinger, kundeKart);
+ filLagret = false;
+ oppdaterTittel();
+ oppdaterTellere();
+ break;
+ }
+}
+
+/* settAktivInaktiv():
+ * ------------------------------
+ *
+ * Setter et prosjekt som inaktivt (ferdig) hvis det er aktiv og motsatt
+ */
+
+void MainWindow::settAktivInaktiv(int kartotekPlassering) {
+ ProsjektFil prosjekt = prosjektKart.at(kartotekPlassering);
+ bool ferdig = prosjekt.value("ferdig").toBool();
+ if (ferdig)
+ prosjekt.insert("ferdig", false);
+ else
+ prosjekt.insert("ferdig", true);
+
+ prosjektKart.replace(kartotekPlassering, prosjekt);
+ prosjektW->oppdaterProsjektListe(prosjektKart, bindinger, kundeKart);
+ filLagret = false;
+ oppdaterTittel();
+}
+
+/* fjernKundeFraProsjekt():
+ * ------------------------------
+ *
+ * Sletter bindingene en kunde har mot det valgte prosjektet
+ */
+
+void MainWindow::fjernKundeFraProsjekt(int prosjektKartotekPosisjon, int kundeID) {
+ int prosjektID = prosjektKart.at(prosjektKartotekPosisjon).value("ordrenummer").toInt();
+ QList prosjektKundeListe = bindinger.value(prosjektID);
+ prosjektKundeListe.removeOne(kundeID);
+ bindinger[prosjektID] = prosjektKundeListe;
+
+ prosjektW->oppdaterProsjektListe(prosjektKart, bindinger, kundeKart);
+ filLagret = false;
+ oppdaterTittel();
+}
+
+/* varsle():
+ * ------------------------------
+ *
+ * Hvis et varsel er trigget av arbeidshesten, invokeres denne funksjonen
+ */
+
+void MainWindow::varsle(ProsjektFil prosjekt, AlertConditions kondisjon, AlertTypes type) {
+ erstattProsjekt(prosjekt);
+ varsleDlg = new VarsleDialog(this, kondisjon);
+ varsleDlg->settProsjektNavn(prosjekt.value("prosjektnavn").toString());
+ varsleDlg->settStart(prosjekt.value("prosjektstart").toULongLong());
+ varsleDlg->settSlutt(prosjekt.value("prosjektslutt").toULongLong());
+ varsleDlg->show();
+}
+
+/* visNyKundeDlg():
+ * ------------------------------
+ *
+ * Viser dialogboksen for å legge til en ny kunde
+ */
+
+void MainWindow::visNyKundeDlg() {
+ nyKdlg = new NyKundeDialog(this);
+
+ connect(nyKdlg, SIGNAL(leggTilKunde(KundeFil)), this, SLOT(settInnNyKunde(KundeFil)));
+ connect(nyKdlg, SIGNAL(rejected()), this, SLOT(barnDialogLukket()));
+
+ nyKdlg->nyKundeId(kundeKart.size() + 1);
+ this->hide();
+ nyKdlg->show();
+ nyKdlg->setFocus();
+ nyKdlg->activateWindow();
+ nyKdlg->startTopp();
+}
+
+/* visRedigerKundeDlg():
+ * ----------------------------------------------------------------------
+ * Argumenter: (int) posisjon - posisjonen i QListen der kunden er lagret
+ * ----------------------------------------------------------------------
+ *
+ * Viser dialogboksen for å redigere en kunde
+ */
+
+void MainWindow::visRedigerKundeDlg(int posisjon) {
+ redigerKdlg = new RedigerKundeDialog(this);
+
+ connect(redigerKdlg, SIGNAL(oppdaterKundeFil(KundeFil)), this, SLOT(redigerKunde(KundeFil)));
+ connect(redigerKdlg, SIGNAL(rejected()), this, SLOT(barnDialogLukket()));
+
+ this->hide();
+ redigerKdlg->show();
+ redigerKdlg->setFocus();
+ redigerKdlg->activateWindow();
+ redigerKdlg->settInnGamleVerdier(kundeKart.at(posisjon));
+}
+
+/* settInnNyKunde():
+ * ------------------------------
+ *
+ * Setter inn en ny kunde i kartoteket og oppdaterer tabellen i kundewidgeten
+ */
+
+
+void MainWindow::settInnNyKunde(KundeFil kunde) {
+ if (kunde.value("fornavn").toString().isEmpty()) {
+ QMessageBox::warning(this, "Kan ikke lagre kunde", "Fornavn feltet er påkrevd");
+ } else if (kunde.value("etternavn").toString().isEmpty()) {
+ QMessageBox::warning(this, "Kan ikke lagre kunde", "Etternavn feltet er påkrevd");
+ } else if (kunde.value("firmanavn").toString().isEmpty()) {
+ QMessageBox::warning(this, "Kan ikke lagre kunde", "Firmanavn feltet er påkrevd");
+ } else {
+ kundeKart.append(kunde);
+ oppdaterTellere();
+ kundeW->lagKundeTabell(kundeKart);
+ filLagret = false;
+ oppdaterTittel();
+ nyKdlg->close();
+ delete nyKdlg;
+ }
+}
+
+/* redigerKunde():
+ * ------------------------------
+ *
+ * Redigerer en eksisterende kunde i kartoteket og oppdaterer tabellen i kundewidgeten
+ */
+
+void MainWindow::redigerKunde(KundeFil redigertKunde) {
+ if (redigertKunde.value("fornavn").isNull()) {
+ QMessageBox::warning(this, "Kan ikke lagre kunde", "Fornavn feltet er påkrevd");
+ } else if (redigertKunde.value("etternavn").isNull()) {
+ QMessageBox::warning(this, "Kan ikke lagre kunde", "Etternavn feltet er påkrevd");
+ } else if (redigertKunde.value("firmanavn").isNull()) {
+ QMessageBox::warning(this, "Kan ikke lagre kunde", "Firmanavn feltet er påkrevd");
+ } else {
+ for (int i = 0; i < kundeKart.size(); ++i) {
+ if (kundeKart.at(i).value("id").toInt() == redigertKunde.value("id").toInt()) {
+ kundeKart.replace(i, redigertKunde);
+ }
+ }
+
+ kundeW->lagKundeTabell(kundeKart);
+ filLagret = false;
+ oppdaterTittel();
+ redigerKdlg->close();
+ delete redigerKdlg;
+ }
+}
+
+/* slettKunde():
+ * ------------------------------
+ *
+ * Sletter kunden fra databasen. MERK: Kunden blir ikke fysisk slettet, men blir satt til
+ * inaktiv for å bevare konsistensen og rekkefølgen i databasen, samt kundenummer sekvens
+ */
+
+void MainWindow::slettKunde(int posisjon) {
+ QMessageBox bekreftBoks;
+ bekreftBoks.setText("Er du sikker?");
+ bekreftBoks.setInformativeText("Vil du slette denne kunden? Prosjektdataene som eventuelt er tilknyttet, vil ikke bli slettet.");
+ bekreftBoks.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
+ bekreftBoks.setDefaultButton(QMessageBox::Cancel);
+
+ int svar = bekreftBoks.exec();
+
+ switch (svar) {
+ case QMessageBox::Ok:
+ kundeKart[posisjon].insert("active", false);
+ kundeW->lagKundeTabell(kundeKart);
+ filLagret = false;
+ oppdaterTittel();
+ oppdaterTellere();
+ break;
+ default:
+ break;
+ }
+}
+
+/* visProsjektListe():
+ * ------------------------------
+ *
+ * Åpner dialogboksen der brukeren kan tilordne kunden til et prosjekt
+ */
+
+
+void MainWindow::visProsjektListe(int posisjon) {
+ if (tellProsjekter() == 0) {
+ QMessageBox::warning(this, "Ugyldig operasjon", "Prosjektkartoteket inneholder ingen prosjekter. Du får ikke tilordnet noen kunder før du har opprettet et prosjekt!");
+ } else {
+ kundeProsjektDlg = new VelgKundeProsjektDialog(this);
+
+ connect(kundeProsjektDlg, SIGNAL(opprettBinding(int,int)), this, SLOT(knyttProsjekt(int,int)));
+ connect(kundeProsjektDlg, SIGNAL(rejected()), this, SLOT(barnDialogLukket()));
+
+ KundeFil kunde = kundeKart.at(posisjon);
+ int kundeID = kunde.value("id").toInt();
+ kundeProsjektDlg->settKundeID(kundeID);
+ kundeProsjektDlg->hentProsjekter(prosjektKart, bindinger);
+ this->hide();
+ kundeProsjektDlg->show();
+ kundeProsjektDlg->setFocus();
+ kundeProsjektDlg->activateWindow();
+ }
+}
+
+/* knyttProsjekt():
+ * ------------------------------
+ *
+ * Oppretter en relasjon mellom kunde og prosjekt
+ */
+
+void MainWindow::knyttProsjekt(int kunde, int prosjekt) {
+ QList kundeListe;
+ QList prosjektBindinger = bindinger.keys();
+ if (!prosjektBindinger.contains(prosjekt)) {
+ kundeListe.append(kunde);
+ bindinger.insert(prosjekt, kundeListe);
+ } else {
+ kundeListe = bindinger.value(prosjekt);
+ if (!kundeListe.contains(kunde)) {
+ kundeListe.append(kunde);
+ bindinger[prosjekt] = kundeListe;
+ }
+ }
+
+ kundeProsjektDlg->close();
+ delete kundeProsjektDlg;
+ filLagret = false;
+ oppdaterTittel();
+ QMessageBox::information(this, "Tilknyttet", tr("Kunde med kundenummer %1 er tilknyttet prosjekt med ordrenummer %2").arg(kunde).arg(prosjekt));
+}
+
+/* on_actionLagre_triggered():
+ * ------------------------------
+ *
+ * Lagrer endringer i databasen til fil
+ */
+
+void MainWindow::on_actionLagre_triggered() {
+ // invokerer lagreFil fra DataHandler klassen der alle IO funksjoner ligger
+ ioHandler->lagreFil(filSti, kundeKart, prosjektKart, bindinger);
+ // Oppdaterer diverse brytere i klassen for å reflektere endringer i programmet
+ harFil = true;
+ filLagret = true;
+ oppdaterTittel();
+ oppdaterUI();
+}
+
+/* on_action_Innstillinger_triggered():
+ * --------------------------------------
+ *
+ * Åpner innstillings dialogboksen
+ */
+
+void MainWindow::on_action_Innstillinger_triggered() {
+ this->hide();
+ innstillingDlg->show();
+}
+
+/* barnDialogLukket():
+ * --------------------------------------
+ *
+ * Denne funksjonen invokeres hver gang en underdialog lukkes
+ */
+
+void MainWindow::barnDialogLukket() {
+ this->show();
+}
+
+
+/* barnDialogLukket():
+ * --------------------------------------
+ *
+ * Denne funksjonen invokeres hver gang en underdialog lukkes
+ */
+
+void MainWindow::on_actionOm_triggered() {
+ om = new OmDialog(this);
+ om->setVersjon(APP_VERSJON);
+ connect(om, SIGNAL(rejected()), this, SLOT(barnDialogLukket()));
+ this->hide();
+ om->show();
+}
diff --git a/src/core/mainwindow.h b/src/core/mainwindow.h
new file mode 100644
index 0000000..fe29e2f
--- /dev/null
+++ b/src/core/mainwindow.h
@@ -0,0 +1,99 @@
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include
+#include
+#include
+
+#include "kundewidget.h"
+#include "prosjektwidget.h"
+#include "datahandler.h"
+#include "nykundedialog.h"
+#include "redigerkundedialog.h"
+#include "nyttprosjektdialog.h"
+#include "redigerprosjektdialog.h"
+#include "velgkundeprosjektdialog.h"
+#include "innstillingdialog.h"
+#include "arbeidshest.h"
+#include "varsledialog.h"
+#include "omdialog.h"
+
+QT_BEGIN_NAMESPACE
+namespace Ui { class MainWindow; }
+QT_END_NAMESPACE
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ MainWindow(QWidget *parent = nullptr);
+ ~MainWindow();
+
+private slots:
+
+ void on_actionNy_triggered();
+ void on_action_pne_triggered();
+ void on_action_Avslutt_triggered();
+ void on_actionLagre_triggered();
+ void on_action_Innstillinger_triggered();
+ void barnDialogLukket();
+
+ /* Kundeslots */
+ void on_commandCustomers_clicked();
+ void visNyKundeDlg();
+ void visRedigerKundeDlg(int posisjon);
+ void settInnNyKunde(KundeFil kunde);
+ void redigerKunde(KundeFil redigertKunde);
+ void slettKunde(int posisjon);
+ void visProsjektListe(int posisjon);
+ void knyttProsjekt(int kunde, int prosjekt);
+
+ /* Prosjektslots */
+ void on_commandProsjekter_clicked();
+ void visNyttProsjektDlg();
+ void leggTilNyttProsjekt(ProsjektFil prosjekt);
+ void sendProsjektFil(int kartotekPlassering);
+ void visRedigerProsjektDialog(int kartotekPlassering);
+ void lagreProsjektEndringer(ProsjektFil endringer);
+ void slettProsjekt(int kartotekPlassering);
+ void settAktivInaktiv(int kartotekPlassering);
+ void fjernKundeFraProsjekt(int prosjektKartotekPosisjon, int kundeID);
+
+ /* Arbeidshest slots */
+ void varsle(ProsjektFil prosjekt, AlertConditions kondisjon, AlertTypes type);
+
+ void on_actionOm_triggered();
+
+private:
+ Ui::MainWindow *ui;
+ KundeWidget *kundeW;
+ ProsjektWidget *prosjektW;
+ DataHandler *ioHandler;
+ NyKundeDialog *nyKdlg;
+ RedigerKundeDialog *redigerKdlg;
+ NyttProsjektDialog *nyProsjektDlg;
+ RedigerProsjektDialog *redigerProsjektDlg;
+ VelgKundeProsjektDialog *kundeProsjektDlg;
+ InnstillingDialog *innstillingDlg;
+ VarsleDialog *varsleDlg;
+ OmDialog *om;
+ ArbeidsHest *hest;
+
+ void oppdaterTittel();
+ void oppdaterUI();
+ void oppdaterTellere();
+ void erstattProsjekt(ProsjektFil prosjekt);
+ int tellKunder();
+ int tellProsjekter();
+
+ bool harFil, filLagret, kListe, prosjekter, utlop, pListe;
+ QString filSti;
+ // kundeFil kundeListe;
+ KundeFil kundeKort;
+ KundeKartotek kundeKart;
+ ProsjektFil prosjektKort;
+ ProsjektKartotek prosjektKart;
+ ProsjektBindinger bindinger;
+};
+#endif // MAINWINDOW_H
diff --git a/src/core/mainwindow.ui b/src/core/mainwindow.ui
new file mode 100644
index 0000000..a8de30a
--- /dev/null
+++ b/src/core/mainwindow.ui
@@ -0,0 +1,261 @@
+
+
+ MainWindow
+
+
+
+ 0
+ 0
+ 965
+ 627
+
+
+
+ Sæterprosjekt
+
+
+
+ -
+
+
-
+
+
+
+ 16
+ 75
+ true
+
+
+
+ Hovedmeny
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Kundeliste
+
+
+
+ :/res/user.svg:/res/user.svg
+
+
+
+ -
+
+
+ Prosjekter
+
+
+
+ :/res/clipboard.svg:/res/clipboard.svg
+
+
+
+ -
+
+
+ Utløpsdatoer
+
+
+
+ :/res/clock.svg:/res/clock.svg
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
-
+
+
-
+
+
+ Antall kunder i databasen:
+
+
+
+ -
+
+
+
+ 75
+ true
+
+
+
+ 0
+
+
+
+
+
+ -
+
+
-
+
+
+ Antall prosjekter i databasen:
+
+
+
+ -
+
+
+
+ 75
+ true
+
+
+
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Ny
+
+
+
+
+ &Lagre
+
+
+
+
+ L&agre som
+
+
+
+
+ &Avslutt ...
+
+
+
+
+ Om
+
+
+
+
+ &Åpne
+
+
+
+
+ &Innstillinger
+
+
+
+
+
+
+
+
diff --git a/src/core/nykundedialog.cpp b/src/core/nykundedialog.cpp
new file mode 100644
index 0000000..b135859
--- /dev/null
+++ b/src/core/nykundedialog.cpp
@@ -0,0 +1,45 @@
+#include "nykundedialog.h"
+#include "ui_nykundedialog.h"
+
+NyKundeDialog::NyKundeDialog(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::NyKundeDialog) {
+ ui->setupUi(this);
+
+ ui->lineTlf->setValidator(new QIntValidator(10000000, 99999999, this));
+ ui->linePostnr->setValidator(new QIntValidator(1000, 9999, this));
+}
+
+NyKundeDialog::~NyKundeDialog() {
+ delete ui;
+}
+
+void NyKundeDialog::startTopp() {
+ ui->lineFornavn->setFocus();
+}
+
+void NyKundeDialog::nyKundeId(quint64 id) {
+ ui->lineKundenummer->setText(QString::number(id));
+}
+
+void NyKundeDialog::on_pushAvbryt_clicked() {
+ QDialog::close();
+}
+
+
+void NyKundeDialog::on_pushButton_clicked() {
+ KundeFil nyKunde;
+ nyKunde.insert("fornavn", ui->lineFornavn->text());
+ nyKunde.insert("etternavn", ui->lineEtternavn->text());
+ nyKunde.insert("firmanavn", ui->lineFirmanavn->text());
+ nyKunde.insert("adresse", ui->lineGate->text());
+ nyKunde.insert("postnr", ui->linePostnr->text().toInt());
+ nyKunde.insert("sted", ui->lineSted->text());
+ nyKunde.insert("epost", ui->lineEpost->text());
+ nyKunde.insert("tlf", ui->lineTlf->text().toInt());
+ nyKunde.insert("id", ui->lineKundenummer->text().toInt());
+ nyKunde.insert("active", true);
+
+ emit leggTilKunde(nyKunde);
+}
+
diff --git a/src/core/nykundedialog.h b/src/core/nykundedialog.h
new file mode 100644
index 0000000..215b8bb
--- /dev/null
+++ b/src/core/nykundedialog.h
@@ -0,0 +1,34 @@
+#ifndef NYKUNDEDIALOG_H
+#define NYKUNDEDIALOG_H
+
+#include
+#include
+#include "datatypes.h"
+
+namespace Ui {
+class NyKundeDialog;
+}
+
+class NyKundeDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit NyKundeDialog(QWidget *parent = nullptr);
+ ~NyKundeDialog();
+
+ void startTopp();
+ void nyKundeId(quint64 id);
+
+signals:
+ void leggTilKunde(KundeFil kunde);
+
+private slots:
+ void on_pushAvbryt_clicked();
+ void on_pushButton_clicked();
+
+private:
+ Ui::NyKundeDialog *ui;
+};
+
+#endif // NYKUNDEDIALOG_H
diff --git a/src/core/nykundedialog.ui b/src/core/nykundedialog.ui
new file mode 100644
index 0000000..b87f255
--- /dev/null
+++ b/src/core/nykundedialog.ui
@@ -0,0 +1,249 @@
+
+
+ NyKundeDialog
+
+
+
+ 0
+ 0
+ 474
+ 358
+
+
+
+ Opprett ny kunde
+
+
+ -
+
+
-
+
+
-
+
+
+
+ 75
+ true
+
+
+
+ Fornavn:
+
+
+
+ -
+
+
+ -
+
+
+
+ 75
+ true
+
+
+
+ Etternavn:
+
+
+
+ -
+
+
+ -
+
+
+
+ 75
+ true
+
+
+
+ Firmanavn:
+
+
+
+ -
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
-
+
+
+
+ 75
+ true
+
+
+
+ Gateadresse:
+
+
+
+ -
+
+
+ -
+
+
+
+ 75
+ true
+
+
+
+ Postnr:
+
+
+
+ -
+
+
+ -
+
+
+
+ 75
+ true
+
+
+
+ Sted:
+
+
+
+ -
+
+
+ -
+
+
+
+ 75
+ true
+
+
+
+ Telefon:
+
+
+
+ -
+
+
+ -
+
+
+
+ 75
+ true
+
+
+
+ Epost:
+
+
+
+ -
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
-
+
+
+
+ 75
+ true
+
+
+
+ Kundenummer:
+
+
+
+ -
+
+
+ true
+
+
+ true
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Avbryt
+
+
+
+ -
+
+
+ Lagre
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/core/nyttprosjektdialog.cpp b/src/core/nyttprosjektdialog.cpp
new file mode 100644
index 0000000..9e4eb5e
--- /dev/null
+++ b/src/core/nyttprosjektdialog.cpp
@@ -0,0 +1,91 @@
+#include "nyttprosjektdialog.h"
+#include "ui_nyttprosjektdialog.h"
+
+NyttProsjektDialog::NyttProsjektDialog(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::NyttProsjektDialog) {
+ ui->setupUi(this);
+
+ QDateTime iDag = QDateTime::currentDateTime();
+ QDate dagensDato = iDag.date();
+
+ ui->dateStart->setMinimumDate(dagensDato);
+ ui->dateSlutt->setMinimumDate(dagensDato);
+}
+
+NyttProsjektDialog::~NyttProsjektDialog() {
+ delete ui;
+}
+
+void NyttProsjektDialog::opprettOrdreNr(int ordreNr) {
+ ui->lineOrdrenummer->setText(QString::number(ordreNr));
+}
+
+void NyttProsjektDialog::fokusStart() {
+ ui->lineProsjektNavn->setFocus();
+}
+
+void NyttProsjektDialog::on_pushAvbryt_clicked() {
+ QDialog::close();
+}
+
+
+void NyttProsjektDialog::on_pushLagre_clicked() {
+ ProsjektFil nyttProsjekt;
+
+ nyttProsjekt.insert("prosjektnavn", ui->lineProsjektNavn->text());
+ nyttProsjekt.insert("ordrenummer", ui->lineOrdrenummer->text().toInt());
+ nyttProsjekt.insert("prosjektbeskrivelse", ui->textEditProsjektBeskrivelse->toHtml());
+ nyttProsjekt.insert("varslestart", ui->checkVarsleStart->isChecked());
+ nyttProsjekt.insert("varsleslutt", ui->checkVarsleSlutt->isChecked());
+
+ QDateTime prosjektStartDato = ui->dateStart->dateTime();
+ quint64 mSekStart = prosjektStartDato.toMSecsSinceEpoch() + ui->timeStart->time().msecsSinceStartOfDay();
+
+ QDateTime prosjektSluttDato = ui->dateSlutt->dateTime();
+ quint64 mSekSlutt = prosjektSluttDato.toMSecsSinceEpoch() + ui->timeSlutt->time().msecsSinceStartOfDay();
+
+ nyttProsjekt.insert("prosjektstart", mSekStart);
+ nyttProsjekt.insert("prosjektslutt", mSekSlutt);
+
+ int dognVarselStart = ui->spinBoxAntallDognVarslingStart->value();
+ int timerVarselStart = ui->spinBoxTimerForStart->value();
+ quint64 epochVarselDognStart = dognVarselStart * 24 * 60 * 60 * 1000;
+ quint64 epochVarselTimerStart = timerVarselStart * 60 * 60 * 1000;
+ quint64 epochVarselStart = epochVarselDognStart + epochVarselTimerStart;
+
+ int dognVarselSlutt = ui->spinBoxAntallDognVarslingSlutt->value();
+ int timerVarselSlutt = ui->spinBoxTimerForSlutt->value();
+ quint64 epochVarselDognSlutt = dognVarselSlutt * 24 * 60 * 60 * 1000;
+ quint64 epochVarselTimerSlutt = timerVarselSlutt * 60 * 60 * 1000;
+ quint64 epochVarselSlutt = epochVarselDognSlutt + epochVarselTimerSlutt;
+
+ nyttProsjekt.insert("varselstart", epochVarselStart);
+ nyttProsjekt.insert("varselslutt", epochVarselSlutt);
+ nyttProsjekt.insert("dognvarselstart", ui->spinBoxAntallDognVarslingStart->value());
+ nyttProsjekt.insert("dognvarselslutt", ui->spinBoxAntallDognVarslingSlutt->value());
+ nyttProsjekt.insert("timervarselstart", ui->spinBoxTimerForStart->value());
+ nyttProsjekt.insert("timercarselslutt", ui->spinBoxTimerForSlutt->value());
+
+ nyttProsjekt.insert("active", true);
+ nyttProsjekt.insert("ferdig", false);
+
+ emit leggTilProsjekt(nyttProsjekt);
+}
+
+
+void NyttProsjektDialog::on_checkVarsleStart_clicked() {
+ endreVarselStatus();
+}
+
+
+void NyttProsjektDialog::on_checkVarsleSlutt_clicked() {
+ endreVarselStatus();
+}
+
+void NyttProsjektDialog::endreVarselStatus() {
+ ui->spinBoxAntallDognVarslingSlutt->setEnabled(ui->checkVarsleSlutt->isChecked());
+ ui->spinBoxTimerForSlutt->setEnabled(ui->checkVarsleSlutt->isChecked());
+ ui->spinBoxAntallDognVarslingStart->setEnabled(ui->checkVarsleStart->isChecked());
+ ui->spinBoxTimerForStart->setEnabled(ui->checkVarsleStart->isChecked());
+}
diff --git a/src/core/nyttprosjektdialog.h b/src/core/nyttprosjektdialog.h
new file mode 100644
index 0000000..cc7e75f
--- /dev/null
+++ b/src/core/nyttprosjektdialog.h
@@ -0,0 +1,37 @@
+#ifndef NYTTPROSJEKTDIALOG_H
+#define NYTTPROSJEKTDIALOG_H
+
+#include
+#include "datatypes.h"
+
+namespace Ui {
+class NyttProsjektDialog;
+}
+
+class NyttProsjektDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit NyttProsjektDialog(QWidget *parent = nullptr);
+ ~NyttProsjektDialog();
+
+ void opprettOrdreNr(int ordreNr);
+ void fokusStart();
+
+signals:
+ void leggTilProsjekt(ProsjektFil prosjekt);
+
+private slots:
+ void on_pushAvbryt_clicked();
+ void on_pushLagre_clicked();
+ void on_checkVarsleStart_clicked();
+ void on_checkVarsleSlutt_clicked();
+
+private:
+ Ui::NyttProsjektDialog *ui;
+
+ void endreVarselStatus();
+};
+
+#endif // NYTTPROSJEKTDIALOG_H
diff --git a/src/core/nyttprosjektdialog.ui b/src/core/nyttprosjektdialog.ui
new file mode 100644
index 0000000..fd1b8ca
--- /dev/null
+++ b/src/core/nyttprosjektdialog.ui
@@ -0,0 +1,735 @@
+
+
+ NyttProsjektDialog
+
+
+
+ 0
+ 0
+ 597
+ 518
+
+
+
+ Nytt Prosjekt
+
+
+ -
+
+
+
+ 10
+ 75
+ true
+
+
+
+ Prosjekt detaljer
+
+
+ true
+
+
+
-
+
+
-
+
+
+
+ 8
+ 75
+ true
+
+
+
+ Prosjekt navn:
+
+
+
+ -
+
+
+
+ 8
+ 50
+ false
+
+
+
+
+ -
+
+
+
+ 8
+ 75
+ true
+
+
+
+ Ordrenummer:
+
+
+
+ -
+
+
+
+ 8
+ 50
+ false
+
+
+
+ true
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 10
+ 75
+ true
+
+
+
+ Prosjektbeskrivelse
+
+
+ true
+
+
+
-
+
+
+
+ 10
+ 50
+ false
+
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 10
+ 75
+ true
+
+
+
+ Prosjekt start
+
+
+ true
+
+
+ false
+
+
+
-
+
+
-
+
+
-
+
+
+
+ 8
+ 75
+ true
+
+
+
+ Dato:
+
+
+
+ -
+
+
+
+ 8
+ 50
+ false
+
+
+
+
+
+
+ QDateTimeEdit::DaySection
+
+
+ true
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 8
+ 75
+ true
+
+
+
+ Klokken:
+
+
+
+ -
+
+
+
+ 8
+ 50
+ false
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
-
+
+
-
+
+
+
+ 8
+ 50
+ false
+
+
+
+ Slå på varsling
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 8
+ 75
+ true
+
+
+
+ Antall døgn:
+
+
+
+ -
+
+
+ false
+
+
+
+ 8
+ 50
+ false
+
+
+
+ 0
+
+
+ 365
+
+
+ 14
+
+
+
+ -
+
+
+
+ 8
+ 50
+ false
+
+
+
+ Før start
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+
+ 8
+ 75
+ true
+
+
+
+ Antall timer:
+
+
+
+ -
+
+
+ false
+
+
+
+ 8
+ 50
+ false
+
+
+
+ 24
+
+
+
+ -
+
+
+
+ 8
+ 50
+ false
+
+
+
+ Før start
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 10
+ 75
+ true
+
+
+
+ Prosjekt slutt
+
+
+ true
+
+
+ false
+
+
+
-
+
+
-
+
+
-
+
+
+
+ 8
+ 75
+ true
+
+
+
+ Dato:
+
+
+
+ -
+
+
+
+ 8
+ 50
+ false
+
+
+
+
+
+
+ QDateTimeEdit::DaySection
+
+
+ true
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 8
+ 75
+ true
+
+
+
+ Klokken:
+
+
+
+ -
+
+
+
+ 8
+ 50
+ false
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
-
+
+
-
+
+
+
+ 8
+ 50
+ false
+
+
+
+ Slå på varsling
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 8
+ 75
+ true
+
+
+
+ Antall døgn:
+
+
+
+ -
+
+
+ false
+
+
+
+ 8
+ 50
+ false
+
+
+
+ 0
+
+
+ 365
+
+
+ 14
+
+
+
+ -
+
+
+
+ 8
+ 50
+ false
+
+
+
+ Før slutt
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+
+ 8
+ 75
+ true
+
+
+
+ Antall timer:
+
+
+
+ -
+
+
+ false
+
+
+
+ 8
+ 50
+ false
+
+
+
+ 24
+
+
+
+ -
+
+
+
+ 8
+ 50
+ false
+
+
+
+ Før slutt
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Avbryt
+
+
+
+ -
+
+
+ Lagre
+
+
+ true
+
+
+
+
+
+
+
+
+
+
diff --git a/src/core/omdialog.cpp b/src/core/omdialog.cpp
new file mode 100644
index 0000000..6963cfc
--- /dev/null
+++ b/src/core/omdialog.cpp
@@ -0,0 +1,21 @@
+#include "omdialog.h"
+#include "ui_omdialog.h"
+
+OmDialog::OmDialog(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::OmDialog) {
+ ui->setupUi(this);
+}
+
+OmDialog::~OmDialog() {
+ delete ui;
+}
+
+void OmDialog::setVersjon(qreal versjon) {
+ ui->labelVersjon->setText(tr("Versjon %1").arg(versjon));
+}
+
+void OmDialog::on_pushOk_clicked() {
+ QDialog::close();
+}
+
diff --git a/src/core/omdialog.h b/src/core/omdialog.h
new file mode 100644
index 0000000..33a6a89
--- /dev/null
+++ b/src/core/omdialog.h
@@ -0,0 +1,27 @@
+#ifndef OMDIALOG_H
+#define OMDIALOG_H
+
+#include
+
+namespace Ui {
+class OmDialog;
+}
+
+class OmDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit OmDialog(QWidget *parent = nullptr);
+ ~OmDialog();
+
+ void setVersjon(qreal versjon);
+
+private slots:
+ void on_pushOk_clicked();
+
+private:
+ Ui::OmDialog *ui;
+};
+
+#endif // OMDIALOG_H
diff --git a/src/core/omdialog.ui b/src/core/omdialog.ui
new file mode 100644
index 0000000..be5341b
--- /dev/null
+++ b/src/core/omdialog.ui
@@ -0,0 +1,146 @@
+
+
+ OmDialog
+
+
+
+ 0
+ 0
+ 386
+ 257
+
+
+
+ Om dette programmet
+
+
+ -
+
+
-
+
+
+
+ 12
+ 75
+ true
+
+
+
+ <html><head/><body><p><span style=" font-size:18pt; font-weight:600; color:#ff0000;">Sæte</span><span style=" font-size:18pt; font-weight:600; color:#004add;">rp</span><span style=" font-size:18pt; font-weight:600; color:#ffffff;">r</span><span style=" font-size:18pt; font-weight:600; color:#004add;">os</span><span style=" font-size:18pt; font-weight:600; color:#ff0000;">jekt</span></p></body></html>
+
+
+ Qt::RichText
+
+
+ Qt::AlignHCenter|Qt::AlignTop
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 12
+
+
+
+ TextLabel
+
+
+ Qt::AlignHCenter|Qt::AlignTop
+
+
+
+
+
+ -
+
+
+
+ 75
+ true
+
+
+
+ Kopirett(c) av Helge-Mikael Nordgård
+
+
+ Qt::AlignHCenter|Qt::AlignTop
+
+
+
+ -
+
+
+ <html><head/><body><p>Dette programmet er kopibeskyttet og lisensiert under GPLv3 (GNU General Public License versjon 3). Programmet er åpen og fri kildekode og kan modifiseres og redistribueres under visse betingelser. </p><p><a href="https://www.gnu.org/licenses/gpl-3.0.html"><span style=" text-decoration: underline; color:#0000ff;">Du kan lese lisensen i sin helhet her.</span></a></p><p>For å laste ned kildekoden, nye utgivelser, rapportere bugs m.m. kan du besøke <a href="https://git.outlands.no/heno/Saeterprosjekt"><span style=" text-decoration: underline; color:#0000ff;">prosjektets hjemmeside</span></a>.</p></body></html>
+
+
+ Qt::RichText
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
+
+
+ true
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Ok
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/core/prosjektwidget.cpp b/src/core/prosjektwidget.cpp
new file mode 100644
index 0000000..317777f
--- /dev/null
+++ b/src/core/prosjektwidget.cpp
@@ -0,0 +1,138 @@
+#include "prosjektwidget.h"
+#include "ui_prosjektwidget.h"
+
+ProsjektWidget::ProsjektWidget(QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::ProsjektWidget) {
+ ui->setupUi(this);
+}
+
+ProsjektWidget::~ProsjektWidget() {
+ delete ui;
+}
+
+void ProsjektWidget::oppdaterProsjektListe(ProsjektKartotek &kartotek, ProsjektBindinger &bindinger, KundeKartotek &kundeKart) {
+ ui->prosjektTre->clear();
+ ui->prosjektTre->setColumnCount(1);
+
+ connect(ui->prosjektTre, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(gjenstandKlikk(QTreeWidgetItem*,int)));
+
+ QList prosjektListe;
+ QIcon prosjektIkon(":/res/clipboard.svg");
+ QIcon prosjektFerdigIkon(":/res/check.svg");
+ QIcon kundeIkon(":/res/user.svg");
+
+ for (int i = 0; i < kartotek.size(); ++i) {
+ bool aktiv = kartotek.at(i).value("active").toBool();
+ if (aktiv) {
+ bool ferdig = kartotek.at(i).value("ferdig").toBool();
+ QTreeWidgetItem *prosjektGjenstand = new QTreeWidgetItem(QTreeWidgetItem::Type);
+ prosjektGjenstand->setText(0, kartotek.at(i).value("prosjektnavn").toString());
+
+ if (ferdig)
+ prosjektGjenstand->setIcon(0,prosjektFerdigIkon);
+ else
+ prosjektGjenstand->setIcon(0, prosjektIkon);
+
+ int ordrenummer = kartotek.at(i).value("ordrenummer").toInt();
+ QList kundeGjenstander;
+ if (bindinger.contains(ordrenummer)) {
+ QList kunder = bindinger.value(ordrenummer);
+ for (int x = 0; x < kunder.size(); ++x) {
+ QString kundeFornavn, kundeEtternavn, kundeFirmanavn;
+ for (int z = 0; z < kundeKart.size(); ++z) {
+ if (kundeKart.at(z).value("id").toInt() == kunder.at(x)) {
+ kundeFornavn = kundeKart.at(z).value("fornavn").toString();
+ kundeEtternavn = kundeKart.at(z).value("etternavn").toString();
+ kundeFirmanavn = kundeKart.at(z).value("firmanavn").toString();
+ }
+ }
+ QTreeWidgetItem *kunde = new QTreeWidgetItem(QTreeWidgetItem::UserType);
+ kunde->setText(0, tr("%1 %2 (%3)").arg(kundeFornavn, kundeEtternavn, kundeFirmanavn));
+ kunde->setIcon(0, kundeIkon);
+ kunde->setData(0, Qt::UserRole, kunder.at(x));
+ kundeGjenstander.append(kunde);
+ }
+ prosjektGjenstand->addChildren(kundeGjenstander);
+ }
+
+ prosjektGjenstand->setData(0, Qt::UserRole, i);
+ prosjektListe.append(prosjektGjenstand);
+ }
+ }
+
+ ui->prosjektTre->addTopLevelItems(prosjektListe);
+}
+
+void ProsjektWidget::settGjeldendeProsjekt(ProsjektFil prosjekt) {
+ valgtProsjekt = prosjekt;
+}
+
+void ProsjektWidget::on_pushNy_clicked() {
+ emit opprettProsjekt();
+}
+
+void ProsjektWidget::gjenstandKlikk(QTreeWidgetItem *gjenstand, int kolonne) {
+ if (gjenstand->type() == QTreeWidgetItem::Type) {
+ emit hentProsjektFil(gjenstand->data(kolonne, Qt::UserRole).toInt());
+ kartotekPosisjon = gjenstand->data(kolonne, Qt::UserRole).toInt();
+
+ ui->labelProsjektNavn->setText(valgtProsjekt.value("prosjektnavn").toString());
+ ui->labelOrdrenrValue->setText(valgtProsjekt.value("ordrenummer").toString());
+ ui->ordreText->setHtml(valgtProsjekt.value("prosjektbeskrivelse").toString());
+
+ quint64 prosjektStart = valgtProsjekt.value("prosjektstart").toULongLong();
+ quint64 prosjektSlutt = valgtProsjekt.value("prosjektslutt").toULongLong();
+ QDateTime tProsjektStart(QDateTime::fromMSecsSinceEpoch(prosjektStart));
+ QDateTime tProsjektSlutt(QDateTime::fromMSecsSinceEpoch(prosjektSlutt));
+ ui->labelBegynnerValue->setText(tProsjektStart.toString("dd.MM.yyyy hh:mm"));
+ ui->labelSlutterValue->setText(tProsjektSlutt.toString("dd.MM.yyyy hh:mm"));
+
+ prosjektUI();
+ } else {
+ QTreeWidgetItem *forelder = gjenstand->parent();
+ kartotekPosisjon = forelder->data(kolonne, Qt::UserRole).toInt();
+ kundeID = gjenstand->data(kolonne, Qt::UserRole).toInt();
+ ui->labelProsjektNavn->setText("Ingen prosjekt valgt");
+ ui->labelOrdrenrValue->setText("-");
+ ui->labelBegynnerValue->setText("-");
+ ui->labelSlutterValue->setText("-");
+ ui->ordreText->clear();
+
+ kundeUI();
+ }
+}
+
+void ProsjektWidget::prosjektUI() {
+ ui->pushFjernKunde->setEnabled(false);
+ ui->pushRediger->setEnabled(true);
+ ui->pushSlett->setEnabled(true);
+ ui->pushMerkFerdig->setEnabled(true);
+}
+
+void ProsjektWidget::kundeUI() {
+ ui->pushFjernKunde->setEnabled(true);
+ ui->pushRediger->setEnabled(false);
+ ui->pushSlett->setEnabled(false);
+ ui->pushMerkFerdig->setEnabled(false);
+}
+
+
+void ProsjektWidget::on_pushRediger_clicked() {
+ emit redigerProsjekt(kartotekPosisjon);
+}
+
+
+void ProsjektWidget::on_pushSlett_clicked() {
+ emit slettProsjekt(kartotekPosisjon);
+}
+
+
+void ProsjektWidget::on_pushMerkFerdig_clicked() {
+ emit settAktiv(kartotekPosisjon);
+}
+
+
+void ProsjektWidget::on_pushFjernKunde_clicked() {
+ emit fjernKunde(kartotekPosisjon, kundeID);
+}
diff --git a/src/core/prosjektwidget.h b/src/core/prosjektwidget.h
new file mode 100644
index 0000000..9cbf4ad
--- /dev/null
+++ b/src/core/prosjektwidget.h
@@ -0,0 +1,49 @@
+#ifndef PROSJEKTWIDGET_H
+#define PROSJEKTWIDGET_H
+
+#include
+#include
+#include "datatypes.h"
+
+namespace Ui {
+class ProsjektWidget;
+}
+
+class ProsjektWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit ProsjektWidget(QWidget *parent = nullptr);
+ ~ProsjektWidget();
+
+ void oppdaterProsjektListe(ProsjektKartotek &kartotek, ProsjektBindinger &bindinger, KundeKartotek &kundeKart);
+ void settGjeldendeProsjekt(ProsjektFil prosjekt);
+
+signals:
+ void opprettProsjekt();
+ void hentProsjektFil(int kartotekPlassering);
+ void redigerProsjekt(int kartotekPlassering);
+ void slettProsjekt(int kartotekPlassering);
+ void settAktiv(int kartotekPlassering);
+ void fjernKunde(int prosjektKartotekPosisjon, int kundeID);
+
+private slots:
+ void on_pushNy_clicked();
+ void gjenstandKlikk(QTreeWidgetItem *gjenstand, int kolonne);
+ void on_pushRediger_clicked();
+ void on_pushSlett_clicked();
+ void on_pushMerkFerdig_clicked();
+ void on_pushFjernKunde_clicked();
+
+private:
+ Ui::ProsjektWidget *ui;
+ ProsjektFil valgtProsjekt;
+
+ void prosjektUI();
+ void kundeUI();
+
+ int kartotekPosisjon, kundeID;
+};
+
+#endif // PROSJEKTWIDGET_H
diff --git a/src/core/prosjektwidget.ui b/src/core/prosjektwidget.ui
new file mode 100644
index 0000000..b2a50cd
--- /dev/null
+++ b/src/core/prosjektwidget.ui
@@ -0,0 +1,351 @@
+
+
+ ProsjektWidget
+
+
+
+ 0
+ 0
+ 605
+ 427
+
+
+
+ Form
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 12
+ 75
+ true
+
+
+
+ Prosjektliste
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
-
+
+
+ false
+
+
+
+ 1
+
+
+
+
+ -
+
+
+ Prosjektdetaljer
+
+
+
-
+
+
-
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 10
+ 75
+ true
+
+
+
+ Ingen prosjekt valgt
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 75
+ true
+
+
+
+ Ordrenummer:
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 75
+ true
+
+
+
+ Startdato:
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 75
+ true
+
+
+
+ Sluttdato:
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+ Ordrebeskrivelse
+
+
+
-
+
+
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Nytt prosjekt
+
+
+
+ -
+
+
+ false
+
+
+ Rediger prosjekt
+
+
+
+ -
+
+
+ false
+
+
+ Slett prosjekt
+
+
+
+ -
+
+
+ false
+
+
+ Marker som avsluttet/startet
+
+
+
+ -
+
+
+ false
+
+
+ Fjern kunde
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/core/redigerkundedialog.cpp b/src/core/redigerkundedialog.cpp
new file mode 100644
index 0000000..19fb15f
--- /dev/null
+++ b/src/core/redigerkundedialog.cpp
@@ -0,0 +1,52 @@
+#include "redigerkundedialog.h"
+#include "ui_redigerkundedialog.h"
+
+RedigerKundeDialog::RedigerKundeDialog(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::RedigerKundeDialog)
+{
+ ui->setupUi(this);
+}
+
+RedigerKundeDialog::~RedigerKundeDialog()
+{
+ delete ui;
+}
+
+void RedigerKundeDialog::settInnGamleVerdier(KundeFil gjeldendeKundeFil) {
+ ui->lineKundenummer->setText(gjeldendeKundeFil.value("id").toString());
+
+ ui->lineFornavn->setText(gjeldendeKundeFil.value("fornavn").toString());
+ ui->lineEtternavn->setText(gjeldendeKundeFil.value("etternavn").toString());
+ ui->lineFirmanavn->setText(gjeldendeKundeFil.value("firmanavn").toString());
+ ui->lineGate->setText(gjeldendeKundeFil.value("adresse").toString());
+ ui->linePostnr->setText(gjeldendeKundeFil.value("postnr").toString());
+ ui->lineSted->setText(gjeldendeKundeFil.value("sted").toString());
+ ui->lineEpost->setText(gjeldendeKundeFil.value("epost").toString());
+ ui->lineTlf->setText(gjeldendeKundeFil.value("tlf").toString());
+
+ ui->lineFornavn->selectAll();
+ ui->lineFornavn->setFocus();
+}
+
+void RedigerKundeDialog::on_pushAvbryt_clicked() {
+ QDialog::close();
+}
+
+
+void RedigerKundeDialog::on_pushButton_clicked() {
+ KundeFil oppdatertFil;
+ oppdatertFil.insert("id", ui->lineKundenummer->text().toInt());
+ oppdatertFil.insert("fornavn", ui->lineFornavn->text());
+ oppdatertFil.insert("etternavn", ui->lineEtternavn->text());
+ oppdatertFil.insert("firmanavn", ui->lineFirmanavn->text());
+ oppdatertFil.insert("adresse", ui->lineGate->text());
+ oppdatertFil.insert("postnr", ui->linePostnr->text().toInt());
+ oppdatertFil.insert("sted", ui->lineSted->text());
+ oppdatertFil.insert("epost", ui->lineEpost->text());
+ oppdatertFil.insert("tlf", ui->lineTlf->text().toInt());
+ oppdatertFil.insert("active", true);
+
+ emit oppdaterKundeFil(oppdatertFil);
+}
+
diff --git a/src/core/redigerkundedialog.h b/src/core/redigerkundedialog.h
new file mode 100644
index 0000000..e40ec44
--- /dev/null
+++ b/src/core/redigerkundedialog.h
@@ -0,0 +1,32 @@
+#ifndef REDIGERKUNDEDIALOG_H
+#define REDIGERKUNDEDIALOG_H
+
+#include
+#include "datatypes.h"
+
+namespace Ui {
+class RedigerKundeDialog;
+}
+
+class RedigerKundeDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit RedigerKundeDialog(QWidget *parent = nullptr);
+ ~RedigerKundeDialog();
+
+ void settInnGamleVerdier(KundeFil gjeldendeKundeFil);
+
+signals:
+ void oppdaterKundeFil(KundeFil redigertKundeFil);
+
+private slots:
+ void on_pushAvbryt_clicked();
+ void on_pushButton_clicked();
+
+private:
+ Ui::RedigerKundeDialog *ui;
+};
+
+#endif // REDIGERKUNDEDIALOG_H
diff --git a/src/core/redigerkundedialog.ui b/src/core/redigerkundedialog.ui
new file mode 100644
index 0000000..175d416
--- /dev/null
+++ b/src/core/redigerkundedialog.ui
@@ -0,0 +1,249 @@
+
+
+ RedigerKundeDialog
+
+
+
+ 0
+ 0
+ 359
+ 309
+
+
+
+ Rediger Kunde
+
+
+ -
+
+
-
+
+
-
+
+
+
+ 75
+ true
+
+
+
+ Fornavn:
+
+
+
+ -
+
+
+ -
+
+
+
+ 75
+ true
+
+
+
+ Etternavn:
+
+
+
+ -
+
+
+ -
+
+
+
+ 75
+ true
+
+
+
+ Firmanavn:
+
+
+
+ -
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
-
+
+
+
+ 75
+ true
+
+
+
+ Gateadresse:
+
+
+
+ -
+
+
+ -
+
+
+
+ 75
+ true
+
+
+
+ Postnr:
+
+
+
+ -
+
+
+ -
+
+
+
+ 75
+ true
+
+
+
+ Sted:
+
+
+
+ -
+
+
+ -
+
+
+
+ 75
+ true
+
+
+
+ Telefon:
+
+
+
+ -
+
+
+ -
+
+
+
+ 75
+ true
+
+
+
+ Epost:
+
+
+
+ -
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
-
+
+
+
+ 75
+ true
+
+
+
+ Kundenummer:
+
+
+
+ -
+
+
+ true
+
+
+ true
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Avbryt
+
+
+
+ -
+
+
+ Lagre
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/core/redigerprosjektdialog.cpp b/src/core/redigerprosjektdialog.cpp
new file mode 100644
index 0000000..4d923fc
--- /dev/null
+++ b/src/core/redigerprosjektdialog.cpp
@@ -0,0 +1,111 @@
+#include "redigerprosjektdialog.h"
+#include "ui_redigerprosjektdialog.h"
+
+RedigerProsjektDialog::RedigerProsjektDialog(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::RedigerProsjektDialog) {
+ ui->setupUi(this);
+}
+
+RedigerProsjektDialog::~RedigerProsjektDialog() {
+ delete ui;
+}
+
+void RedigerProsjektDialog::settProsjektFil(ProsjektFil prosjekt) {
+ prosjektFil = prosjekt;
+ fyllSkjemaElementer();
+}
+
+void RedigerProsjektDialog::fyllSkjemaElementer() {
+ ui->lineProsjektNavn->setText(prosjektFil.value("prosjektnavn").toString());
+ ui->lineOrdrenummer->setText(prosjektFil.value("ordrenummer").toString());
+ ui->textEditProsjektBeskrivelse->setHtml(prosjektFil.value("prosjektbeskrivelse").toString());
+ ui->checkVarsleStart->setChecked(prosjektFil.value("varslestart").toBool());
+ ui->checkVarsleSlutt->setChecked(prosjektFil.value("varsleslutt").toBool());
+ endreVarselStatus();
+
+ quint64 prosjektStart = prosjektFil.value("prosjektstart").toULongLong();
+ quint64 prosjektSlutt = prosjektFil.value("prosjektslutt").toULongLong();
+ QDateTime tProsjektStart(QDateTime::fromMSecsSinceEpoch(prosjektStart));
+ QDateTime tProsjektSlutt(QDateTime::fromMSecsSinceEpoch(prosjektSlutt));
+
+ ui->dateStart->setDateTime(tProsjektStart);
+ ui->dateSlutt->setDateTime(tProsjektSlutt);
+ ui->timeStart->setDateTime(tProsjektStart);
+ ui->timeSlutt->setDateTime(tProsjektSlutt);
+
+ ui->spinBoxAntallDognVarslingStart->setValue(prosjektFil.value("dognvarselstart").toInt());
+ ui->spinBoxAntallDognVarslingSlutt->setValue(prosjektFil.value("dognvarselslutt").toInt());
+ ui->spinBoxTimerForStart->setValue(prosjektFil.value("timervarselstart").toInt());
+ ui->spinBoxTimerForSlutt->setValue(prosjektFil.value("timercarselslutt").toInt());
+}
+
+void RedigerProsjektDialog::on_checkVarsleStart_clicked() {
+ endreVarselStatus();
+}
+
+
+void RedigerProsjektDialog::on_checkVarsleSlutt_clicked() {
+ endreVarselStatus();
+}
+
+void RedigerProsjektDialog::endreVarselStatus() {
+ ui->spinBoxAntallDognVarslingSlutt->setEnabled(ui->checkVarsleSlutt->isChecked());
+ ui->spinBoxTimerForSlutt->setEnabled(ui->checkVarsleSlutt->isChecked());
+ ui->spinBoxAntallDognVarslingStart->setEnabled(ui->checkVarsleStart->isChecked());
+ ui->spinBoxTimerForStart->setEnabled(ui->checkVarsleStart->isChecked());
+}
+
+
+void RedigerProsjektDialog::on_pushAvbryt_clicked() {
+ QDialog::close();
+}
+
+
+void RedigerProsjektDialog::on_pushLagre_clicked() {
+ ProsjektFil nyttProsjekt;
+
+ nyttProsjekt.insert("prosjektnavn", ui->lineProsjektNavn->text());
+ nyttProsjekt.insert("ordrenummer", ui->lineOrdrenummer->text().toInt());
+ nyttProsjekt.insert("prosjektbeskrivelse", ui->textEditProsjektBeskrivelse->toHtml());
+ nyttProsjekt.insert("varslestart", ui->checkVarsleStart->isChecked());
+ nyttProsjekt.insert("varsleslutt", ui->checkVarsleSlutt->isChecked());
+
+ QDateTime prosjektStartDato = ui->dateStart->dateTime();
+ quint64 mSekStart = prosjektStartDato.toMSecsSinceEpoch() + ui->timeStart->time().msecsSinceStartOfDay();
+
+ QDateTime prosjektSluttDato = ui->dateSlutt->dateTime();
+ quint64 mSekSlutt = prosjektSluttDato.toMSecsSinceEpoch() + ui->timeSlutt->time().msecsSinceStartOfDay();
+
+ nyttProsjekt.insert("prosjektstart", mSekStart);
+ nyttProsjekt.insert("prosjektslutt", mSekSlutt);
+
+ int dognVarselStart = ui->spinBoxAntallDognVarslingStart->value();
+ int timerVarselStart = ui->spinBoxTimerForStart->value();
+ quint64 epochVarselDognStart = dognVarselStart * 24 * 60 * 60 * 1000;
+ quint64 epochVarselTimerStart = timerVarselStart * 60 * 60 * 1000;
+ quint64 epochVarselStart = epochVarselDognStart + epochVarselTimerStart;
+
+ int dognVarselSlutt = ui->spinBoxAntallDognVarslingSlutt->value();
+ int timerVarselSlutt = ui->spinBoxTimerForSlutt->value();
+ quint64 epochVarselDognSlutt = dognVarselSlutt * 24 * 60 * 60 * 1000;
+ quint64 epochVarselTimerSlutt = timerVarselSlutt * 60 * 60 * 1000;
+ quint64 epochVarselSlutt = epochVarselDognSlutt + epochVarselTimerSlutt;
+
+ nyttProsjekt.insert("varselstart", epochVarselStart);
+ nyttProsjekt.insert("varselslutt", epochVarselSlutt);
+ nyttProsjekt.insert("dognvarselstart", ui->spinBoxAntallDognVarslingStart->value());
+ nyttProsjekt.insert("dognvarselslutt", ui->spinBoxAntallDognVarslingSlutt->value());
+ nyttProsjekt.insert("timervarselstart", ui->spinBoxTimerForStart->value());
+ nyttProsjekt.insert("timercarselslutt", ui->spinBoxTimerForSlutt->value());
+
+ nyttProsjekt.insert("active", true);
+ nyttProsjekt.insert("ferdig", false);
+
+ emit lagreProsjekt(nyttProsjekt);
+}
+
+void RedigerProsjektDialog::fokusStart() {
+ ui->lineProsjektNavn->setFocus();
+ ui->lineProsjektNavn->selectAll();
+}
diff --git a/src/core/redigerprosjektdialog.h b/src/core/redigerprosjektdialog.h
new file mode 100644
index 0000000..dc4502e
--- /dev/null
+++ b/src/core/redigerprosjektdialog.h
@@ -0,0 +1,38 @@
+#ifndef REDIGERPROSJEKTDIALOG_H
+#define REDIGERPROSJEKTDIALOG_H
+
+#include
+#include "datatypes.h"
+
+namespace Ui {
+class RedigerProsjektDialog;
+}
+
+class RedigerProsjektDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit RedigerProsjektDialog(QWidget *parent = nullptr);
+ ~RedigerProsjektDialog();
+ void settProsjektFil(ProsjektFil prosjekt);
+ void fokusStart();
+
+signals:
+ void lagreProsjekt(ProsjektFil prosjekt);
+
+private slots:
+ void on_checkVarsleStart_clicked();
+ void on_checkVarsleSlutt_clicked();
+ void endreVarselStatus();
+ void on_pushAvbryt_clicked();
+ void on_pushLagre_clicked();
+
+private:
+ Ui::RedigerProsjektDialog *ui;
+ ProsjektFil prosjektFil;
+
+ void fyllSkjemaElementer();
+};
+
+#endif // REDIGERPROSJEKTDIALOG_H
diff --git a/src/core/redigerprosjektdialog.ui b/src/core/redigerprosjektdialog.ui
new file mode 100644
index 0000000..af29d9e
--- /dev/null
+++ b/src/core/redigerprosjektdialog.ui
@@ -0,0 +1,735 @@
+
+
+ RedigerProsjektDialog
+
+
+
+ 0
+ 0
+ 526
+ 505
+
+
+
+ Rediger prosjekt
+
+
+ -
+
+
+
+ 10
+ 75
+ true
+
+
+
+ Prosjekt detaljer
+
+
+ true
+
+
+
-
+
+
-
+
+
+
+ 8
+ 75
+ true
+
+
+
+ Prosjekt navn:
+
+
+
+ -
+
+
+
+ 8
+ 50
+ false
+
+
+
+
+ -
+
+
+
+ 8
+ 75
+ true
+
+
+
+ Ordrenummer:
+
+
+
+ -
+
+
+
+ 8
+ 50
+ false
+
+
+
+ true
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 10
+ 75
+ true
+
+
+
+ Prosjektbeskrivelse
+
+
+ true
+
+
+
-
+
+
+
+ 10
+ 50
+ false
+
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 10
+ 75
+ true
+
+
+
+ Prosjekt start
+
+
+ true
+
+
+ false
+
+
+
-
+
+
-
+
+
-
+
+
+
+ 8
+ 75
+ true
+
+
+
+ Dato:
+
+
+
+ -
+
+
+
+ 8
+ 50
+ false
+
+
+
+
+
+
+ QDateTimeEdit::DaySection
+
+
+ true
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 8
+ 75
+ true
+
+
+
+ Klokken:
+
+
+
+ -
+
+
+
+ 8
+ 50
+ false
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
-
+
+
-
+
+
+
+ 8
+ 50
+ false
+
+
+
+ Slå på varsling
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 8
+ 75
+ true
+
+
+
+ Antall døgn:
+
+
+
+ -
+
+
+ false
+
+
+
+ 8
+ 50
+ false
+
+
+
+ 0
+
+
+ 365
+
+
+ 14
+
+
+
+ -
+
+
+
+ 8
+ 50
+ false
+
+
+
+ Før start
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+
+ 8
+ 75
+ true
+
+
+
+ Antall timer:
+
+
+
+ -
+
+
+ false
+
+
+
+ 8
+ 50
+ false
+
+
+
+ 24
+
+
+
+ -
+
+
+
+ 8
+ 50
+ false
+
+
+
+ Før start
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 10
+ 75
+ true
+
+
+
+ Prosjekt slutt
+
+
+ true
+
+
+ false
+
+
+
-
+
+
-
+
+
-
+
+
+
+ 8
+ 75
+ true
+
+
+
+ Dato:
+
+
+
+ -
+
+
+
+ 8
+ 50
+ false
+
+
+
+
+
+
+ QDateTimeEdit::DaySection
+
+
+ true
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 8
+ 75
+ true
+
+
+
+ Klokken:
+
+
+
+ -
+
+
+
+ 8
+ 50
+ false
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
-
+
+
-
+
+
+
+ 8
+ 50
+ false
+
+
+
+ Slå på varsling
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 8
+ 75
+ true
+
+
+
+ Antall døgn:
+
+
+
+ -
+
+
+ false
+
+
+
+ 8
+ 50
+ false
+
+
+
+ 0
+
+
+ 365
+
+
+ 14
+
+
+
+ -
+
+
+
+ 8
+ 50
+ false
+
+
+
+ Før slutt
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+
+ 8
+ 75
+ true
+
+
+
+ Antall timer:
+
+
+
+ -
+
+
+ false
+
+
+
+ 8
+ 50
+ false
+
+
+
+ 24
+
+
+
+ -
+
+
+
+ 8
+ 50
+ false
+
+
+
+ Før slutt
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Avbryt
+
+
+
+ -
+
+
+ Lagre
+
+
+ true
+
+
+
+
+
+
+
+
+
+
diff --git a/src/core/varsledialog.cpp b/src/core/varsledialog.cpp
new file mode 100644
index 0000000..8e219f4
--- /dev/null
+++ b/src/core/varsledialog.cpp
@@ -0,0 +1,65 @@
+#include "varsledialog.h"
+#include "ui_varsledialog.h"
+
+VarsleDialog::VarsleDialog(QWidget *parent, AlertConditions alertCondition) :
+ QDialog(parent),
+ ui(new Ui::VarsleDialog) {
+ ui->setupUi(this);
+
+ condition = alertCondition;
+
+ switch (condition) {
+ case AlertConditions::CONDITION_GREEN:
+ setConditionGreen();
+ break;
+ case AlertConditions::CONDITION_YELLOW:
+ setConditionYellow();
+ break;
+ case AlertConditions::CONDITION_RED:
+ setConditionRed();
+ break;
+ default:
+ break;
+ }
+}
+
+VarsleDialog::~VarsleDialog() {
+ delete ui;
+}
+
+void VarsleDialog::settProsjektNavn(QString navn) {
+ ui->labelProsjektNavnVerdi->setText(navn);
+}
+
+void VarsleDialog::settStart(quint64 epoch) {
+ QDateTime tProsjektStart(QDateTime::fromMSecsSinceEpoch(epoch));
+ ui->labelStartVerdi->setText(tProsjektStart.toString("dd.MM.yyyy hh:mm"));
+}
+
+void VarsleDialog::settSlutt(quint64 epoch) {
+ QDateTime tProsjektStart(QDateTime::fromMSecsSinceEpoch(epoch));
+ ui->labelSluttVerdi->setText(tProsjektStart.toString("dd.MM.yyyy hh:mm"));
+}
+
+void VarsleDialog::setConditionGreen() {
+ QString kText = "Kondisjon: Grønn
";
+ ui->labelKondisjonVerdi->setTextFormat(Qt::RichText);
+ ui->labelKondisjonVerdi->setText(kText);
+}
+
+void VarsleDialog::setConditionYellow() {
+ QString kText = "Kondisjon: ! Gul !
";
+ ui->labelKondisjonVerdi->setTextFormat(Qt::RichText);
+ ui->labelKondisjonVerdi->setText(kText);
+}
+
+void VarsleDialog::setConditionRed() {
+ QString kText = "Kondisjon: !!! RØD !!!
";
+ ui->labelKondisjonVerdi->setTextFormat(Qt::RichText);
+ ui->labelKondisjonVerdi->setText(kText);
+}
+
+void VarsleDialog::on_pushOk_clicked() {
+ QDialog::close();
+}
+
diff --git a/src/core/varsledialog.h b/src/core/varsledialog.h
new file mode 100644
index 0000000..efaed32
--- /dev/null
+++ b/src/core/varsledialog.h
@@ -0,0 +1,35 @@
+#ifndef VARSLEDIALOG_H
+#define VARSLEDIALOG_H
+
+#include
+#include "datatypes.h"
+
+namespace Ui {
+class VarsleDialog;
+}
+
+class VarsleDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit VarsleDialog(QWidget *parent = nullptr, AlertConditions alertCondition = AlertConditions::CONDITION_GREEN);
+ ~VarsleDialog();
+
+ void settProsjektNavn(QString navn);
+ void settStart(quint64 epoch);
+ void settSlutt(quint64 epoch);
+
+private slots:
+ void on_pushOk_clicked();
+
+private:
+ Ui::VarsleDialog *ui;
+ AlertConditions condition;
+
+ void setConditionGreen();
+ void setConditionYellow();
+ void setConditionRed();
+};
+
+#endif // VARSLEDIALOG_H
diff --git a/src/core/varsledialog.ui b/src/core/varsledialog.ui
new file mode 100644
index 0000000..2bacd30
--- /dev/null
+++ b/src/core/varsledialog.ui
@@ -0,0 +1,251 @@
+
+
+ VarsleDialog
+
+
+
+ 0
+ 0
+ 422
+ 311
+
+
+
+ Varsel om prosjekt
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 16
+ 75
+ true
+
+
+
+ Varsel
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 14
+
+
+
+ <html><head/><body><p>Kondisjon: <span style=" color:#00c800;">Grønn</span></p></body></html>
+
+
+ Qt::RichText
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
-
+
+
+
+ 75
+ true
+
+
+
+ Prosjektnavn:
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 75
+ true
+
+
+
+ Start:
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 75
+ true
+
+
+
+ Slutt:
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+ Lukk varsel
+
+
+ true
+
+
+
+
+
+
+
+
diff --git a/src/core/velgkundeprosjektdialog.cpp b/src/core/velgkundeprosjektdialog.cpp
new file mode 100644
index 0000000..e7baf26
--- /dev/null
+++ b/src/core/velgkundeprosjektdialog.cpp
@@ -0,0 +1,47 @@
+#include "velgkundeprosjektdialog.h"
+#include "ui_velgkundeprosjektdialog.h"
+
+VelgKundeProsjektDialog::VelgKundeProsjektDialog(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::VelgKundeProsjektDialog) {
+ ui->setupUi(this);
+}
+
+VelgKundeProsjektDialog::~VelgKundeProsjektDialog() {
+ delete ui;
+}
+
+void VelgKundeProsjektDialog::settKundeID(int id) {
+ kundeID = id;
+}
+
+int VelgKundeProsjektDialog::hentKundeID() {
+ return kundeID;
+}
+
+void VelgKundeProsjektDialog::hentProsjekter(ProsjektKartotek &kartotek, ProsjektBindinger &bindinger) {
+ for (int i = 0; i < kartotek.size(); ++i) {
+ QList prosjektMedlemmer = bindinger.value(kartotek.at(i).value("ordrenummer").toInt());
+ if (!prosjektMedlemmer.contains(kundeID)) {
+ QListWidgetItem *prosjekt = new QListWidgetItem(kartotek.at(i).value("prosjektnavn").toString());
+ prosjekt->setData(Qt::UserRole, kartotek.at(i).value("ordrenummer").toInt());
+ ui->prosjektListe->addItem(prosjekt);
+ }
+ }
+}
+
+void VelgKundeProsjektDialog::on_pushAvbryt_clicked() {
+ QDialog::close();
+}
+
+
+void VelgKundeProsjektDialog::on_prosjektListe_itemClicked(QListWidgetItem *item) {
+ ui->pushVelg->setEnabled(true);
+ prosjektID = item->data(Qt::UserRole).toInt();
+}
+
+
+void VelgKundeProsjektDialog::on_pushVelg_clicked() {
+ emit opprettBinding(kundeID, prosjektID);
+}
+
diff --git a/src/core/velgkundeprosjektdialog.h b/src/core/velgkundeprosjektdialog.h
new file mode 100644
index 0000000..18349ac
--- /dev/null
+++ b/src/core/velgkundeprosjektdialog.h
@@ -0,0 +1,39 @@
+#ifndef VELGKUNDEPROSJEKTDIALOG_H
+#define VELGKUNDEPROSJEKTDIALOG_H
+
+#include
+#include
+#include "datatypes.h"
+
+namespace Ui {
+class VelgKundeProsjektDialog;
+}
+
+class VelgKundeProsjektDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit VelgKundeProsjektDialog(QWidget *parent = nullptr);
+ ~VelgKundeProsjektDialog();
+
+ void settKundeID(int id);
+ int hentKundeID();
+
+ void hentProsjekter(ProsjektKartotek &kartotek, ProsjektBindinger &bindinger);
+
+signals:
+ void opprettBinding(int kunde, int prosjekt);
+
+private slots:
+ void on_pushAvbryt_clicked();
+ void on_prosjektListe_itemClicked(QListWidgetItem *item);
+
+ void on_pushVelg_clicked();
+
+private:
+ Ui::VelgKundeProsjektDialog *ui;
+ int kundeID, prosjektID;
+};
+
+#endif // VELGKUNDEPROSJEKTDIALOG_H
diff --git a/src/core/velgkundeprosjektdialog.ui b/src/core/velgkundeprosjektdialog.ui
new file mode 100644
index 0000000..d59b2e3
--- /dev/null
+++ b/src/core/velgkundeprosjektdialog.ui
@@ -0,0 +1,61 @@
+
+
+ VelgKundeProsjektDialog
+
+
+
+ 0
+ 0
+ 400
+ 300
+
+
+
+ Velg et prosjekt for kunden
+
+
+ -
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Avbryt
+
+
+
+ -
+
+
+ false
+
+
+ Velg prosjekt
+
+
+ true
+
+
+
+
+
+
+
+
+
+
diff --git a/src/src.pro b/src/src.pro
new file mode 100644
index 0000000..4165df6
--- /dev/null
+++ b/src/src.pro
@@ -0,0 +1,3 @@
+TEMPLATE = subdirs
+
+SUBDIRS += core