#include #include #include #include #include "seqmatcher.h" #include "got.h" #include "gui.h" #include "xutil.h" int main(int argc, char **argv) { if (argc >= 2 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0)) { std::cout << "GUI for GOT (https://github.com/lieuwex/got), which is a rewrite of Timetrap.\n" "This thing runs as a daemon; it gets activated with the Pause/Break key on\n" "your keyboard. The following sequences trigger actions:\n" " E -- Edit the note for the currently running activity\n" " I -- Check into a sheet\n" " O -- Check out of the current activity\n" " -- Switch and check into the 'misc' sheet\n" " Q -- Quit this program (killing it also works of course)\n" << std::flush; return 0; } if (!std::filesystem::exists(got::getDBpath())) { std::cerr << "The GOT database (" << got::getDBpath() << ") doesn't exist!" << std::endl; std::cerr << "Please run 'got' at least once before using this tool." << std::endl; return 1; } auto dpy_pair = x::XOpenDisplayRAII(nullptr); Display *dpy = dpy_pair.first; bool quitRequested = false; SeqMatcher matcher{dpy}; matcher.addSequence({XK_E}, []() { if (got::getRunning()) { if (auto descr = gui::promptText("Edit currently running entry's text:")) { got::editRunning(*descr); } } else { gui::showNotification("Cannot edit if not checked in"); } }); matcher.addSequence({XK_I}, []() { std::vector sheets = got::getSheets(); auto choice = gui::chooseList("Check in", "Sheet", sheets); if (choice) { auto current = got::getRunning(); if (current) { got::checkOut(); gui::showNotification("Checked out of sheet '" + current->first + "'"); } got::checkIn(*choice); gui::showNotification("Checked in to sheet '" + *choice + "'"); } }); matcher.addSequence({XK_O}, []() { auto current = got::getRunning(); if (current) { got::checkOut(); gui::showNotification("Checked out of sheet '" + current->first + "'"); } else { gui::showNotification("Cannot check out if not checked in"); } }); matcher.addSequence({XK_space}, []() { if (got::getRunning()) got::checkOut(); got::checkIn("misc"); gui::showNotification("Switched to 'misc'"); }); matcher.addSequence({XK_Break}, []() { auto current = got::getRunning(); if (!current) { gui::showNotification("Currently checked out"); } else { gui::showNotification( "Checked into '" + current->first + "'" + (current->second.empty() ? current->second : " (" + current->second + ")") ); } }); matcher.addSequence({XK_Q}, [&quitRequested]() { gui::showNotification("GOT GUI is quitting"); quitRequested = true; }); x::globalKeyWatch( dpy, XK_Break, [dpy, &matcher, &quitRequested](const XKeyEvent&) -> bool { matcher.reset(); SeqMatcher::Callback cb; x::globalKeyboardGrab(dpy, [&matcher, &cb](const XKeyEvent &ev) -> bool { auto opt_cb = matcher.observe(ev); if (opt_cb) { cb = *opt_cb; return true; } else { return false; } }); if (cb) cb(); return quitRequested; } ); }