Skip to content

Commit 221b81b

Browse files
authored
Release 0.1.0.0
2 parents 5c9a9ac + ad99f06 commit 221b81b

20 files changed

+69578
-21
lines changed

Time Tracker/App.xaml

+5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
xmlns:local="clr-namespace:Time_Tracker"
55
StartupUri="MainWindow.xaml">
66
<Application.Resources>
7+
<ResourceDictionary>
8+
<ResourceDictionary.MergedDictionaries>
9+
<ResourceDictionary Source="/Resources/Styles/Basic.xaml"/>
10+
</ResourceDictionary.MergedDictionaries>
11+
</ResourceDictionary>
712

813
</Application.Resources>
914
</Application>

Time Tracker/Clock.ico

2.08 KB
Binary file not shown.

Time Tracker/MainWindow.xaml

+35-3
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,42 @@
33
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
44
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
55
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
6-
xmlns:local="clr-namespace:Time_Tracker"
6+
xmlns:tb="http://www.hardcodet.net/taskbar"
77
mc:Ignorable="d"
8-
Title="MainWindow" Height="450" Width="800">
8+
Title="MainWindow" Height="135" Width="268" ShowInTaskbar="False" WindowStartupLocation="Manual" WindowStyle="None" ResizeMode="NoResize" Deactivated="Window_Deactivated" Loaded="Window_Loaded" Closing="Window_Closing">
99
<Grid>
10-
10+
11+
<tb:TaskbarIcon x:Name="uiTrayIcon"
12+
Visibility="Visible"
13+
IconSource="/Resources/Images/Clock.ico"
14+
MenuActivation="RightClick"
15+
TrayMouseDoubleClick="UiTrayIcon_TrayMouseDoubleClick"
16+
>
17+
<tb:TaskbarIcon.ContextMenu>
18+
<ContextMenu>
19+
<MenuItem Header="Quit" Click="MenuItem_Quit_Click"/>
20+
</ContextMenu>
21+
</tb:TaskbarIcon.ContextMenu>
22+
</tb:TaskbarIcon>
23+
24+
<StackPanel>
25+
<DockPanel>
26+
<Button Name="uiStart" Click="UiStart_Click" Content="&#xf04b;" FontFamily="{StaticResource FontAwesomeSolid}" DockPanel.Dock="Left" Width="28" Height="28"/>
27+
<Button Name="uiStop" Click="UiStop_Click" Content="&#xf04d;" FontFamily="{StaticResource FontAwesomeSolid}" DockPanel.Dock="Left" Width="28" Height="28"/>
28+
<Button Name="uiClose" Click="UiClose_Click" Content="&#xf057;" FontFamily="{StaticResource FontAwesomeSolid}" DockPanel.Dock="Right" Width="28" Height="28"/>
29+
<Button Name="uiSettings" Content="&#xf013;" FontFamily="{StaticResource FontAwesomeSolid}" DockPanel.Dock="Right" Width="28" Height="28"/>
30+
<Button Name="uiShowAll" Content="Show All" DockPanel.Dock="Right" Padding="7,5" Height="28"/>
31+
<Label Name="uiTime" Content="00:00:00" HorizontalContentAlignment="Center" FontSize="13px"/>
32+
</DockPanel>
33+
<DockPanel>
34+
<Label Name="uiOvertimeLabel" Content="Elapsed:" DockPanel.Dock="Left" Padding="5,5,2,5"/>
35+
<Label Name="uiOvertime" Content="00:00:00 (+00:00)"/>
36+
</DockPanel>
37+
<StackPanel>
38+
<TextBox Name="uiActivity" Margin="5,0,5,2"/>
39+
<TextBox Name="uiDescription" Height="54" AcceptsReturn="True" VerticalScrollBarVisibility="Auto" TextWrapping="Wrap" Margin="5,2,5,5"/>
40+
</StackPanel>
41+
</StackPanel>
42+
1143
</Grid>
1244
</Window>

Time Tracker/MainWindow.xaml.cs

+94-15
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,107 @@
11
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Text;
5-
using System.Threading.Tasks;
62
using System.Windows;
7-
using System.Windows.Controls;
8-
using System.Windows.Data;
9-
using System.Windows.Documents;
10-
using System.Windows.Input;
11-
using System.Windows.Media;
12-
using System.Windows.Media.Imaging;
13-
using System.Windows.Navigation;
14-
using System.Windows.Shapes;
3+
using System.Windows.Threading;
4+
using Time_Tracker.Resources.Classes;
155

