From 5ff71d5008af130f26ea60daff3060a1163d7e6c Mon Sep 17 00:00:00 2001 From: Claude Brisson <claude@renegat.net> Date: Tue, 26 Feb 2019 12:31:23 +0100 Subject: [PATCH] Take sleeping periods into account --- Makefile | 10 +++++++--- src/timeslice.cpp | 43 ++++++++++++++++++++++++++++++------------- src/timeslice.h | 11 +++++++---- 3 files changed, 44 insertions(+), 20 deletions(-) diff --git a/Makefile b/Makefile index 4863674..c762975 100644 --- a/Makefile +++ b/Makefile @@ -18,16 +18,16 @@ CXXFLAGS += -I/usr/include/atk-1.0 -I/usr/include/atkmm-1.6 CXXFLAGS += -I/usr/include/mysql # link flags -LDFLAGS += -L/usr/local/lib -L/usr/lib -L/usr/lib/x86_64-linux-gnu -lgtkmm-3.0 -latkmm-1.6 -lglibmm-2.4 -lsigc-2.0 -lmysqlpp -ldl +LDFLAGS += -L/usr/local/lib -L/usr/lib -L/usr/lib/x86_64-linux-gnu -lgtkmm-3.0 -latkmm-1.6 -lglibmm-2.4 -lsigc-2.0 -lmysqlpp -lXss -lX11 -lgdkmm-3.0 -ldl all: timeslice .PHONY: all clean -timeslice: obj/timeslice.o obj/main.o +timeslice: obj/timeslice.o obj/main.o obj/idle.o $(CXX) $^ -o $@ $(LDFLAGS) -obj/timeslice.o: src/timeslice.cpp src/timeslice.h src/config.h +obj/timeslice.o: src/timeslice.cpp src/timeslice.h src/config.h src/idle.h mkdir -p obj $(CXX) $(CXXFLAGS) -o $@ -c $< @@ -35,5 +35,9 @@ obj/main.o: src/main.cpp src/timeslice.h mkdir -p obj $(CXX) $(CXXFLAGS) -o $@ -c $< +obj/idle.o: src/idle.cpp src/idle.h + mkdir -p obj + $(CXX) $(CXXFLAGS) -o $@ -c $< + clean: rm -rf obj timeslice diff --git a/src/timeslice.cpp b/src/timeslice.cpp index 5056559..656dc35 100644 --- a/src/timeslice.cpp +++ b/src/timeslice.cpp @@ -3,6 +3,7 @@ #include <iostream> #include <mysql++/mysql++.h> #include "config.h" +#include "idle.h" static TimeSlice *app = nullptr; @@ -17,7 +18,6 @@ Project::Project(int id, std::string name) : id(id), name(name) void Project::on_button_clicked() { app->setActive(this); - app->resetStart(); } TimeSlice::TimeSlice() @@ -103,34 +103,52 @@ void TimeSlice::setActive(Project *project) { if (active) { - timestamp now = std::chrono::system_clock::now(); - std::cerr << "@@@ old:" << (now - start).count() << std::endl; - std::cerr << "@@@ new:" << time_diff(now, start) << std::endl; - active->elapsed += time_diff(now, start); + timestamp now = TIME_NOW(); + int diff = TIME_DIFF(now, start) - slept; + active->elapsed += diff; } active = project; + start = TIME_NOW(); + lastElapsed = slept = 0; } bool TimeSlice::on_timer() { if (active) { - timestamp now = std::chrono::system_clock::now(); - long elapsed = active->elapsed + time_diff(now, start); - long hours = elapsed / 3600; - long minutes = (elapsed % 3600) / 60; - long seconds = elapsed % 60; +std::ostringstream dbg; + timestamp now = TIME_NOW(); + int diff = TIME_DIFF(now, start); +dbg<<"@@ raw diff = " << diff << ", sleeped " << (diff - lastElapsed - 1); + slept += std::max(0, diff - lastElapsed - 1); +dbg<<", total sleep = " << slept; + lastElapsed = diff; + diff -= slept; +dbg<<", actual diff = " << diff << std::endl; +std::cerr << dbg.str(); + int elapsed = active->elapsed + diff; + int hours = elapsed / 3600; + int minutes = (elapsed % 3600) / 60; + int seconds = elapsed % 60; std::ostringstream oss; oss << std::setfill('0') << std::setw(2) << hours << ':' << std::setw(2) << minutes << ':' << std::setw(2) << seconds; std::string hms = oss.str(); active->label->set_text(hms); active->label->queue_draw(); - registerTimeSlice(active->id, start, elapsed); + registerTimeSlice(active->id, start, diff); + // now check for inactivity + int idleSeconds = GetIdleTime(); + if (idleSeconds > IDLE) + { + idle->clicked(); + Glib::RefPtr<Gdk::Window> window = get_window(); + if (window) window->beep(); + } } return true; } -void TimeSlice::registerTimeSlice(int id, timestamp start, long elapsed) +void TimeSlice::registerTimeSlice(int id, timestamp start, int elapsed) { mysqlpp::Connection conn; mysqlpp::SetCharsetNameOption *scno = new mysqlpp::SetCharsetNameOption("utf8"); @@ -138,7 +156,6 @@ void TimeSlice::registerTimeSlice(int id, timestamp start, long elapsed) conn.connect(TS_DB, TS_HOST, TS_USER, TS_PASSWORD); mysqlpp::Query query = conn.query(); std::time_t time = std::chrono::system_clock::to_time_t(start); - std::cerr << "@@@ " << std::put_time(std::localtime(&time), "%F %T") << std::endl; query << "INSERT INTO timeslice (pr_id, starttime, duration) VALUES (" << id << ", '" << std::put_time(std::localtime(&time), "%F %T") << "', " << elapsed << ") ON DUPLICATE KEY UPDATE duration = VALUES(duration)"; if (!query.exec()) throw std::runtime_error("could not update time slice"); } diff --git a/src/timeslice.h b/src/timeslice.h index bd6f63a..c629134 100644 --- a/src/timeslice.h +++ b/src/timeslice.h @@ -3,8 +3,10 @@ #include <gtkmm-3.0/gtkmm.h> #define TIMEOUT 1000 +#define IDLE 300000 // 5 min typedef std::chrono::time_point<std::chrono::system_clock> timestamp; -#define time_diff(a,b) (std::chrono::duration_cast<std::chrono::seconds>((a) - (b)).count()) +#define TIME_DIFF(a,b) (std::chrono::duration_cast<std::chrono::seconds>((a) - (b)).count()) +#define TIME_NOW() (std::chrono::system_clock::now()) struct Project { @@ -14,7 +16,7 @@ struct Project std::shared_ptr<Gtk::RadioButton> button; std::shared_ptr<Gtk::Label> label; void on_button_clicked(); - long elapsed = 0; + int elapsed = 0; }; class TimeSlice : public Gtk::Window @@ -30,8 +32,7 @@ public: void on_idle_clicked(); bool on_timer(); void setActive(Project *project); - void resetStart() { start = std::chrono::system_clock::now(); } - void registerTimeSlice(int id, timestamp start, long elapsed); + void registerTimeSlice(int id, timestamp start, int elapsed); protected: std::shared_ptr<Gtk::RadioButtonGroup> group; @@ -41,4 +42,6 @@ protected: sigc::connection timer; Project * active = nullptr; timestamp start; + int lastElapsed = 0; + int slept = 0; // seconds }; -- GitLab