166
namespace Time_Tracker
177
{
18-
/// <summary>
19-
/// Interaktionslogik für MainWindow.xaml
20-
/// </summary>
218
public partial class MainWindow : Window
229
{
10+
private Database oDatabase;
11+
private DateTime dStart;
12+
private DispatcherTimer oTimer = new DispatcherTimer();
13+
2314
public MainWindow()
2415
{
2516
InitializeComponent();
17+
SetStartupPosition();
18+
19+
oTimer.Tick += new EventHandler(Timer_Tick);
20+
oTimer.Interval = new TimeSpan(0, 0, 1);
21+
22+
oDatabase = new Database(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\TimeTracker");
23+
}
24+
25+
private void SetStartupPosition()
26+
{
27+
double iScreenHeight = SystemParameters.WorkArea.Height;
28+
double iScreenWidth = SystemParameters.WorkArea.Width;
29+
30+
this.Left = iScreenWidth - this.Width - 10;
31+
this.Top = iScreenHeight - this.Height - 10;
32+
}
33+
34+
private void UiTrayIcon_TrayMouseDoubleClick(object sender, RoutedEventArgs e)
35+
{
36+
this.Visibility = Visibility.Visible;
37+
this.Activate();
38+
}
39+
40+
private void Window_Deactivated(object sender, EventArgs e)
41+
{
42+
this.Visibility = Visibility.Collapsed;
43+
}
44+
45+
private void Window_Loaded(object sender, RoutedEventArgs e)
46+
{
47+
this.Visibility = Visibility.Collapsed;
48+
}
49+
50+
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
51+
{
52+
if (oTimer.IsEnabled)
53+
{
54+
if(MessageBox.Show("If you quit the App now your current timer will be lost. Quit anyway?",
55+
"Quit?", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.No)
56+
{
57+
e.Cancel = true;
58+
}
59+
}
60+
}
61+
62+
private void MenuItem_Quit_Click(object sender, RoutedEventArgs e)
63+
{
64+
Application.Current.Shutdown(0);
65+
}
66+
67+
private void UiClose_Click(object sender, RoutedEventArgs e)
68+
{
69+
this.Close();
70+
}
71+
72+
private void UiStart_Click(object sender, RoutedEventArgs e)
73+
{
74+
//Do nothing if timer is already running.
75+
if (oTimer.IsEnabled)
76+
{
77+
return;
78+
}
79+
80+
//-1 second to create a 1 second elapsed time right away (looks weird if it starts at 0).
81+
dStart = DateTime.Now.AddSeconds(-1);
82+
this.uiActivity.Text = "";
83+
this.uiDescription.Text = "";
84+
85+
//Call the tick event directly to make it start right away.
86+
Timer_Tick(null, null);
87+
oTimer.Start();
88+
}
89+
90+
private void UiStop_Click(object sender, RoutedEventArgs e)
91+
{
92+
oTimer.Stop();
93+
94+
DateTime dEnd = DateTime.Now;
95+
96+
oDatabase.Save(new Database.TimeRecord(0, this.dStart, dEnd, this.uiActivity.Text, this.uiDescription.Text));
97+
98+
//Start new timer
99+
UiStart_Click(null, null);
100+
}
101+
102+
private void Timer_Tick(object sender, EventArgs e)
103+
{
104+
this.uiTime.Content = DateTime.Parse((DateTime.Now - dStart).ToString()).ToString("HH:mm:ss");
26105
}
27106
}
28107
}

Time Tracker/Properties/AssemblyInfo.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
[assembly: AssemblyConfiguration("")]
1313
[assembly: AssemblyCompany("Github@NinjaPewPew")]
1414
[assembly: AssemblyProduct("Time Tracker")]
15-
[assembly: AssemblyCopyright("Copyright © 2019")]
15+
[assembly: AssemblyCopyright("Copyright © Marcel Rütjerodt 2019")]
1616
[assembly: AssemblyTrademark("")]
1717
[assembly: AssemblyCulture("")]
1818

@@ -51,5 +51,5 @@
5151
// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
5252
// übernehmen, indem Sie "*" eingeben:
5353
// [assembly: AssemblyVersion("1.0.*")]
54-
[assembly: AssemblyVersion("0.0.0.0")]
55-
[assembly: AssemblyFileVersion("0.0.0.0")]
54+
[assembly: AssemblyVersion("0.1.0.0")]
55+
[assembly: AssemblyFileVersion("0.1.0.0")]
+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
using System;
2+
using System.Data.SQLite;
3+
4+
namespace Time_Tracker.Resources.Classes
5+
{
6+
class Database
7+
{
8+
private string sDatabasePath;
9+
10+
/// <summary>
11+
/// Initialize a new database. Folders and database will be created if they not already exist.
12+
/// </summary>
13+
/// <param name="sDatabasePath">Path where the database is supposed to be saved.</param>
14+
public Database(string sDatabasePath)
15+
{
16+
this.sDatabasePath = sDatabasePath;
17+
System.IO.Directory.CreateDirectory(sDatabasePath);
18+
19+
SQLiteConnection oSQLiteConnection = new SQLiteConnection($"Data Source={sDatabasePath}\\TimeTracker.db;Version=3;foreign keys=true;");
20+
oSQLiteConnection.Open();
21+
22+
bool bExist = false;
23+
SQLiteDataReader oSQLiteReader = new SQLiteCommand("SELECT name FROM sqlite_master WHERE type='table' AND name='TimeTracker';",
24+
oSQLiteConnection).ExecuteReader();
25+
while (oSQLiteReader.Read())
26+
{
27+
bExist = true;
28+
break;
29+
}
30+
31+
if (!bExist)
32+
{
33+
new SQLiteCommand(@"CREATE TABLE TimeTracker (
34+
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE,
35+
start DATETIME NOT NULL,
36+
[end] DATETIME NOT NULL,
37+
activity TEXT,
38+
description TEXT);", oSQLiteConnection).ExecuteNonQuery();
39+
}
40+
41+
oSQLiteConnection.Close();
42+
}
43+
44+
/// <summary>
45+
/// Save a time record.
46+
/// </summary>
47+
/// <param name="oTimeRecord"></param>
48+
/// <returns>True if successful</returns>
49+
public bool Save(TimeRecord oTimeRecord)
50+
{
51+
SQLiteConnection oSQLiteConnection = new SQLiteConnection($"Data Source={sDatabasePath}\\TimeTracker.db;Version=3;foreign keys=true;");
52+
oSQLiteConnection.Open();
53+
54+
string sSQL = $@"INSERT INTO TimeTracker(start, [end], activity, description) VALUES
55+
('{oTimeRecord.dStart.ToString("yyyy-MM-dd hh:mm:ss")}',
56+
'{oTimeRecord.dEnd.ToString("yyyy-MM-dd hh:mm:ss")}',
57+
{(oTimeRecord.sActivitiy != "" ? "'" + oTimeRecord.sActivitiy.Replace("'", "''") + "'":"NULL")},
58+
{(oTimeRecord.sDescription != "" ? "'" + oTimeRecord.sDescription.Replace("'", "''") + "'" : "NULL")});";
59+
60+
new SQLiteCommand(sSQL, oSQLiteConnection).ExecuteNonQuery();
61+
62+
oSQLiteConnection.Close();
63+
64+
return true;
65+
}
66+
67+
/// <summary>
68+
/// Class for storing time record data.
69+
/// </summary>
70+
public class TimeRecord
71+
{
72+
public int iID;
73+
public DateTime dStart;
74+
public DateTime dEnd;
75+
public string sActivitiy;
76+
public string sDescription;
77+
78+
public TimeRecord(int iID, DateTime dStart, DateTime dEnd, string sActivitiy, string sDescription)
79+
{
80+
this.iID = iID;
81+
this.dStart = dStart;
82+
this.dEnd = dEnd;
83+
this.sActivitiy = sActivitiy;
84+
this.sDescription = sDescription;
85+
}
86+
}
87+
}
88+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
Font Awesome Free License
2+
-------------------------
3+
4+
Font Awesome Free is free, open source, and GPL friendly. You can use it for
5+
commercial projects, open source projects, or really almost whatever you want.
6+
Full Font Awesome Free license: https://fontawesome.com/license/free.
7+
8+
# Icons: CC BY 4.0 License (https://creativecommons.org/licenses/by/4.0/)
9+
In the Font Awesome Free download, the CC BY 4.0 license applies to all icons
10+
packaged as SVG and JS file types.
11+
12+
# Fonts: SIL OFL 1.1 License (https://scripts.sil.org/OFL)
13+
In the Font Awesome Free download, the SIL OFL license applies to all icons
14+
packaged as web and desktop font files.
15+
16+
# Code: MIT License (https://opensource.org/licenses/MIT)
17+
In the Font Awesome Free download, the MIT license applies to all non-font and
18+
non-icon files.
19+
20+
# Attribution
21+
Attribution is required by MIT, SIL OFL, and CC BY licenses. Downloaded Font
22+
Awesome Free files already contain embedded comments with sufficient
23+
attribution, so you shouldn't need to do anything additional when using these
24+
files normally.
25+
26+
We've kept attribution comments terse, so we ask that you do not actively work
27+
to remove them from files, especially code. They're a great way for folks to
28+
learn about Font Awesome.
29+
30+
# Brand Icons
31+
All brand icons are trademarks of their respective owners. The use of these
32+
trademarks does not indicate endorsement of the trademark holder by Font
33+
Awesome, nor vice versa. **Please do not use brand logos for any purpose except
34+
to represent the company, product, or service to which they refer.**

0 commit comments

Comments
 (0)