├── logo.png
├── .krazy
├── icons
├── 128-apps-kronometer.png
├── 48-apps-kronometer.png
├── 64-apps-kronometer.png
├── sc-apps-kronometer.svgz
└── CMakeLists.txt
├── autotests
├── gui
│ ├── CMakeLists.txt
│ ├── testtimedisplay.h
│ └── testtimedisplay.cpp
├── CMakeLists.txt
└── core
│ ├── CMakeLists.txt
│ ├── teststopwatch.h
│ ├── testlap.h
│ ├── testsession.h
│ ├── testtimeformat.h
│ ├── teststopwatch.cpp
│ ├── testlap.cpp
│ ├── testtimeformat.cpp
│ └── testsession.cpp
├── .gitignore
├── src
├── gui
│ ├── kronometerui.qrc
│ ├── settings.kcfgc
│ ├── fontsettings.cpp
│ ├── colorsettings.cpp
│ ├── fontsettings.h
│ ├── colorsettings.h
│ ├── generalsettings.h
│ ├── CMakeLists.txt
│ ├── lapitemdelegate.h
│ ├── generalsettings.cpp
│ ├── lapitemdelegate.cpp
│ ├── colorsettings.ui
│ ├── sessiondialog.h
│ ├── timedisplay.ui
│ ├── kronometerui.rc
│ ├── sessiondialog.ui
│ ├── digitdisplay.h
│ ├── kronometer.kcfg
│ ├── timedisplay.h
│ ├── digitdisplay.cpp
│ ├── sessiondialog.cpp
│ ├── timedisplay.cpp
│ ├── mainwindow.h
│ └── fontsettings.ui
├── models
│ ├── CMakeLists.txt
│ ├── lapmodel.h
│ ├── sessionmodel.h
│ ├── lapmodel.cpp
│ └── sessionmodel.cpp
├── core
│ ├── CMakeLists.txt
│ ├── lap.cpp
│ ├── session.cpp
│ ├── lap.h
│ ├── stopwatch.cpp
│ ├── session.h
│ ├── timeformat.cpp
│ ├── stopwatch.h
│ └── timeformat.h
├── Mainpage.dox
├── CMakeLists.txt
└── main.cpp
├── Messages.sh
├── desktop
├── CMakeLists.txt
└── org.kde.kronometer.desktop
├── README.md
├── doc
├── CMakeLists.txt
├── man-kronometer.1.docbook
└── index.docbook
├── .gitlab-ci.yml
├── .kde-ci.yml
├── .flatpak-manifest.json
├── flatpak
└── org.kde.kronometer.json
├── CMakeLists.txt
├── po
├── sv
│ └── docs
│ │ └── kronometer
│ │ ├── man-kronometer.1.docbook
│ │ └── index.docbook
├── it
│ └── docs
│ │ └── kronometer
│ │ └── man-kronometer.1.docbook
├── nl
│ └── docs
│ │ └── kronometer
│ │ ├── man-kronometer.1.docbook
│ │ └── index.docbook
├── de
│ └── docs
│ │ └── kronometer
│ │ └── man-kronometer.1.docbook
├── pt
│ └── docs
│ │ └── kronometer
│ │ └── man-kronometer.1.docbook
├── pt_BR
│ └── docs
│ │ └── kronometer
│ │ └── man-kronometer.1.docbook
├── ca
│ └── docs
│ │ └── kronometer
│ │ └── man-kronometer.1.docbook
├── es
│ └── docs
│ │ └── kronometer
│ │ └── man-kronometer.1.docbook
└── uk
│ └── docs
│ └── kronometer
│ └── man-kronometer.1.docbook
├── CMakePresets.json
├── CHANGELOG
└── LICENSES
└── CC0-1.0.txt
/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KDE/kronometer/HEAD/logo.png
--------------------------------------------------------------------------------
/.krazy:
--------------------------------------------------------------------------------
1 | EXTRA camelcase,defines,multiclasses,null,qenums,qmath
2 | EXCLUDE postfixop
3 |
--------------------------------------------------------------------------------
/icons/128-apps-kronometer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KDE/kronometer/HEAD/icons/128-apps-kronometer.png
--------------------------------------------------------------------------------
/icons/48-apps-kronometer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KDE/kronometer/HEAD/icons/48-apps-kronometer.png
--------------------------------------------------------------------------------
/icons/64-apps-kronometer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KDE/kronometer/HEAD/icons/64-apps-kronometer.png
--------------------------------------------------------------------------------
/icons/sc-apps-kronometer.svgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KDE/kronometer/HEAD/icons/sc-apps-kronometer.svgz
--------------------------------------------------------------------------------
/autotests/gui/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | ecm_add_tests(
2 | testtimedisplay.cpp
3 | LINK_LIBRARIES Qt::Test gui)
4 |
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *build*/
2 | CMakeLists.txt.user
3 | *.kdev4
4 | cmake-build-debug/
5 | .idea/
6 | .vscode/
7 | compile_commands.json
8 | .cache
9 |
--------------------------------------------------------------------------------
/src/gui/kronometerui.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | kronometerui.rc
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/gui/settings.kcfgc:
--------------------------------------------------------------------------------
1 | File=kronometer.kcfg
2 | ClassName=KronometerConfig
3 | Singleton=true
4 | Mutators=true
5 | UseEnumTypes=true
6 | GenerateProperties=true
7 |
--------------------------------------------------------------------------------
/autotests/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | include(ECMAddTests)
2 |
3 | find_package(Qt6Test ${QT_MIN_VERSION} REQUIRED NO_MODULE)
4 |
5 | add_subdirectory(core)
6 | add_subdirectory(gui)
7 |
--------------------------------------------------------------------------------
/autotests/core/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | ecm_add_tests(
2 | testlap.cpp
3 | testsession.cpp
4 | teststopwatch.cpp
5 | testtimeformat.cpp
6 | LINK_LIBRARIES Qt::Test core)
7 |
--------------------------------------------------------------------------------
/Messages.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 | $EXTRACTRC `find . -name \*.rc -o -name \*.kcfg -o -name \*.ui` >> rc.cpp || exit 11
3 | $XGETTEXT `find . -name \*.h -o -name \*.cpp` -o $podir/kronometer.pot
4 |
--------------------------------------------------------------------------------
/desktop/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | install(FILES org.kde.kronometer.appdata.xml
2 | DESTINATION ${KDE_INSTALL_METAINFODIR})
3 | install(PROGRAMS org.kde.kronometer.desktop
4 | DESTINATION ${KDE_INSTALL_APPDIR})
5 |
--------------------------------------------------------------------------------
/icons/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | ecm_install_icons(
2 | ICONS
3 | 48-apps-kronometer.png
4 | 64-apps-kronometer.png
5 | 128-apps-kronometer.png
6 | sc-apps-kronometer.svgz
7 | DESTINATION ${KDE_INSTALL_ICONDIR})
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Kronometer
2 | ==========
3 |
4 | Kronometer is a simple stopwatch application.
5 |
6 | Homepage: https://userbase.kde.org/Kronometer
7 |
8 | Installation
9 | ============
10 |
11 | See https://userbase.kde.org/Kronometer#Installation
12 |
--------------------------------------------------------------------------------
/src/models/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | set(models_SRCS
2 | lapmodel.cpp lapmodel.h
3 | sessionmodel.cpp sessionmodel.h)
4 |
5 | add_library(models STATIC ${models_SRCS})
6 | target_link_libraries(models
7 | Qt::Core
8 | KF6::I18n
9 | core)
10 |
--------------------------------------------------------------------------------
/src/core/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | set(core_SRCS
2 | lap.cpp
3 | session.cpp
4 | stopwatch.cpp
5 | timeformat.cpp
6 | lap.h
7 | session.h
8 | stopwatch.h
9 | timeformat.h)
10 |
11 | add_library(core STATIC ${core_SRCS})
12 | target_link_libraries(core Qt::Core)
13 |
--------------------------------------------------------------------------------
/src/Mainpage.dox:
--------------------------------------------------------------------------------
1 | /**
2 |
3 | @mainpage Kronometer
4 |
5 | Here you can browse the Doxygen documentation for the [Kronometer](https://userbase.kde.org/Kronometer "Kronometer homepage") source code.
6 |
7 | @licenses @gpl
8 |
9 | */
10 |
11 | // What is this?
12 | // DOXYGEN_SET_PROJECT_NAME = Kronometer
13 |
--------------------------------------------------------------------------------
/doc/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # Create and install documentation files
2 |
3 | kdoctools_create_handbook(index.docbook
4 | INSTALL_DESTINATION ${KDE_INSTALL_DOCBUNDLEDIR}/en
5 | SUBDIR kronometer)
6 | kdoctools_create_manpage(man-kronometer.1.docbook
7 | 1
8 | INSTALL_DESTINATION
9 | ${KDE_INSTALL_MANDIR})
10 |
--------------------------------------------------------------------------------
/src/gui/fontsettings.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2016 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #include "fontsettings.h"
8 |
9 | FontSettings::FontSettings(QWidget *parent) : QWidget(parent)
10 | {
11 | setupUi(this);
12 | }
13 |
14 | #include "moc_fontsettings.cpp"
15 |
--------------------------------------------------------------------------------
/src/gui/colorsettings.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2016 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #include "colorsettings.h"
8 |
9 | ColorSettings::ColorSettings(QWidget *parent) : QWidget(parent)
10 | {
11 | setupUi(this);
12 | }
13 |
14 | #include "moc_colorsettings.cpp"
15 |
--------------------------------------------------------------------------------
/.gitlab-ci.yml:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: None
2 | # SPDX-License-Identifier: CC0-1.0
3 |
4 | include:
5 | - project: sysadmin/ci-utilities
6 | file:
7 | - /gitlab-templates/flatpak.yml
8 | - /gitlab-templates/linux-qt6.yml
9 | - /gitlab-templates/linux-qt6-next.yml
10 | - /gitlab-templates/freebsd-qt6.yml
11 | - /gitlab-templates/windows-qt6.yml
12 | - /gitlab-templates/documentation.yml
13 |
--------------------------------------------------------------------------------
/src/gui/fontsettings.h:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2014 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #ifndef FONTSETTINGS_H
8 | #define FONTSETTINGS_H
9 |
10 | #include "ui_fontsettings.h"
11 |
12 | class FontSettings : public QWidget, public Ui::FontSettings
13 | {
14 | Q_OBJECT
15 |
16 | public:
17 | explicit FontSettings(QWidget *parent = nullptr);
18 | };
19 |
20 | #endif
21 |
--------------------------------------------------------------------------------
/src/gui/colorsettings.h:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2014 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #ifndef COLORSETTINGS_H
8 | #define COLORSETTINGS_H
9 |
10 | #include "ui_colorsettings.h"
11 |
12 | class ColorSettings : public QWidget, public Ui::ColorSettings
13 | {
14 | Q_OBJECT
15 |
16 | public:
17 | explicit ColorSettings(QWidget *parent = nullptr);
18 | };
19 |
20 | #endif
21 |
--------------------------------------------------------------------------------
/autotests/gui/testtimedisplay.h:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2016 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #ifndef TESTTIMEDISPLAY_H
8 | #define TESTTIMEDISPLAY_H
9 |
10 | #include
11 |
12 | class TestTimeDisplay : public QObject
13 | {
14 | Q_OBJECT
15 |
16 | private Q_SLOTS:
17 |
18 | void testDefaultWidget();
19 | void testSetBackgroundColor();
20 | void testSetTextColor();
21 | };
22 |
23 | #endif
24 |
--------------------------------------------------------------------------------
/autotests/core/teststopwatch.h:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2015 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #ifndef TESTSTOPWATCH_H
8 | #define TESTSTOPWATCH_H
9 |
10 | #include
11 |
12 | class TestStopwatch : public QObject
13 | {
14 | Q_OBJECT
15 |
16 | private Q_SLOTS:
17 |
18 | void testInactive();
19 | void testRunning();
20 | void testPaused();
21 | void testReset();
22 | void testInitialize();
23 | };
24 |
25 | #endif
26 |
--------------------------------------------------------------------------------
/autotests/core/testlap.h:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2015 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #ifndef TESTLAP_H
8 | #define TESTLAP_H
9 |
10 | #include
11 |
12 | class TestLap : public QObject
13 | {
14 | Q_OBJECT
15 |
16 | private Q_SLOTS:
17 |
18 | void testDefaultLap();
19 | void testLapTime();
20 | void testRelativeTime();
21 | void testAbsoluteTime();
22 | void testNote();
23 | void testRawData();
24 | void testTimeTo();
25 | };
26 |
27 | #endif
28 |
--------------------------------------------------------------------------------
/.kde-ci.yml:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: None
2 | # SPDX-License-Identifier: CC0-1.0
3 |
4 | Dependencies:
5 | - 'on': ['Linux', 'FreeBSD', 'Windows']
6 | 'require':
7 | 'frameworks/extra-cmake-modules': '@latest-kf6'
8 | 'frameworks/kconfig': '@latest-kf6'
9 | 'frameworks/kcoreaddons': '@latest-kf6'
10 | 'frameworks/kcrash': '@latest-kf6'
11 | 'frameworks/kdoctools': '@latest-kf6'
12 | 'frameworks/ki18n': '@latest-kf6'
13 | 'frameworks/kwidgetsaddons': '@latest-kf6'
14 | 'frameworks/kxmlgui': '@latest-kf6'
15 |
16 | Options:
17 | require-passing-tests-on: ['Linux', 'FreeBSD', 'Windows']
18 |
--------------------------------------------------------------------------------
/autotests/core/testsession.h:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2015 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #ifndef TESTSESSION_H
8 | #define TESTSESSION_H
9 |
10 | #include
11 |
12 | class TestSession : public QObject
13 | {
14 | Q_OBJECT
15 |
16 | private Q_SLOTS:
17 |
18 | void testDefaultSession();
19 | void testTime();
20 | void testName();
21 | void testNote();
22 | void testDate();
23 | void testLaps();
24 | void testEquality();
25 | void testInequality();
26 | void testJson();
27 | };
28 |
29 | #endif
30 |
--------------------------------------------------------------------------------
/src/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | add_subdirectory(core)
2 | add_subdirectory(gui)
3 | add_subdirectory(models)
4 |
5 | include_directories(${CMAKE_BINARY_DIR}) # for version.h generated by cmake
6 | add_executable(kronometer main.cpp)
7 |
8 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
9 | target_compile_options(kronometer PRIVATE -pedantic)
10 | endif()
11 |
12 | target_link_libraries(kronometer
13 | KF6::CoreAddons
14 | KF6::Crash
15 | gui)
16 |
17 | install(TARGETS kronometer ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
18 | install(FILES gui/kronometer.kcfg
19 | DESTINATION ${KDE_INSTALL_KCFGDIR})
20 |
--------------------------------------------------------------------------------
/autotests/core/testtimeformat.h:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2015 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #ifndef TESTTIMEFORMAT_H
8 | #define TESTTIMEFORMAT_H
9 |
10 | #include
11 |
12 | class TestTimeFormat : public QObject
13 | {
14 | Q_OBJECT
15 |
16 | private Q_SLOTS:
17 |
18 | void testDefaultFormat();
19 | void testFullFormat();
20 | void testMinimalFormat();
21 | void testNoDividers();
22 | void testEquality();
23 | void testInequality();
24 | void testOverrideHours();
25 | void testOverrideMinutes();
26 | };
27 |
28 | #endif
29 |
--------------------------------------------------------------------------------
/src/gui/generalsettings.h:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2014 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #ifndef GENERALSETTINGS_H
8 | #define GENERALSETTINGS_H
9 |
10 | #include "ui_generalsettings.h"
11 |
12 | class GeneralSettings : public QWidget, public Ui::GeneralSettings
13 | {
14 | Q_OBJECT
15 |
16 | public:
17 | explicit GeneralSettings(QWidget *parent = nullptr);
18 |
19 | private Q_SLOTS:
20 |
21 | void showFractionsToggled(bool toggled);
22 | void showLapFractionsToggled(bool toggled);
23 | void enableLapsToggled(bool toggled);
24 | };
25 |
26 | #endif
27 |
--------------------------------------------------------------------------------
/.flatpak-manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "org.kde.kronometer",
3 | "branch": "master",
4 | "runtime": "org.kde.Platform",
5 | "runtime-version": "6.10",
6 | "sdk": "org.kde.Sdk",
7 | "command": "kronometer",
8 | "tags": ["nightly"],
9 | "desktop-file-name-suffix": " (Nightly)",
10 | "finish-args": ["--share=ipc", "--socket=fallback-x11", "--socket=wayland" ],
11 | "modules": [
12 | {
13 | "name": "kronometer",
14 | "buildsystem": "cmake-ninja",
15 | "config-opts": [ "-DBUILD_WITH_QT6=ON" ],
16 | "sources": [
17 | { "type": "dir", "path": "." }
18 | ]
19 | }
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/flatpak/org.kde.kronometer.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "org.kde.kronometer",
3 | "branch": "master",
4 | "rename-icon": "kronometer",
5 | "runtime": "org.kde.Platform",
6 | "runtime-version": "5.15-24.08",
7 | "sdk": "org.kde.Sdk",
8 | "command": "kronometer",
9 | "tags": [
10 | "nightly"
11 | ],
12 | "desktop-file-name-prefix": "(Nightly) ",
13 | "finish-args": [
14 | "--device=dri",
15 | "--share=ipc",
16 | "--socket=session-bus",
17 | "--socket=wayland",
18 | "--socket=x11-fallback"
19 | ],
20 | "modules": [
21 | {
22 | "name": "kronometer",
23 | "buildsystem": "cmake-ninja",
24 | "sources": [
25 | {
26 | "type": "dir",
27 | "path": "."
28 | }
29 | ]
30 | }
31 | ]
32 | }
33 |
--------------------------------------------------------------------------------
/src/gui/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | set(gui_SRCS
2 | colorsettings.cpp
3 | digitdisplay.cpp
4 | fontsettings.cpp
5 | generalsettings.cpp
6 | lapitemdelegate.cpp
7 | mainwindow.cpp
8 | sessiondialog.cpp
9 | timedisplay.cpp
10 | colorsettings.h
11 | digitdisplay.h
12 | fontsettings.h
13 | generalsettings.h
14 | lapitemdelegate.h
15 | mainwindow.h
16 | sessiondialog.h
17 | timedisplay.h
18 | )
19 |
20 | ki18n_wrap_ui(gui_SRCS
21 | colorsettings.ui
22 | fontsettings.ui
23 | generalsettings.ui
24 | sessiondialog.ui
25 | timedisplay.ui)
26 |
27 | qt_add_resources(gui_SRCS kronometerui.qrc)
28 | kconfig_add_kcfg_files(gui_SRCS settings.kcfgc GENERATE_MOC)
29 |
30 | add_library(gui STATIC ${gui_SRCS})
31 | target_link_libraries(gui
32 | Qt::Core
33 | Qt::Widgets
34 | KF6::I18n
35 | KF6::WidgetsAddons
36 | KF6::XmlGui
37 | core
38 | models)
39 |
--------------------------------------------------------------------------------
/src/gui/lapitemdelegate.h:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2022 Johnny Jazeix
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #ifndef LAPITEMDELEGATE_H
8 | #define LAPITEMDELEGATE_H
9 |
10 | #include
11 |
12 | class MainWindow;
13 | /**
14 | * @brief ItemDelegate to block the Return key press creating a new line
15 | * when editing a line.
16 | */
17 | class LapItemDelegate : public QItemDelegate {
18 | Q_OBJECT
19 |
20 | public:
21 | explicit LapItemDelegate(MainWindow *window);
22 | QWidget* createEditor(QWidget *parent,
23 | const QStyleOptionViewItem &option,
24 | const QModelIndex &index) const override;
25 |
26 | void onCloseEditor(QWidget *,
27 | QAbstractItemDelegate::EndEditHint) const;
28 |
29 | private:
30 | MainWindow *m_window;
31 | };
32 |
33 | #endif
34 |
--------------------------------------------------------------------------------
/src/gui/generalsettings.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2015 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #include "generalsettings.h"
8 |
9 | #include
10 |
11 | GeneralSettings::GeneralSettings(QWidget *parent) : QWidget(parent)
12 | {
13 | setupUi(this);
14 |
15 | connect(kcfg_showSecondFractions, &QCheckBox::toggled, this, &GeneralSettings::showFractionsToggled);
16 | connect(kcfg_showLapSecondFractions, &QCheckBox::toggled, this, &GeneralSettings::showLapFractionsToggled);
17 | connect(kcfg_isLapsRecordingEnabled, &QCheckBox::toggled, this, &GeneralSettings::enableLapsToggled);
18 | }
19 |
20 | void GeneralSettings::showFractionsToggled(bool toggled)
21 | {
22 | kcfg_fractionsType->setEnabled(toggled);
23 | }
24 |
25 | void GeneralSettings::showLapFractionsToggled(bool toggled)
26 | {
27 | kcfg_lapFractionsType->setEnabled(toggled);
28 | }
29 |
30 | void GeneralSettings::enableLapsToggled(bool toggled)
31 | {
32 | lapSettings->setVisible(toggled);
33 | }
34 |
35 | #include "moc_generalsettings.cpp"
36 |
--------------------------------------------------------------------------------
/src/gui/lapitemdelegate.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2022 Johnny Jazeix
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #include "lapitemdelegate.h"
8 | #include "mainwindow.h"
9 |
10 | #include
11 | #include
12 |
13 | LapItemDelegate::LapItemDelegate(MainWindow *window) : QItemDelegate(window),
14 | m_window{window}
15 | {
16 | connect(this, &QItemDelegate::closeEditor, this, &LapItemDelegate::onCloseEditor);
17 | }
18 |
19 | QWidget* LapItemDelegate::createEditor(QWidget *parent,
20 | const QStyleOptionViewItem &option,
21 | const QModelIndex &index) const
22 | {
23 | m_window->enableLapShortcuts(false);
24 | return QItemDelegate::createEditor(parent, option, index);
25 | }
26 | void LapItemDelegate::onCloseEditor(QWidget *,
27 | QAbstractItemDelegate::EndEditHint) const
28 | {
29 | m_window->enableLapShortcuts(true);
30 | }
31 |
32 | #include "moc_lapitemdelegate.cpp"
33 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.16)
2 | project(kronometer)
3 |
4 | set(QT_MIN_VERSION "6.5.0")
5 | set(KF_MIN_VERSION "6.0.0")
6 |
7 | set(PROJECT_VERSION 2.3.70)
8 |
9 | set(CMAKE_CXX_STANDARD 17)
10 | set(CXX_STANDARD_REQUIRED ON)
11 |
12 | find_package(ECM ${KF_MIN_VERSION} REQUIRED NO_MODULE)
13 | set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH})
14 |
15 | include(KDEInstallDirs)
16 | include(KDECMakeSettings)
17 | include(KDECompilerSettings NO_POLICY_SCOPE)
18 | include(ECMInstallIcons)
19 | include(ECMSetupVersion)
20 | include(FeatureSummary)
21 | include(ECMDeprecationSettings)
22 |
23 | find_package(Qt6 ${QT_MIN_VERSION} REQUIRED
24 | COMPONENTS
25 | Core
26 | Gui
27 | Widgets)
28 |
29 | find_package(KF6 ${KF_MIN_VERSION} REQUIRED
30 | COMPONENTS
31 | CoreAddons
32 | Config
33 | Crash
34 | DocTools
35 | I18n
36 | WidgetsAddons
37 | XmlGui)
38 |
39 | ecm_setup_version(${PROJECT_VERSION}
40 | VARIABLE_PREFIX KRONOMETER
41 | VERSION_HEADER version.h)
42 |
43 | add_definitions(
44 | -DQT_NO_CAST_FROM_ASCII
45 | -DQT_NO_CAST_TO_ASCII
46 | -DQT_USE_QSTRINGBUILDER)
47 |
48 | ecm_set_disabled_deprecation_versions(QT 5.15.2
49 | KF 5.102
50 | )
51 |
52 | add_subdirectory(desktop)
53 | add_subdirectory(src)
54 | add_subdirectory(icons)
55 | add_subdirectory(autotests)
56 |
57 | ki18n_install(po)
58 | if(KF6DocTools_FOUND)
59 | add_subdirectory(doc)
60 | kdoctools_install(po)
61 | endif()
62 |
63 | feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
64 |
--------------------------------------------------------------------------------
/autotests/core/teststopwatch.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2015 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #include "teststopwatch.h"
8 | #include "stopwatch.h"
9 |
10 | void TestStopwatch::testInactive()
11 | {
12 | Stopwatch stopwatch;
13 |
14 | QVERIFY(!stopwatch.isRunning());
15 | QVERIFY(!stopwatch.isPaused());
16 | QVERIFY(stopwatch.isInactive());
17 | }
18 |
19 | void TestStopwatch::testRunning()
20 | {
21 | Stopwatch stopwatch;
22 |
23 | stopwatch.start();
24 |
25 | QVERIFY(stopwatch.isRunning());
26 | QVERIFY(!stopwatch.isPaused());
27 | QVERIFY(!stopwatch.isInactive());
28 | }
29 |
30 | void TestStopwatch::testPaused()
31 | {
32 | Stopwatch stopwatch;
33 |
34 | stopwatch.pause();
35 |
36 | QVERIFY(!stopwatch.isRunning());
37 | QVERIFY(stopwatch.isPaused());
38 | QVERIFY(!stopwatch.isInactive());
39 | }
40 |
41 | void TestStopwatch::testReset()
42 | {
43 | Stopwatch stopwatch;
44 |
45 | stopwatch.reset();
46 |
47 | QVERIFY(!stopwatch.isRunning());
48 | QVERIFY(!stopwatch.isPaused());
49 | QVERIFY(stopwatch.isInactive());
50 | }
51 |
52 | void TestStopwatch::testInitialize()
53 | {
54 | Stopwatch s1, s2;
55 |
56 | s1.start();
57 | QTest::qSleep(100);
58 | s1.pause();
59 | int t = s1.raw();
60 |
61 | QVERIFY(s2.initialize(t));
62 | QVERIFY(s2.isPaused());
63 | QCOMPARE(s2.raw(), t);
64 | }
65 |
66 | QTEST_MAIN(TestStopwatch)
67 |
68 | #include "moc_teststopwatch.cpp"
69 |
--------------------------------------------------------------------------------
/autotests/gui/testtimedisplay.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2016 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #include "testtimedisplay.h"
8 | #include "timedisplay.h"
9 |
10 | #include "digitdisplay.h"
11 |
12 | #include
13 |
14 | void TestTimeDisplay::testDefaultWidget()
15 | {
16 | TimeDisplay timeDisplay;
17 |
18 | const auto groupBoxes = timeDisplay.findChildren();
19 | QCOMPARE(groupBoxes.size(), 4);
20 |
21 | for (auto group : groupBoxes) {
22 | QCOMPARE(group->findChildren().size(), 1);
23 | QVERIFY(!group->title().isEmpty());
24 | }
25 | }
26 |
27 | void TestTimeDisplay::testSetBackgroundColor()
28 | {
29 | const auto color = qApp->palette().base().color();
30 |
31 | TimeDisplay timeDisplay;
32 | timeDisplay.setBackgroundColor(color);
33 |
34 | const auto groupBoxes = timeDisplay.findChildren();
35 | for (auto group : groupBoxes) {
36 | QCOMPARE(group->palette().color(group->backgroundRole()), color);
37 | }
38 | }
39 |
40 | void TestTimeDisplay::testSetTextColor()
41 | {
42 | const auto color = qApp->palette().text().color();
43 |
44 | TimeDisplay timeDisplay;
45 | timeDisplay.setTextColor(color);
46 |
47 | const auto groupBoxes = timeDisplay.findChildren();
48 | for (auto group : groupBoxes) {
49 | QCOMPARE(group->palette().color(group->foregroundRole()), color);
50 | }
51 | }
52 |
53 | QTEST_MAIN(TestTimeDisplay)
54 |
55 | #include "moc_testtimedisplay.cpp"
56 |
--------------------------------------------------------------------------------
/autotests/core/testlap.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2015 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #include "testlap.h"
8 | #include "lap.h"
9 |
10 | #include
11 |
12 | void TestLap::testDefaultLap()
13 | {
14 | Lap lap;
15 |
16 | QCOMPARE(lap.time(), QTime(0, 0));
17 | QCOMPARE(lap.raw(), 0);
18 | QVERIFY(lap.relativeTime().isEmpty());
19 | QVERIFY(lap.absoluteTime().isEmpty());
20 | }
21 |
22 | void TestLap::testLapTime()
23 | {
24 | QTime time {1, 30};
25 | Lap lap {time};
26 |
27 | QCOMPARE(lap.time(), time);
28 | }
29 |
30 | void TestLap::testRelativeTime()
31 | {
32 | Lap lap;
33 | auto test = QLatin1String("test");
34 |
35 | lap.setRelativeTime(test);
36 |
37 | QCOMPARE(lap.relativeTime(), test);
38 | }
39 |
40 | void TestLap::testAbsoluteTime()
41 | {
42 | Lap lap;
43 | auto test = QLatin1String("test");
44 |
45 | lap.setAbsoluteTime(test);
46 |
47 | QCOMPARE(lap.absoluteTime(), test);
48 | }
49 |
50 | void TestLap::testNote()
51 | {
52 | Lap lap;
53 | auto test = QLatin1String("test");
54 |
55 | lap.setNote(test);
56 |
57 | QCOMPARE(lap.note(), test);
58 | }
59 |
60 | void TestLap::testRawData()
61 | {
62 | int t = 1000;
63 | Lap lap = Lap::fromRawData(t);
64 |
65 | QCOMPARE(lap.raw(), t);
66 | }
67 |
68 | void TestLap::testTimeTo()
69 | {
70 | int t1 = 50;
71 | int t2 = 100;
72 |
73 | Lap lap1 = Lap::fromRawData(t1);
74 | Lap lap2 = Lap::fromRawData(t2);
75 |
76 | QCOMPARE(lap1.timeTo(lap2).msec(), t2 - t1);
77 | }
78 |
79 | QTEST_MAIN(TestLap)
80 |
81 | #include "moc_testlap.cpp"
82 |
--------------------------------------------------------------------------------
/src/gui/colorsettings.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | ColorSettings
4 |
5 |
6 |
7 | 0
8 | 0
9 | 1077
10 | 487
11 |
12 |
13 |
14 |
15 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
16 |
17 | -
18 |
19 |
20 | Display Background:
21 |
22 |
23 |
24 | -
25 |
26 |
27 | Background color of the stopwatch display
28 |
29 |
30 |
31 | -
32 |
33 |
34 | Display Digits:
35 |
36 |
37 |
38 | -
39 |
40 |
41 | Color of the stopwatch display digits
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | KColorButton
50 | QPushButton
51 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/src/gui/sessiondialog.h:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2015 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #ifndef SESSIONDIALOG_H
8 | #define SESSIONDIALOG_H
9 |
10 | #include "ui_sessiondialog.h"
11 | #include "session.h"
12 |
13 | #include
14 |
15 | class SessionModel;
16 |
17 | class KMessageWidget;
18 |
19 | class QDialogButtonBox;
20 | class QSortFilterProxyModel;
21 | class QTableView;
22 |
23 | /**
24 | * @brief Dialog for sessions interaction.
25 | */
26 | class SessionDialog : public QDialog, public Ui::SessionDialog
27 | {
28 | Q_OBJECT
29 |
30 | public:
31 |
32 | explicit SessionDialog(SessionModel *sessionModel, QWidget *parent = nullptr);
33 |
34 | Session selectedSession() const;
35 |
36 | public Q_SLOTS:
37 |
38 | virtual void accept() override;
39 |
40 | protected:
41 |
42 | virtual void keyPressEvent(QKeyEvent *event) override;
43 |
44 | private Q_SLOTS:
45 |
46 | /**
47 | * Call accept() if the selection's column is not editable.
48 | * @param index The selected index.
49 | */
50 | void slotDoubleClicked(const QModelIndex& index);
51 |
52 | /**
53 | * Disable the OK button if no session is selected.
54 | */
55 | void slotSelectionChanged();
56 |
57 | /**
58 | * Enable the OK button after the first session is added.
59 | */
60 | void slotSessionAdded();
61 |
62 | /**
63 | * Disable the OK button if no session is available.
64 | */
65 | void slotEmptyModel();
66 |
67 | private:
68 |
69 | SessionModel *m_sessionModel;
70 | QSortFilterProxyModel *m_proxyModel;
71 | Session m_selectedSession;
72 |
73 | /**
74 | * @return The actual selected index in the view.
75 | */
76 | QModelIndex selectedIndex();
77 |
78 | /**
79 | * Ask confirm to the user before removing a session.
80 | */
81 | void removeDialog();
82 |
83 | Q_DISABLE_COPY(SessionDialog)
84 | };
85 |
86 | #endif
87 |
--------------------------------------------------------------------------------
/src/core/lap.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2014 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #include "lap.h"
8 |
9 | #include
10 |
11 | Lap::Lap(const QTime& lap) :
12 | m_time {lap}
13 | {}
14 |
15 | QTime Lap::time() const
16 | {
17 | return m_time;
18 | }
19 |
20 | QTime Lap::timeTo(const Lap& lap) const
21 | {
22 | if (lap.time() < m_time)
23 | return {0, 0};
24 |
25 | const auto zero = QTime {0, 0};
26 | return zero.addMSecs(m_time.msecsTo(lap.time()));
27 | }
28 |
29 | void Lap::setRelativeTime(const QString& rel)
30 | {
31 | m_relativeTime = rel;
32 | }
33 |
34 | QString Lap::relativeTime() const
35 | {
36 | return m_relativeTime;
37 | }
38 |
39 | void Lap::setAbsoluteTime(const QString& abs)
40 | {
41 | m_absoluteTime = abs;
42 | }
43 |
44 | QString Lap::absoluteTime() const
45 | {
46 | return m_absoluteTime;
47 | }
48 |
49 | void Lap::setNote(const QString& note)
50 | {
51 | m_note = note;
52 | }
53 |
54 | QString Lap::note() const
55 | {
56 | return m_note;
57 | }
58 |
59 | int Lap::raw() const
60 | {
61 | const auto zero = QTime {0, 0};
62 | return zero.msecsTo(m_time);
63 | }
64 |
65 | void Lap::write(QJsonObject& json) const
66 | {
67 | json[QStringLiteral("time")] = raw();
68 | json[QStringLiteral("reltime")] = m_relativeTime;
69 | json[QStringLiteral("abstime")] = m_absoluteTime;
70 | json[QStringLiteral("note")] = m_note;
71 | }
72 |
73 | Lap Lap::fromJson(const QJsonObject& json)
74 | {
75 | auto lap = fromRawData(json[QStringLiteral("time")].toInt());
76 | lap.m_relativeTime = json[QStringLiteral("reltime")].toString();
77 | lap.m_absoluteTime = json[QStringLiteral("abstime")].toString();
78 | lap.m_note = json[QStringLiteral("note")].toString();
79 |
80 | return lap;
81 | }
82 |
83 | Lap Lap::fromRawData(int rawData)
84 | {
85 | if (rawData < 0) {
86 | return Lap {};
87 | }
88 |
89 | const auto zero = QTime {0, 0};
90 | return Lap {zero.addMSecs(rawData)};
91 | }
92 |
--------------------------------------------------------------------------------
/src/main.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2014 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #include "sessionmodel.h"
8 | #include "mainwindow.h"
9 | #include "version.h"
10 |
11 | #include
12 | #include
13 | #include
14 |
15 | #include
16 | #include
17 | #include
18 | #include
19 |
20 | int main (int argc, char **argv)
21 | {
22 | QApplication app {argc, argv};
23 | KLocalizedString::setApplicationDomain("kronometer");
24 |
25 | KCrash::initialize();
26 |
27 | auto aboutData = KAboutData {
28 | QStringLiteral("kronometer"), // componentName
29 | i18nc("KAboutData display name", "Kronometer"),
30 | QStringLiteral(KRONOMETER_VERSION_STRING),
31 | i18n("Kronometer is a simple stopwatch application"), // shortDescription
32 | KAboutLicense::GPL_V2, // licenseType
33 | i18n("Copyright (C) 2014-2016 Elvis Angelaccio"), // copyrightStatement
34 | {}, // otherText
35 | QStringLiteral("https://userbase.kde.org/Kronometer") // homePageAddress
36 | };
37 |
38 | aboutData.addAuthor(
39 | i18n("Elvis Angelaccio"),
40 | i18n("Maintainer"),
41 | QStringLiteral("elvis.angelaccio@kde.org"),
42 | QStringLiteral("https://eang.it")
43 | );
44 |
45 | aboutData.addCredit(
46 | i18n("Ken Vermette"),
47 | i18n("Kronometer icon"),
48 | QStringLiteral("vermette@gmail.com")
49 | );
50 |
51 | KAboutData::setApplicationData(aboutData);
52 | app.setWindowIcon(QIcon::fromTheme(QStringLiteral("kronometer")));
53 |
54 | // Make sure that the local data directory is available.
55 | auto appdata = QFileInfo {QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)};
56 | if (!appdata.exists()) {
57 | auto dir = QDir {appdata.absolutePath()};
58 | dir.mkdir(appdata.fileName());
59 | }
60 |
61 | SessionModel sessionModel;
62 | auto window = new MainWindow {&sessionModel};
63 | window->show();
64 |
65 | return app.exec();
66 | }
67 |
--------------------------------------------------------------------------------
/src/gui/timedisplay.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | TimeDisplay
4 |
5 |
6 |
7 | 0
8 |
9 |
10 | 0
11 |
12 |
13 | 0
14 |
15 | -
16 |
17 |
18 | Hours
19 |
20 |
21 |
-
22 |
23 |
24 |
25 |
26 |
27 | -
28 |
29 |
30 | Minutes
31 |
32 |
33 |
-
34 |
35 |
36 |
37 |
38 |
39 | -
40 |
41 |
42 | Seconds
43 |
44 |
45 |
-
46 |
47 |
48 |
49 |
50 |
51 | -
52 |
53 |
54 | Hundredths
55 |
56 |
57 |
-
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | DigitDisplay
68 | QWidget
69 |
70 | 1
71 |
72 |
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/src/gui/kronometerui.rc:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
10 |
17 |
18 |
19 |
20 | Kronometer Toolbar
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/src/gui/sessiondialog.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | SessionDialog
4 |
5 |
6 |
7 | 0
8 | 0
9 | 400
10 | 300
11 |
12 |
13 |
14 | Open Session
15 |
16 |
17 | -
18 |
19 |
20 | -
21 |
22 |
23 | QAbstractItemView::SingleSelection
24 |
25 |
26 | QAbstractItemView::SelectRows
27 |
28 |
29 | Qt::DotLine
30 |
31 |
32 | true
33 |
34 |
35 | true
36 |
37 |
38 | false
39 |
40 |
41 |
42 | -
43 |
44 |
45 | Qt::Horizontal
46 |
47 |
48 | QDialogButtonBox::Cancel|QDialogButtonBox::Ok
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | KMessageWidget
57 | QFrame
58 |
59 |
60 |
61 |
62 |
63 |
64 | m_buttonBox
65 | accepted()
66 | SessionDialog
67 | accept()
68 |
69 |
70 | 248
71 | 254
72 |
73 |
74 | 157
75 | 274
76 |
77 |
78 |
79 |
80 | m_buttonBox
81 | rejected()
82 | SessionDialog
83 | reject()
84 |
85 |
86 | 316
87 | 260
88 |
89 |
90 | 286
91 | 274
92 |
93 |
94 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/doc/man-kronometer.1.docbook:
--------------------------------------------------------------------------------
1 |
2 |
4 | ]>
5 |
6 |
7 |
8 | 2016-04-10
9 | kronometer 2.0
10 |
11 |
12 |
13 | kronometer
14 | 1
15 | April 2016
16 | KRONOMETER 2.1.0
17 |
18 |
19 | kronometer
20 | stopwatch application
21 |
22 |
23 |
24 |
25 | kronometer
26 |
27 |
28 |
29 | DESCRIPTION
30 | Kronometer is a stopwatch (timer/chronometer) application.
31 |
32 | Kronometer’s main features are the following:
33 |
34 |
35 |
36 | Start/pause/resume the stopwatch widget;
37 |
38 |
39 | Laps recording: you can capture the stopwatch time when you want;
40 |
41 |
42 | Lap times sorting: you can easily find the shortest lap time or the
43 | longest one;
44 |
45 |
46 | Reset the stopwatch widget and the lap times;
47 |
48 |
49 | Time format settings: you can choose the stopwatch granularity;
50 |
51 |
52 | Times saving and resuming: you can save the stopwatch status and
53 | resume it later;
54 |
55 |
56 | Font customization: you can choose the fonts for each of the stopwatch
57 | digits;
58 |
59 |
60 | Color customization: you can choose the color for the stopwatch digits
61 | and the stopwatch background;
62 |
63 |
64 | Lap times export: you can export the lap times on a file using the JSON
65 | or CSV format.
66 |
67 |
68 |
69 |
70 |
71 | AUTHOR
72 | The KRONOMETER was written by Elvis Angelaccio <elvis.angelaccio@kde.org>.
73 |
74 | This manual page was written by Joao Eriberto Mota Filho <eriberto@debian.org>
75 | for the Debian project (but may be used by others).
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/autotests/core/testtimeformat.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2015 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #include "testtimeformat.h"
8 | #include "timeformat.h"
9 |
10 | #include
11 |
12 | void TestTimeFormat::testDefaultFormat()
13 | {
14 | TimeFormat timeFormat;
15 | QTime t {0, 0};
16 |
17 | QCOMPARE(timeFormat.format(t), QStringLiteral("00:00.00"));
18 | QCOMPARE(timeFormat.secondFractions(), TimeFormat::UpToHundredths);
19 | QVERIFY(!timeFormat.hasHours());
20 | QVERIFY(timeFormat.hasMinutes());
21 | QVERIFY(timeFormat.hasFractions());
22 | }
23 |
24 | void TestTimeFormat::testFullFormat()
25 | {
26 | TimeFormat timeFormat {true, true, TimeFormat::UpToMilliseconds};
27 | QTime t {0, 0};
28 |
29 | QCOMPARE(timeFormat.format(t), QStringLiteral("00:00:00.000"));
30 | QCOMPARE(timeFormat.secondFractions(), TimeFormat::UpToMilliseconds);
31 | QVERIFY(timeFormat.hasHours());
32 | QVERIFY(timeFormat.hasMinutes());
33 | QVERIFY(timeFormat.hasFractions());
34 | }
35 |
36 | void TestTimeFormat::testMinimalFormat()
37 | {
38 | TimeFormat timeFormat {false, false, TimeFormat::NoFractions};
39 | QTime t {0, 0};
40 |
41 | QCOMPARE(timeFormat.format(t), QStringLiteral("00"));
42 | QCOMPARE(timeFormat.secondFractions(), TimeFormat::NoFractions);
43 | QVERIFY(!timeFormat.hasHours());
44 | QVERIFY(!timeFormat.hasMinutes());
45 | QVERIFY(!timeFormat.hasFractions());
46 | }
47 |
48 | void TestTimeFormat::testNoDividers()
49 | {
50 | TimeFormat timeFormat;
51 | QTime t {0, 0};
52 |
53 | timeFormat.showDividers(false);
54 |
55 | QCOMPARE(timeFormat.format(t), QStringLiteral("000000"));
56 | }
57 |
58 | void TestTimeFormat::testEquality()
59 | {
60 | TimeFormat timeFormat1;
61 | TimeFormat timeFormat2;
62 |
63 | QCOMPARE(timeFormat1, timeFormat2);
64 | }
65 |
66 | void TestTimeFormat::testInequality()
67 | {
68 | TimeFormat timeFormat1;
69 | TimeFormat timeFormat2 {true, false};
70 |
71 | QVERIFY(timeFormat1 != timeFormat2);
72 | }
73 |
74 | void TestTimeFormat::testOverrideHours()
75 | {
76 | TimeFormat timeFormat {false, true, TimeFormat::NoFractions};
77 | QTime t {0, 0};
78 |
79 | QCOMPARE(timeFormat.format(t), QStringLiteral("00:00"));
80 |
81 | timeFormat.overrideHours();
82 |
83 | QCOMPARE(timeFormat.format(t), QStringLiteral("00:00:00"));
84 | }
85 |
86 | void TestTimeFormat::testOverrideMinutes()
87 | {
88 | TimeFormat timeFormat {false, false, TimeFormat::UpToTenths};
89 | QTime t {0, 0};
90 |
91 | QCOMPARE(timeFormat.format(t), QStringLiteral("00.0"));
92 |
93 | timeFormat.overrideMinutes();
94 |
95 | QCOMPARE(timeFormat.format(t), QStringLiteral("00:00.0"));
96 | }
97 |
98 | QTEST_MAIN(TestTimeFormat)
99 |
100 | #include "moc_testtimeformat.cpp"
101 |
--------------------------------------------------------------------------------
/src/models/lapmodel.h:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2014 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #ifndef LAPMODEL_H
8 | #define LAPMODEL_H
9 |
10 | #include "lap.h"
11 | #include "timeformat.h"
12 |
13 | #include
14 |
15 | class QTime;
16 |
17 | /**
18 | * @brief A LapModel is a Model for lap times.
19 | * A LapModel holds a list of times. Every time is meant to be the absolute time of a lap.
20 | * The model can also show the relative time of the lap, computing the difference between two consecutive absolute times.
21 | */
22 | class LapModel : public QAbstractTableModel
23 | {
24 | Q_OBJECT
25 |
26 | public:
27 |
28 | enum class Roles
29 | {
30 | LapIdRole = Qt::UserRole,
31 | RelativeTimeRole,
32 | AbsoluteTimeRole,
33 | NoteRole,
34 | LapRole
35 | };
36 |
37 | explicit LapModel(QObject *parent = nullptr);
38 |
39 | int rowCount(const QModelIndex& parent = {}) const override;
40 | int columnCount(const QModelIndex& parent = {}) const override;
41 | QVariant data(const QModelIndex& index, int role) const override;
42 | QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
43 | bool setData(const QModelIndex& index, const QVariant& value, int role) override;
44 | Qt::ItemFlags flags(const QModelIndex& index) const override;
45 |
46 | /**
47 | * Update the lap times format used by the model.
48 | * @param format The times format to be used.
49 | */
50 | void setTimeFormat(const TimeFormat& format);
51 |
52 | /**
53 | * Insert a new Lap object to the end of the model.
54 | * @param lap The new Lap object.
55 | */
56 | void append(const Lap& lap);
57 |
58 | /**
59 | * @return Whether the model does not hold any lap.
60 | */
61 | bool isEmpty() const;
62 |
63 | /**
64 | * @return The index of the column for the given role.
65 | */
66 | int columnForRole(Roles role) const;
67 |
68 | public Q_SLOTS:
69 |
70 | /**
71 | * Add a new absolute lap time to the model.
72 | * @param lapTime The absolute time of the new lap.
73 | */
74 | void addLap(const QTime& lapTime);
75 |
76 | /**
77 | * Clear all the model data
78 | */
79 | void clear();
80 |
81 | private:
82 |
83 | const QVector m_roles {Roles::LapIdRole, Roles::RelativeTimeRole, Roles::AbsoluteTimeRole, Roles::NoteRole};
84 |
85 | QVector m_laps; /** Lap times */
86 | TimeFormat m_timeFormat; /** Current lap times format */
87 |
88 | /**
89 | * Reload the model data.
90 | */
91 | void reload();
92 |
93 | /**
94 | * @return The role for the given column.
95 | */
96 | Roles roleForColumn(int column) const;
97 |
98 | Q_DISABLE_COPY(LapModel)
99 | };
100 |
101 |
102 | #endif
103 |
--------------------------------------------------------------------------------
/src/gui/digitdisplay.h:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2014 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #ifndef DIGITDISPLAY_H
8 | #define DIGITDISPLAY_H
9 |
10 | #include
11 |
12 | class QLabel;
13 |
14 | /**
15 | * @brief A custom widget displaying up to three digits.
16 | * This widget is meant to be used as a QLabel replacement to display the digits
17 | * of a timer component (minutes, seconds, etc.). By default a QLabel displays
18 | * a single text and if the font is not monospace this might look bad when the
19 | * text is refreshed very quickly, as in a stopwatch timer. This widget instead
20 | * displays the text by splitting it into up to three different strings, displayed
21 | * in different QLabels within a horizontal layout. (i.e. simulating a monospace font
22 | * using adequate padding).
23 | */
24 | class DigitDisplay : public QWidget
25 | {
26 | Q_OBJECT
27 |
28 | public:
29 |
30 | enum class Digits
31 | {
32 | One, /**< Display one digit. */
33 | Two, /**< Display two digits. */
34 | Three, /**< Display three digits. */
35 | None /**< Display no digit. */
36 | };
37 |
38 | explicit DigitDisplay(QWidget *parent = nullptr, Digits digits = Digits::None);
39 |
40 | /**
41 | * Set the number of digits to be displayed.
42 | * @param digits The number of digits to be displayed.
43 | */
44 | void setDigits(Digits digits);
45 |
46 | /**
47 | * The digits to be displayed.
48 | * The input string shall have a length equal to the internal digit counter.
49 | * Otherwise nothing is displayed.
50 | * @param digits The digits string to be displayed.
51 | */
52 | void showDigits(const QString& digits) const;
53 |
54 | /**
55 | * Set a custom font for the widget labels.
56 | * @param font The custom font to set.
57 | */
58 | void setFont(const QFont& font);
59 |
60 | virtual QSize minimumSizeHint() const override;
61 |
62 | private:
63 |
64 | QLabel *m_leftmostDigit;
65 | QLabel *m_centerDigit;
66 | QLabel *m_rightmostDigit;
67 |
68 | QFont m_displayFont;
69 | Digits m_digits;
70 |
71 | /**
72 | * @return Whether the length of @p text is consistent with the display digits.
73 | */
74 | bool isValid(const QString& text) const;
75 |
76 | /**
77 | * Helper function to display a single digit.
78 | * @param digit The digit to be displayed.
79 | */
80 | void showOneDigit(const QString& digit) const;
81 |
82 | /**
83 | * Helper function to display two digits.
84 | * @param digits The digits to be displayed.
85 | */
86 | void showTwoDigits(const QString& digits) const;
87 |
88 | /**
89 | * Helper function to display three digits.
90 | * @param digits The digits to be displayed.
91 | */
92 | void showThreeDigits(const QString& digits) const;
93 |
94 | Q_DISABLE_COPY(DigitDisplay)
95 | };
96 |
97 | #endif
98 |
--------------------------------------------------------------------------------
/src/core/session.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2015 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #include "session.h"
8 |
9 | #include
10 | #include
11 |
12 | Session::Session(int time, const QDateTime& date) :
13 | m_time {time},
14 | m_date {date}
15 | {}
16 |
17 | void Session::setName(const QString& name)
18 | {
19 | m_name = name;
20 | }
21 |
22 | void Session::setNote(const QString& note)
23 | {
24 | m_note = note;
25 | }
26 |
27 | void Session::setTime(int time)
28 | {
29 | m_time = time;
30 | }
31 |
32 | void Session::setDate(const QDateTime& date)
33 | {
34 | m_date = date;
35 | }
36 |
37 | void Session::setIsOutdated(bool isOutdated)
38 | {
39 | m_isOutdated = isOutdated;
40 | }
41 |
42 | QString Session::name() const
43 | {
44 | return m_name;
45 | }
46 |
47 | QString Session::note() const
48 | {
49 | return m_note;
50 | }
51 |
52 | int Session::time() const
53 | {
54 | return m_time;
55 | }
56 |
57 | QDateTime Session::date() const
58 | {
59 | return m_date;
60 | }
61 |
62 | bool Session::isOutdated() const
63 | {
64 | return m_isOutdated;
65 | }
66 |
67 | QVector Session::laps() const
68 | {
69 | return m_laps;
70 | }
71 |
72 | bool Session::isEmpty() const
73 | {
74 | return m_time == 0;
75 | }
76 |
77 | void Session::addLap(const Lap& lap)
78 | {
79 | m_laps.append(lap);
80 | }
81 |
82 | void Session::clear()
83 | {
84 | m_time = 0;
85 | m_laps.clear();
86 | }
87 |
88 | void Session::write(QJsonObject& json) const
89 | {
90 | json[QStringLiteral("name")] = m_name;
91 | json[QStringLiteral("note")] = m_note;
92 | json[QStringLiteral("time")] = m_time;
93 | json[QStringLiteral("date")] = m_date.toString(Qt::ISODate);
94 |
95 | auto laps = QJsonArray {};
96 |
97 | for (const auto& lap : m_laps) {
98 | auto object = QJsonObject {};
99 | lap.write(object);
100 | laps.append(object);
101 | }
102 |
103 | json[QStringLiteral("laps")] = laps;
104 | }
105 |
106 | Session Session::fromJson(const QJsonObject& json)
107 | {
108 | auto session = Session {};
109 |
110 | session.m_name = json[QStringLiteral("name")].toString();
111 | session.m_note = json[QStringLiteral("note")].toString();
112 | session.m_time = json[QStringLiteral("time")].toInt();
113 | session.m_date = QDateTime::fromString(json[QStringLiteral("date")].toString(), Qt::ISODate);
114 |
115 | const auto laps = json[QStringLiteral("laps")].toArray();
116 | for (const auto& lap : laps) {
117 | session.addLap(Lap::fromJson(lap.toObject()));
118 | }
119 |
120 | return session;
121 | }
122 |
123 | bool Session::operator==(const Session& right) const
124 | {
125 | return m_date == right.m_date;
126 | }
127 |
128 | bool Session::operator!=(const Session& right) const
129 | {
130 | return !(*this == right);
131 | }
132 |
133 |
--------------------------------------------------------------------------------
/po/sv/docs/kronometer/man-kronometer.1.docbook:
--------------------------------------------------------------------------------
1 |
2 |
4 | ]>
5 |
6 |
7 |
8 | 2016-04-10
10 | kronometer 2.0
12 |
13 |
14 |
15 | kronometer
17 | 1
19 | April 2016
21 | Kronometer 2.1.0
23 |
24 |
25 | kronometer
27 | Tidtagarurprogram
29 |
30 |
31 |
32 |
33 | kronometer
35 |
36 |
37 |
38 | Beskrivning
41 | Kronometer är ett tidtagarurprogram (stoppur/kronometer).
43 |
44 | Huvudfunktionerna i Kronometer är följande:
46 |
47 |
48 |
49 | Starta, pausa, återstarta tidtagarurets grafiska komponent,
51 |
52 |
53 | Varvtider: Det går att lagra tidtagarurets tid när man vill,
55 |
56 |
57 | Sortering av varvtider: Det är enkelt att hitta den kortaste eller längsta varvtiden,
59 |
60 |
61 | Nollställ tidtagarurets grafiska komponent och varvtiderna,
63 |
64 |
65 | Inställning av tidsformat: Det går att välja tidtagarurets upplösning,
67 |
68 |
69 | Spara och återstarta tider: Det går att spara tidtagarurets status och senare återstarta det,
71 |
72 |
73 | Anpassning av teckensnitt: Det går att välja teckensnitten för varje siffra i tidtagaruret,
75 |
76 |
77 | Anpassning av färger: Det går att välja färg för tidtagarurets siffror och bakgrund,
79 |
80 |
81 | Export av varvtider: Det går att exportera varvtider till en fil med JSON- eller CSV-format.
83 |
84 |
85 |
86 |
87 |
88 | Upphovsman
91 | Kronometer är skrivet av Elvis Angelaccio <elvis.angelaccio@kde.org>.
93 |
94 | Den här manualsidan är skriven av Joao Eriberto Mota Filho <eriberto@debian.org> för Debians GNU/Linux-system (men kan användas av andra).
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/po/it/docs/kronometer/man-kronometer.1.docbook:
--------------------------------------------------------------------------------
1 |
2 |
4 | ]>
5 |
6 |
7 |
8 | 2016-04-10
10 | kronometer 2.0
12 |
13 |
14 |
15 | kronometer
17 | 1
19 | Aprile 2016
21 | KRONOMETER 2.1.0
23 |
24 |
25 | kronometer
27 | cronometro
29 |
30 |
31 |
32 |
33 | kronometer
35 |
36 |
37 |
38 | DESCRIZIONE
41 | Kronometer è un cronometro.
43 |
44 | Le principali funzionalità di Kronometer sono:
46 |
47 |
48 |
49 | Oggetto per avviare, mettere in pausa e riavviare il cronometro;
51 |
52 |
53 | Registrazione dei giri: puoi catturare il tempo del cronometro ogni volta che vuoi;
55 |
56 |
57 | Ordinamento dei tempi sul giro: puoi facilmente trovare il tempo sul giro più breve o più lungo;
59 |
60 |
61 | Oggetto per azzerare il cronometro e i tempi sul giro;
63 |
64 |
65 | Impostazioni del formato del tempo: puoi scegliere la risoluzione del cronometro;
67 |
68 |
69 | Salvataggio e ripristino dei tempi: puoi salvare lo stato del cronometro e ripristinarlo più avanti;
71 |
72 |
73 | Configurazione dei caratteri: puoi scegliere i caratteri per ciascuna cifra del cronometro;
75 |
76 |
77 | Configurazione dei colori: puoi scegliere il colore delle cifre e dello sfondo del cronometro;
79 |
80 |
81 | Esportazione dei tempi sul giro: puoi esportare i tempi sul giro su file nei formati JSON o CSV.
83 |
84 |
85 |
86 |
87 |
88 | AUTORE
91 | Kronometer è stato scritto da Elvis Angelaccio <elvis.angelaccio@kde.org>.
93 |
94 | Questa pagina di manuale è stata scritta da João Eriberto Mota Filho <eriberto@debian.org> per il progetto Debian (ma fruibile da altri).
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/po/nl/docs/kronometer/man-kronometer.1.docbook:
--------------------------------------------------------------------------------
1 |
2 |
4 | ]>
5 |
6 |
7 |
8 | 2016-04-10
10 | kronometer 2.0
12 |
13 |
14 |
15 | kronometer
17 | 1
19 | April 2016
21 | KRONOMETER 2.1.0
23 |
24 |
25 | kronometer
27 | stopwatch-toepassing
29 |
30 |
31 |
32 |
33 | kronometer
35 |
36 |
37 |
38 | BESCHRIJVING
41 | Kronometer is een stopwatch (timer/chronometer) toepassing.
43 |
44 | De hoofdfuncties van Kronometer zijn als volgt:
46 |
47 |
48 |
49 | Start/pauzeer/hervat het stopwatch-widget;
51 |
52 |
53 | Rondetijden opnemen: u kunt de tijd van de stopwatch opnemen wanneer u wilt;
55 |
56 |
57 | Rondetijden sorteren: u kunt gemakkelijk de kortste of de langste rondetijd vinden;
59 |
60 |
61 | Reset het stopwatch-widget en de rondetijden;
63 |
64 |
65 | Instellingen van de tijdopmaak: u kunt de nauwkeurigheid van de stopwatch kiezen;
67 |
68 |
69 | Tijden opslaan en hervatten: u kunt de status van de stopwatch opslaan en deze later hervatten;
71 |
72 |
73 | Aanpassen van het lettertype: u kunt het lettertype van elk van de cijfers van de stopwatch kiezen;
75 |
76 |
77 | Aanpassen van kleur: u kunt de kleur van de cijfers en de achtergrond van de stopwatch kiezen;
79 |
80 |
81 | Exporteren van rondetijden: u kunt de rondetijden exporteren in een bestand met het JSON- of CSV-formaat.
83 |
84 |
85 |
86 |
87 |
88 | AUTEUR
91 | KRONOMETER is geschreven door Elvis Angelaccio <elvis.angelaccio@kde.org>.
93 |
94 | Deze manpagina is gemaakt door Joao Eriberto Mota Filho <eriberto@debian.org> voor het Debian GNU/Linux systeem (maar kan worden gebruikt door anderen).
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/po/de/docs/kronometer/man-kronometer.1.docbook:
--------------------------------------------------------------------------------
1 |
2 |
4 | ]>
5 |
6 |
7 |
8 | 2016-04-10
10 | kronometer 2.0
12 |
13 |
14 |
15 | kronometer
17 | 1
19 | April 2016
21 | KRONOMETER 2.1.0
23 |
24 |
25 | kronometer
27 | Stoppuhrprogramm
29 |
30 |
31 |
32 |
33 | kronometer
35 |
36 |
37 |
38 | Beschreibung
41 | Kronometer ist eine Anwendung für die Zeitmessung (Stoppuhr).
43 |
44 | Kronometer hat folgende wichtige Funktionen:
46 |
47 |
48 |
49 | Das Stoppuhr-Miniprogramm starten/anhalten/fortsetzen
51 |
52 |
53 | Zwischenzeiten: Sie können eine Zeit festhalten, wann sie möchten
55 |
56 |
57 | Zwischenzeiten sortieren: so finden Sie einfach die schnellste oder langsamste Zeit
59 |
60 |
61 | Das Stoppuhr-Miniprogramm sowie Zwischenzeiten zurücksetzen
63 |
64 |
65 | Zeitformat einstellen: Sie können die Genauigkeit der Stoppuhr einstellen
67 |
68 |
69 | Zeiten speichern und fortsetzen: Sie können den Status der Stoppuhr speichern und später fortsetzen
71 |
72 |
73 | Eigene Schriftarten: Sie können für jede Ziffer der Stoppuhr eine Schriftart wählen
75 |
76 |
77 | Eigene Farben: Sie können für die Ziffern und den Hintergrund der Stoppuhr die Farbe wählen
79 |
80 |
81 | Zwischenzeiten-Export: Sie können die Zwischenzeiten in den Formaten JSON oder CVS in eine Datei speichern.
83 |
84 |
85 |
86 |
87 |
88 | Autor
91 | Das Programm Kronometer wurde von Elvis Angelaccio <elvis.angelaccio@kde.orgt> geschrieben.
93 |
94 | Diese Handbuchseite wurde von Joao Eriberto Mota Filho <eriberto@debian.org> für das Debian-Projekt geschrieben, darf aber auch von anderen verwendet werden.
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/po/pt/docs/kronometer/man-kronometer.1.docbook:
--------------------------------------------------------------------------------
1 |
2 |
4 | ]>
5 |
6 |
7 |
8 | 2016-04-10
10 | kronometer 2.0
12 |
13 |
14 |
15 | kronometer
17 | 1
19 | Abril de 2016
21 | KRONOMETER 2.1.0
23 |
24 |
25 | kronometer
27 | aplicação de cronómetro
29 |
30 |
31 |
32 |
33 | kronometer
35 |
36 |
37 |
38 | DESCRIÇÃO
41 | O Kronometer é uma aplicação de cronómetros.
43 |
44 | As funcionalidades principais do Kronometer são as seguintes:
46 |
47 |
48 |
49 | Iniciar/pausar/retomar o item do cronómetro;
51 |
52 |
53 | Gravação de voltas: poderá capturar os tempos do cronómetro sempre que desejar;
55 |
56 |
57 | Ordenação dos tempos de voltas: poderá encontrar facilmente o tempo mais curto ou mais longo;
59 |
60 |
61 | Reiniciar o cronómetro e os tempos das voltas;
63 |
64 |
65 | Configuração do formato das horas: poderá escolher a granularidade do relógio;
67 |
68 |
69 | Gravação e recuperação dos tempo: poderá gravar o estado do cronómetro e retomá-lo posteriormente;
71 |
72 |
73 | Personalização dos tipos de letra: poderá escolher os tipos de letra para cada um dos números do cronómetro;
75 |
76 |
77 | Personalização de cores: poderá escolher a cor dos números do cronómetro e o fundo do mesmo;
79 |
80 |
81 | Exportação dos tempos das voltas: poderá exportar os tempos das voltas para um ficheiro no formato CSV ou JSON.
83 |
84 |
85 |
86 |
87 |
88 | AUTOR
91 | O KRONOMETER foi criado por Elvis Angelaccio <elvis.angelaccio@kde.org>.
93 |
94 | Esta página do manual foi criada por João Eriberto Mota Filho <eriberto@debian.org> para o projecto Debian (mas poderá ser usado por outros).
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/autotests/core/testsession.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2015 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #include
8 | #include "testsession.h"
9 | #include "session.h"
10 |
11 | void TestSession::testDefaultSession()
12 | {
13 | Session session;
14 |
15 | QCOMPARE(session.time(), 0);
16 | QVERIFY(session.isEmpty());
17 | QVERIFY(!session.isOutdated());
18 | QVERIFY(session.laps().isEmpty());
19 | QVERIFY(session.name().isNull());
20 | QVERIFY(session.note().isEmpty());
21 | }
22 |
23 | void TestSession::testTime()
24 | {
25 | int time = 1000;
26 | Session session {time};
27 |
28 | QCOMPARE(session.time(), time);
29 | }
30 |
31 | void TestSession::testName()
32 | {
33 | Session session;
34 | auto test = QLatin1String("test");
35 |
36 | session.setName(test);
37 |
38 | QCOMPARE(session.name(), test);
39 | }
40 |
41 | void TestSession::testNote()
42 | {
43 | Session session;
44 | auto test = QLatin1String("test");
45 |
46 | session.setNote(test);
47 |
48 | QCOMPARE(session.note(), test);
49 | }
50 |
51 | void TestSession::testDate()
52 | {
53 | auto date = QDateTime::currentDateTime();
54 | Session session {0, date};
55 |
56 | QCOMPARE(session.date(), date);
57 | }
58 |
59 | void TestSession::testLaps()
60 | {
61 | Session session;
62 |
63 | const auto laps = QVector {Lap {{1, 30}}, Lap {{2, 0}}, Lap {{1, 45}}};
64 | for (const auto& lap : laps) {
65 | session.addLap(lap);
66 | }
67 |
68 | QCOMPARE(session.laps().size(), laps.size());
69 | }
70 |
71 | void TestSession::testEquality()
72 | {
73 | auto date = QDateTime::currentDateTime();
74 |
75 | Session session1 {0, date};
76 | Session session2 {1000, date};
77 |
78 | QCOMPARE(session1, session2);
79 | }
80 |
81 | void TestSession::testInequality()
82 | {
83 | Session session1 {0, QDateTime::currentDateTime()};
84 | QTest::qSleep(100);
85 | Session session2 {0, QDateTime::currentDateTime()};
86 |
87 | QVERIFY(session1 != session2);
88 | }
89 |
90 | void TestSession::testJson()
91 | {
92 | auto date = QDateTime::currentDateTime();
93 | Session session1 {1000, QDateTime::fromString(date.toString(Qt::ISODate), Qt::ISODate)};
94 | session1.setName(QStringLiteral("test-name"));
95 | session1.setNote(QStringLiteral("test-note"));
96 |
97 | const auto laps = QVector {Lap {{1, 30}}, Lap {{2, 0}}, Lap {{1, 45}}};
98 | for (const auto& lap : laps) {
99 | session1.addLap(lap);
100 | }
101 |
102 | QJsonObject json;
103 | session1.write(json);
104 |
105 | Session session2 = Session::fromJson(json);
106 |
107 | QCOMPARE(session1, session2);
108 | QCOMPARE(session1.time(), session2.time());
109 | QCOMPARE(session1.name(), session2.name());
110 | QCOMPARE(session1.note(), session2.note());
111 | QCOMPARE(session1.laps().size(), session2.laps().size());
112 | }
113 |
114 | QTEST_MAIN(TestSession)
115 |
116 | #include "moc_testsession.cpp"
117 |
--------------------------------------------------------------------------------
/po/pt_BR/docs/kronometer/man-kronometer.1.docbook:
--------------------------------------------------------------------------------
1 |
2 |
4 | ]>
5 |
6 |
7 |
8 | 10/04/2016
10 | kronometer 2.0
12 |
13 |
14 |
15 | kronometer
17 | 1
19 | April de 2016
21 | KRONOMETER 2.1.0
23 |
24 |
25 | kronometer
27 | aplicativo de cronômetro
29 |
30 |
31 |
32 |
33 | kronometer
35 |
36 |
37 |
38 | DESCRIÇÃO
41 | Kronometer é um aplicativo de cronômetro e temporizador.
43 |
44 | As principais funcionalidades do Kronometer são as seguintes:
46 |
47 |
48 |
49 | Iniciar/pausar/continuar o cronômetro;
51 |
52 |
53 | Registro de voltas: Você pode capturar o tempo do cronômetro sempre que quiser;
55 |
56 |
57 | Ordenação dos tempos das voltas: Você pode localizar facilmente o tempo mais curto ou mais longo;
59 |
60 |
61 | Reiniciar o cronômetro e os tempos das voltas;
63 |
64 |
65 | Configuração do formato dos tempos: Você pode escolher a granularidade dos cronômetros;
67 |
68 |
69 | Gravação e continuação dos tempos: Você pode salvar o status do cronômetro para continuar mais tarde;
71 |
72 |
73 | Personalização de fontes: Você pode escolher as fontes para cada um dos dígitos do cronômetro;
75 |
76 |
77 | Personalização de cores: Você pode escolher a cor dos dígitos e do fundo do cronômetro;
79 |
80 |
81 | Exportação dos tempos das voltas: Você pode exportar os tempos das voltas para um arquivo no formato JSON ou CSV.
83 |
84 |
85 |
86 |
87 |
88 | AUTOR
91 | O KRONOMETER foi criado por Elvis Angelaccio <elvis.angelaccio@kde.org>.
93 |
94 | Esta página de manual foi escrita por Joao Eriberto Mota Filho <eriberto@debian.org> para o projeto Debian (mas também pode ser usada por outros).
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/po/ca/docs/kronometer/man-kronometer.1.docbook:
--------------------------------------------------------------------------------
1 |
2 |
4 | ]>
5 |
6 |
7 |
8 | 10 d'abril de 2016
10 | kronometer 2.0
12 |
13 |
14 |
15 | kronometer
17 | 1
19 | Abril de 2016
21 | Kronometer 2.1.0
23 |
24 |
25 | kronometer
27 | aplicació de cronòmetre
29 |
30 |
31 |
32 |
33 | kronometer
35 |
36 |
37 |
38 | Descripció
41 | El Kronometer és una aplicació de cronòmetre.
43 |
44 | Les característiques principals del Kronometer són les següents:
46 |
47 |
48 |
49 | Engega/pausa/continua el giny de cronòmetre;
51 |
52 |
53 | Enregistrament de les voltes: podeu capturar el temps del cronòmetre quan vulgueu;
55 |
56 |
57 | Ordenació dels temps per volta: podeu trobar amb facilitat els temps per volta més ràpida o més lenta;
59 |
60 |
61 | Inicialitzar el giny de cronòmetre i els temps per volta;
63 |
64 |
65 | Arranjament pel format del temps: podeu triar el nivell de detall del cronòmetre;
67 |
68 |
69 | Desament i continuació dels temps: podeu desar l'estat del cronòmetre per a continuar més tard;
71 |
72 |
73 | Personalització de les lletres: podeu triar les lletres per a cadascun dels dígits del cronòmetre;
75 |
76 |
77 | Personalització dels colors: podeu triar el color per als dígits del cronòmetre i el fons del cronòmetre;
79 |
80 |
81 | Exportació dels temps per volta: podeu exportar els temps per volta a un fitxer usant el format JSON o CSV.
83 |
84 |
85 |
86 |
87 |
88 | Autor
91 | El Kronometer ha estat escrit per l'Elvis Angelaccio <elvis.angelaccio@kde.org>.
93 |
94 | Aquesta pàgina de manual ha estat escrita per en Joao Eriberto Mota Filho <eriberto@debian.org> pel projecte Debian (però la poden emprar els altres).
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/src/models/sessionmodel.h:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2015 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #ifndef SESSIONMODEL_H
8 | #define SESSIONMODEL_H
9 |
10 | #include "session.h"
11 |
12 | #include
13 |
14 | /**
15 | * @brief A SessionModel is a Model for sessions.
16 | */
17 | class SessionModel : public QAbstractTableModel
18 | {
19 | Q_OBJECT
20 |
21 | public:
22 |
23 | enum class Roles
24 | {
25 | SessionIdRole = Qt::UserRole,
26 | NameRole,
27 | DateRole,
28 | NoteRole,
29 | SessionRole
30 | };
31 |
32 | explicit SessionModel(QObject *parent = nullptr);
33 |
34 | int rowCount(const QModelIndex& parent = {}) const override;
35 | int columnCount(const QModelIndex& parent = {}) const override;
36 | QVariant data(const QModelIndex& index, int role) const override;
37 | QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
38 | bool setData(const QModelIndex& index, const QVariant& value, int role) override;
39 | Qt::ItemFlags flags(const QModelIndex& index) const override;
40 | bool removeRows(int row, int count, const QModelIndex& parent) override;
41 |
42 | /**
43 | * Insert a new Session object to the end of the model.
44 | * @param session The new Session object.
45 | */
46 | void append(const Session& session);
47 |
48 | /**
49 | * Update the given session in the model and updates its date.
50 | * If the session does not belong to the model, nothing happens.
51 | * @param session The session to be updated.
52 | */
53 | void update(Session& session);
54 |
55 | /**
56 | * @return Whether the model does not hold any session.
57 | */
58 | bool isEmpty() const;
59 |
60 | /**
61 | * Whether the given index refers to an editable value in the model.
62 | * @param index An index of the model.
63 | * @return True if the underlying data is editable, false otherwise.
64 | */
65 | bool isEditable(const QModelIndex& index) const;
66 |
67 | /**
68 | * Load the model from the given JSON object.
69 | * @param json A JSON object.
70 | */
71 | void read(const QJsonObject& json);
72 |
73 | private Q_SLOTS:
74 |
75 | /**
76 | * Update the global sessions file with the data in the model.
77 | */
78 | void slotWriteData();
79 |
80 | private:
81 |
82 | /**
83 | * @return The index of the column for the given role.
84 | */
85 | int columnForRole(Roles role) const;
86 |
87 | /**
88 | * @return The role for the given column.
89 | */
90 | Roles roleForColumn(int column) const;
91 |
92 | /**
93 | * @return The list of sessions as json array.
94 | */
95 | QJsonArray jsonSessions() const;
96 |
97 | const QVector m_roles {Roles::SessionIdRole, Roles::NameRole, Roles::DateRole, Roles::NoteRole};
98 |
99 | QVector m_sessionList; /** Sessions in the model. */
100 |
101 | Q_DISABLE_COPY(SessionModel)
102 | };
103 |
104 |
105 | #endif
106 |
--------------------------------------------------------------------------------
/src/core/lap.h:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2014 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #ifndef LAP_H
8 | #define LAP_H
9 |
10 | #include
11 | #include
12 | #include
13 |
14 | class QJsonObject;
15 |
16 | /**
17 | * @brief A Lap is a specific time instant.
18 | * This class is a wrapper for a QTime object and some strings, which are useful to describe it.
19 | */
20 | class Lap
21 | {
22 |
23 | public:
24 |
25 | explicit Lap(const QTime& lap = {0, 0});
26 |
27 | /**
28 | * The specific lap's time
29 | * @return The underlying lap's time object
30 | */
31 | QTime time() const;
32 |
33 | /**
34 | * Compute the difference with the given Lap.
35 | * @param lap A Lap object.
36 | * @return QTime difference if the given Lap is "greater", otherwise a zero QTime.
37 | */
38 | QTime timeTo(const Lap& lap) const;
39 |
40 | /**
41 | * Set the lap's relative time
42 | * @param rel The string to be set as relative time
43 | */
44 | void setRelativeTime(const QString& rel);
45 |
46 | /**
47 | * The relative lap time
48 | * @return String representation of the relative lap time
49 | */
50 | QString relativeTime() const;
51 |
52 | /**
53 | * Set the lap's absolute time
54 | * @param abs The string to be set as absolute lap time
55 | */
56 | void setAbsoluteTime(const QString& abs);
57 |
58 | /**
59 | * The absolute lap time
60 | * @return String representation of the absolute lap time
61 | */
62 | QString absoluteTime() const;
63 |
64 | /**
65 | * Set the lap's annotation
66 | * @param note The note to be set
67 | */
68 | void setNote(const QString& note);
69 |
70 | /**
71 | * The lap's annotation
72 | * @return The lap's annotation
73 | */
74 | QString note() const;
75 |
76 | /**
77 | * The underlying lap's raw data
78 | * @return Lap's raw data counter
79 | */
80 | int raw() const;
81 |
82 | /**
83 | * Serialize the lap on the given JSON object.
84 | * @param json A JSON object.
85 | */
86 | void write(QJsonObject& json) const;
87 |
88 | /**
89 | * Deserialize a lap from the given JSON object.
90 | * @param json A JSON object.
91 | * @return A deserialized lap.
92 | */
93 | static Lap fromJson(const QJsonObject& json);
94 |
95 | /**
96 | * Create a new Lap object from raw data
97 | * @param rawData The raw data counter of the new Lap
98 | * @return A new Lap object created from the given raw data
99 | */
100 | static Lap fromRawData(int rawData);
101 |
102 | private:
103 |
104 | QTime m_time; /** The specific lap time */
105 | QString m_relativeTime; /** String representation of the relative lap time, i.e. compared to another lap */
106 | QString m_absoluteTime; /** String representation of the specific (absolute) lap time */
107 | QString m_note; /** Custom lap annotation */
108 | };
109 |
110 | Q_DECLARE_METATYPE(Lap)
111 |
112 | #endif
113 |
--------------------------------------------------------------------------------
/po/es/docs/kronometer/man-kronometer.1.docbook:
--------------------------------------------------------------------------------
1 |
2 |
4 | ]>
5 |
6 |
7 |
8 | 2016-04-10
10 | kronometer 2.0
12 |
13 |
14 |
15 | kronometer
17 | 1
19 | Abril de 2016
21 | KRONOMETER 2.1.0
23 |
24 |
25 | kronometer
27 | aplicación de cronómetro
29 |
30 |
31 |
32 |
33 | kronometer
35 |
36 |
37 |
38 | DESCRIPCIÓN
41 | Kronometer es una aplicación de cronómetro (temporizador/cronómetro).
43 |
44 | Las funciones principales de Kronometer son las siguientes:
46 |
47 |
48 |
49 | Iniciar, pausar y continuar el elemento gráfico de cronómetro;
51 |
52 |
53 | Grabación de las vueltas: puede capturar los tiempos del cronómetro cuando quiera;
55 |
56 |
57 | Ordenación de los tiempos de las vueltas: puede encontrar con facilidad el tiempo de vuelta más corto o el más largo;
59 |
60 |
61 | Reiniciar el elemento gráfico del cronómetro y los tiempos por vuelta;
63 |
64 |
65 | Preferencias de formato de tiempos: puede escoger el nivel de detalle del cronómetro;
67 |
68 |
69 | Grabación y reanudación de tiempos: puede guardar el estado del cronómetro y reanudar dicho estado posteriormente;
71 |
72 |
73 | Personalización de tipos de letra: puede escoger los tipos de letra para los dígitos del cronómetro;
75 |
76 |
77 | Personalización de colores: puede escoger el color de los dígitos del cronómetro y de su fondo;
79 |
80 |
81 | Exportar los tiempos de las vueltas: puede exportar los tiempos de las vueltas en un archivo usando los formatos JSON o CSV.
83 |
84 |
85 |
86 |
87 |
88 | AUTOR
91 | KRONOMETER fue escrito por Elvis Angelaccio <elvis.angelaccio@kde.org>.
93 |
94 | Esta página de manual fue escrita por Joao Eriberto Mota Filho <eriberto@debian.org> para el proyecto Debian (aunque se puede usar por otros).
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/po/uk/docs/kronometer/man-kronometer.1.docbook:
--------------------------------------------------------------------------------
1 |
2 |
4 | ]>
5 |
6 |
7 |
8 | 10 квітня 2016 року
10 | kronometer 2.0
12 |
13 |
14 |
15 | kronometer
17 | 1
19 | квітень 2016 року
21 | KRONOMETER 2.1.0
23 |
24 |
25 | kronometer
27 | програма-секундомір
29 |
30 |
31 |
32 |
33 | kronometer
35 |
36 |
37 |
38 | ОПИС
41 | Kronometer — програма-секундомір (таймер і хронометр).
43 |
44 | Основні можливості Kronometer:
46 |
47 |
48 |
49 | Віджет запуску, призупинення та поновлення відліку секундоміра.
51 |
52 |
53 | Запис даних щодо проходження кіл: ви можете записувати дані секундоміра у довільні моменти часу.
55 |
56 |
57 | Упорядковування за часом проходження кола: ви легко можете встановити найкращий і найгірший часи проходження.
59 |
60 |
61 | Скидання значення на віджеті секундоміра та скидання часу проходження кіл.
63 |
64 |
65 | Можливість зміни форматування часу: ви можете вибрати значення параметрів так, щоб було показано лише потрібні вам дані.
67 |
68 |
69 | Збереження та відновлення записаних даних щодо часу: ви можете записати стан секундоміра на диск і згодом відновити його.
71 |
72 |
73 | Можливість налаштовування шрифтів: ви можете вибрати шрифт для кожного з компонентів числових даних секундоміра.
75 |
76 |
77 | Можливість налаштовування кольорів: ви можете вибрати колір для числових даних секундоміра та колір тла.
79 |
80 |
81 | Експортування даних щодо часу проходження кіл: ви можете експортувати дані до файла у форматі JSON або CSV.
83 |
84 |
85 |
86 |
87 |
88 | Автор
91 | Програму KRONOMETER створено Elvis Angelaccio <elvis.angelaccio@kde.org>.
93 |
94 | Цю сторінку підручника створено Joao Eriberto Mota Filho <eriberto@debian.org> для проєкту Debian (її можна використовувати і у інших проєктах).
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/src/core/stopwatch.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2014 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #include "stopwatch.h"
8 |
9 | #include
10 | #include
11 |
12 | Stopwatch::Stopwatch(QObject *parent) : QObject(parent) {}
13 |
14 | void Stopwatch::setGranularity(Granularity g)
15 | {
16 | m_granularity = g;
17 |
18 | // whenever granularity is changed, also apply that granularity to the timer event
19 | if (m_timerId != INACTIVE_TIMER_ID) {
20 | killTimer(m_timerId);
21 | m_timerId = startTimer(granularity());
22 | }
23 | }
24 |
25 | bool Stopwatch::isRunning() const
26 | {
27 | return m_state == State::Running;
28 | }
29 |
30 | bool Stopwatch::isPaused() const
31 | {
32 | return m_state == State::Paused;
33 | }
34 |
35 | bool Stopwatch::isInactive() const
36 | {
37 | return m_state == State::Inactive;
38 | }
39 |
40 | int Stopwatch::raw() const
41 | {
42 | return m_accumulator;
43 | }
44 |
45 | bool Stopwatch::initialize(int rawData)
46 | {
47 | if (!isInactive() || rawData <= 0) {
48 | return false;
49 | }
50 |
51 | m_accumulator = rawData;
52 | m_state = State::Paused;
53 | Q_EMIT time(m_accumulator); // it signals that has been deserialized and can be resumed
54 |
55 | return true;
56 | }
57 |
58 | void Stopwatch::start()
59 | {
60 | if (isInactive()) {
61 | m_accumulator = 0;
62 | m_elapsedTimer.start();
63 |
64 | if (m_timerId == INACTIVE_TIMER_ID) {
65 | m_timerId = startTimer(granularity());
66 | }
67 | }
68 | else if (isPaused()) {
69 | m_elapsedTimer.restart();
70 | m_timerId = startTimer(granularity());
71 | }
72 |
73 | m_state = State::Running;
74 | Q_EMIT running();
75 | }
76 |
77 | void Stopwatch::pause()
78 | {
79 | if (m_elapsedTimer.isValid()) {
80 | m_accumulator += m_elapsedTimer.elapsed();
81 | }
82 |
83 | m_elapsedTimer.invalidate();
84 | m_state = State::Paused;
85 | Q_EMIT paused();
86 | }
87 |
88 | void Stopwatch::reset()
89 | {
90 | m_elapsedTimer.invalidate(); // if state is running, it will emit a zero time at next timerEvent() call
91 | QCoreApplication::processEvents();
92 | m_accumulator = 0;
93 | Q_EMIT time(0);
94 | m_state = State::Inactive;
95 | Q_EMIT inactive();
96 | }
97 |
98 | void Stopwatch::storeLap()
99 | {
100 | auto lapTime = m_accumulator;
101 |
102 | if (m_elapsedTimer.isValid()) {
103 | lapTime += m_elapsedTimer.elapsed();
104 | }
105 |
106 | const auto zero = QTime {0, 0};
107 | Q_EMIT lap(zero.addMSecs(lapTime));
108 | }
109 |
110 | void Stopwatch::timerEvent(QTimerEvent *event)
111 | {
112 | if (event->timerId() != m_timerId) { // forward undesired events
113 | QObject::timerEvent(event);
114 | return;
115 | }
116 |
117 | if (m_elapsedTimer.isValid()) {
118 | Q_EMIT time(m_accumulator + m_elapsedTimer.elapsed());
119 | }
120 | else {
121 | killTimer(m_timerId);
122 | m_timerId = INACTIVE_TIMER_ID;
123 | }
124 | }
125 |
126 | int Stopwatch::granularity() const
127 | {
128 | return static_cast(m_granularity);
129 | }
130 |
131 | #include "moc_stopwatch.cpp"
132 |
--------------------------------------------------------------------------------
/src/core/session.h:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2015 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #ifndef SESSION_H
8 | #define SESSION_H
9 |
10 | #include "lap.h"
11 |
12 | #include
13 | #include
14 |
15 | /**
16 | * @brief A session represents a single Kronometer instance.
17 | * A session is made by a stopwatch time, a date timestamp and by zero or more laps.
18 | * An optional name and an optional note are also provided.
19 | */
20 | class Session
21 | {
22 |
23 | public:
24 |
25 | explicit Session(int time = 0, const QDateTime& date = QDateTime::currentDateTime());
26 |
27 | /**
28 | * Set the session's name.
29 | * @param name The string to be set as name.
30 | */
31 | void setName(const QString& name);
32 |
33 | /**
34 | * Set the session's annotation.
35 | * @param note The note to be set.
36 | */
37 | void setNote(const QString& note);
38 |
39 | /**
40 | * Set the session's stopwatch (raw) time.
41 | * @param time The stopwatch raw time.
42 | */
43 | void setTime(int time);
44 |
45 | /**
46 | * Set the session's date (timestamp).
47 | * @param date The date to be set as timestamp.
48 | */
49 | void setDate(const QDateTime& date);
50 |
51 | /**
52 | * Set whether the session data is outdated.
53 | * @param isOutdated Whether the session is outdated.
54 | */
55 | void setIsOutdated(bool isOutdated);
56 |
57 | /**
58 | * @return The session name.
59 | */
60 | QString name() const;
61 |
62 | /**
63 | * @return The session note.
64 | */
65 | QString note() const;
66 |
67 | /**
68 | * @return The session stopwatch raw time.
69 | */
70 | int time() const;
71 |
72 | /**
73 | * @return The session date.
74 | */
75 | QDateTime date() const;
76 |
77 | /**
78 | * Whether the session data is outdated.
79 | * @return True if the session is outdated, false otherwise.
80 | */
81 | bool isOutdated() const;
82 |
83 | /**
84 | * @return The session laps.
85 | */
86 | QVector laps() const;
87 |
88 | /**
89 | * Whether the session is empty.
90 | * @return True if the session is empty, false otherwise.
91 | */
92 | bool isEmpty() const;
93 |
94 | /**
95 | * Add a lap to the session.
96 | * @param lap The lap the be added.
97 | */
98 | void addLap(const Lap& lap);
99 |
100 | /**
101 | * Reset the stopwatch time and remove all the laps from the session.
102 | */
103 | void clear();
104 |
105 | /**
106 | * Serialize the session on the given JSON object.
107 | * @param json A JSON object.
108 | */
109 | void write(QJsonObject& json) const;
110 |
111 | /**
112 | * Deserialize a session from the given JSON object.
113 | * @param json A JSON object.
114 | * @return A deserialized session.
115 | */
116 | static Session fromJson(const QJsonObject& json);
117 |
118 | bool operator==(const Session& right) const;
119 | bool operator!=(const Session& right) const;
120 |
121 | private:
122 |
123 | QString m_name; /** Session name. */
124 | QString m_note; /** Custom session annotation. */
125 | int m_time; /** Session stopwatch time. */
126 | QDateTime m_date; /** Session date (timestamp of the last update). */
127 | QVector m_laps; /** Session laps. */
128 | bool m_isOutdated = false; /** Whether the session data is outdated. */
129 | };
130 |
131 | Q_DECLARE_METATYPE(Session)
132 |
133 | #endif
134 |
--------------------------------------------------------------------------------
/src/gui/kronometer.kcfg:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 | QGuiApplication
8 | QPalette
9 | QFontDatabase
10 | "timeformat.h"
11 |
12 |
13 |
14 |
15 |
16 | false
17 |
18 |
19 | false
20 |
21 |
22 | true
23 |
24 |
25 | true
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | TimeFormat::UpToHundredths
35 |
36 |
37 | true
38 |
39 |
40 | false
41 |
42 |
43 | true
44 |
45 |
46 | true
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | TimeFormat::UpToHundredths
56 |
57 |
58 | false
59 |
60 |
61 | true
62 |
63 |
64 | true
65 |
66 |
67 |
68 |
69 |
70 |
71 | QFont defaultFont(QFontDatabase::systemFont(QFontDatabase::GeneralFont).family(), 54);
72 |
73 | defaultFont
74 |
75 |
76 | defaultFont
77 |
78 |
79 | defaultFont
80 |
81 |
82 | defaultFont
83 |
84 |
85 |
86 |
87 |
88 | qApp->palette().base().color()
89 |
90 |
91 | qApp->palette().text().color()
92 |
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/src/gui/timedisplay.h:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2014 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #ifndef TIMEDISPLAY_H
8 | #define TIMEDISPLAY_H
9 |
10 | #include "ui_timedisplay.h"
11 | #include "timeformat.h"
12 |
13 | #include
14 | #include
15 |
16 | class DigitDisplay;
17 |
18 | class QGroupBox;
19 |
20 | /**
21 | * @brief A custom widget displaying a QTime
22 | * This custom widget implements a "digital" display for a time, formatted according to a certain format.
23 | * This widget can be connected to a generic "time source" producing the time to be displayed.
24 | */
25 | class TimeDisplay : public QWidget, public Ui::TimeDisplay
26 | {
27 | Q_OBJECT
28 |
29 | public:
30 |
31 | explicit TimeDisplay(QWidget *parent = nullptr);
32 |
33 | /**
34 | * Set the internal time format of the display
35 | * @param format The format to be used as time format.
36 | */
37 | void setTimeFormat(const TimeFormat& format);
38 |
39 | /**
40 | * Set a custom font for hours
41 | * @param font The custom font to set.
42 | */
43 | void setHoursFont(const QFont& font);
44 |
45 | /**
46 | * Set a custom font for minutes
47 | * @param font The custom font to set.
48 | */
49 | void setMinutesFont(const QFont& font);
50 |
51 | /**
52 | * Set a custom font for seconds
53 | * @param font The custom font to set.
54 | */
55 | void setSecondsFont(const QFont& font);
56 |
57 | /**
58 | * Set a custom font for second fractions
59 | * @param font The custom font to set.
60 | */
61 | void setFractionsFont(const QFont& font);
62 |
63 | /**
64 | * Set a custom color for display background.
65 | * @param color The custom color to set.
66 | */
67 | void setBackgroundColor(const QColor& color);
68 |
69 | /**
70 | * Set a custom color for display fonts.
71 | * @param color The custom color to set.
72 | */
73 | void setTextColor(const QColor& color);
74 |
75 | /**
76 | * Get the current time formatted with the current format.
77 | * @return Current time formatted as string.
78 | */
79 | QString currentTime();
80 |
81 | public Q_SLOTS:
82 |
83 | /**
84 | * Set the time to be displayed.
85 | * @param time The time to be displayed.
86 | */
87 | void setTime(int time);
88 |
89 | /**
90 | * Reset the display to the default time format. The overridden format (if any) is lost.
91 | */
92 | void reset();
93 |
94 | private:
95 |
96 | static constexpr int MSECS_PER_HOUR = 3600000;
97 | static constexpr int MSECS_PER_MIN = 60000;
98 | static constexpr int MSECS_PER_SEC = 1000;
99 | static constexpr int SECS_PER_MIN = 60;
100 |
101 | QTime m_displayTime = {0, 0}; /** Current display time */
102 | TimeFormat m_currentFormat; /** Current display time format. */
103 | TimeFormat m_defaultFormat; /** Default time format, to be restored on reset. */
104 |
105 | /**
106 | * Refresh the labels text implementing the display timer
107 | */
108 | void updateTimer();
109 |
110 | /**
111 | * Refresh the minimum width of the frames, based on current font sizes
112 | */
113 | void updateWidth();
114 |
115 | /**
116 | * Helper function, called when setting and overriding the time format.
117 | */
118 | void updateTimeFormat();
119 |
120 | /**
121 | * Helper function, called to set frame colors.
122 | */
123 | void setGroupboxColor(QGroupBox *groupBox, QPalette::ColorRole role, const QColor& color);
124 |
125 | Q_DISABLE_COPY(TimeDisplay)
126 | };
127 |
128 | #endif
129 |
--------------------------------------------------------------------------------
/src/core/timeformat.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2014 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #include "timeformat.h"
8 |
9 | #include
10 |
11 | TimeFormat::TimeFormat(bool showHours, bool showMinutes, SecondFraction fractions) :
12 | m_showHours {showHours},
13 | m_showMinutes {showMinutes},
14 | m_fractions {fractions}
15 | {
16 | setupFormat();
17 | }
18 |
19 | QString TimeFormat::format(const QTime& time) const
20 | {
21 | const auto h = formatHours(time);
22 | const auto m = formatMinutes(time);
23 | const auto s = formatSeconds(time);
24 | const auto f = formatFractions(time);
25 |
26 | return h + m + s + f;
27 | }
28 |
29 | QString TimeFormat::formatHours(const QTime& time) const
30 | {
31 | if (!m_showHours) {
32 | return {};
33 | }
34 |
35 | return time.toString(m_hourFormat);
36 | }
37 |
38 | QString TimeFormat::formatMinutes(const QTime& time) const
39 | {
40 | if (!m_showMinutes) {
41 | return {};
42 | }
43 |
44 | return time.toString(m_minFormat);
45 | }
46 |
47 | QString TimeFormat::formatSeconds(const QTime& time) const
48 | {
49 | return time.toString(m_secFormat);
50 | }
51 |
52 | QString TimeFormat::formatFractions(const QTime& time) const
53 | {
54 | auto fracFormat = QStringLiteral("zzz");
55 | auto temp = QString {};
56 |
57 | switch (m_fractions) {
58 | case UpToTenths:
59 | temp = time.toString(fracFormat);
60 | return temp.left(temp.size() - 2);
61 | case UpToHundredths:
62 | temp = time.toString(fracFormat);
63 | return temp.left(temp.size() - 1);
64 | case UpToMilliseconds:
65 | return time.toString(fracFormat);
66 | default:
67 | return QString();
68 | }
69 | }
70 |
71 | void TimeFormat::overrideHours()
72 | {
73 | if (m_showHours)
74 | return;
75 |
76 | m_showHours = true;
77 | setupFormat();
78 | }
79 |
80 | void TimeFormat::overrideMinutes()
81 | {
82 | if (m_showMinutes)
83 | return;
84 |
85 | m_showMinutes = true;
86 | setupFormat();
87 | }
88 |
89 | bool TimeFormat::hasHours() const
90 | {
91 | return m_showHours;
92 | }
93 |
94 | bool TimeFormat::hasMinutes() const
95 | {
96 | return m_showMinutes;
97 | }
98 |
99 | bool TimeFormat::hasFractions() const
100 | {
101 | return m_fractions != NoFractions;
102 | }
103 |
104 | TimeFormat::SecondFraction TimeFormat::secondFractions() const
105 | {
106 | return m_fractions;
107 | }
108 |
109 | void TimeFormat::showDividers(bool show)
110 | {
111 | m_showDividers = show;
112 | setupFormat();
113 | }
114 |
115 | bool TimeFormat::operator==(const TimeFormat& right) const
116 | {
117 | return m_showHours == right.m_showHours &&
118 | m_showMinutes == right.m_showMinutes &&
119 | m_fractions == right.m_fractions &&
120 | m_showDividers == right.m_showDividers;
121 | }
122 |
123 | bool TimeFormat::operator!=(const TimeFormat& right) const
124 | {
125 | return !(*this == right);
126 | }
127 |
128 | void TimeFormat::setupFormat()
129 | {
130 | if (m_showHours) {
131 | if (m_showDividers) {
132 | m_hourFormat = QStringLiteral("hh:");
133 | }
134 | else {
135 | m_hourFormat = QStringLiteral("hh");
136 | }
137 | }
138 |
139 | if (m_showMinutes) {
140 | if (m_showDividers) {
141 | m_minFormat = QStringLiteral("mm:");
142 | }
143 | else {
144 | m_minFormat = QStringLiteral("mm");
145 | }
146 | }
147 |
148 | if (m_showDividers && m_fractions != NoFractions) {
149 | m_secFormat = QStringLiteral("ss.");
150 | }
151 | else {
152 | m_secFormat = QStringLiteral("ss");
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/CMakePresets.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 2,
3 | "configurePresets": [
4 | {
5 | "name": "dev",
6 | "displayName": "Build as debug",
7 | "generator": "Ninja",
8 | "binaryDir": "${sourceDir}/build",
9 | "cacheVariables": {
10 | "CMAKE_BUILD_TYPE": "Debug",
11 | "CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
12 | }
13 | },
14 | {
15 | "name": "dev-disable-deprecated",
16 | "displayName": "Build as without deprecated methods",
17 | "generator": "Ninja",
18 | "binaryDir": "${sourceDir}/build-disable-deprecated",
19 | "cacheVariables": {
20 | "CMAKE_BUILD_TYPE": "Debug",
21 | "CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
22 | "CMAKE_CXX_FLAGS_INIT": "-DQT_DISABLE_DEPRECATED_BEFORE=0x060000 -DKF_DISABLE_DEPRECATED_BEFORE_AND_AT=0x060000"
23 | }
24 | },
25 | {
26 | "name": "asan",
27 | "displayName": "Build with Asan support.",
28 | "generator": "Ninja",
29 | "binaryDir": "${sourceDir}/build-asan",
30 | "cacheVariables": {
31 | "CMAKE_BUILD_TYPE": "Debug",
32 | "ECM_ENABLE_SANITIZERS" : "'address;undefined'",
33 | "CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
34 | }
35 | },
36 | {
37 | "name": "unity",
38 | "displayName": "Build with CMake unity support.",
39 | "generator": "Ninja",
40 | "binaryDir": "${sourceDir}/build-unity",
41 | "cacheVariables": {
42 | "CMAKE_BUILD_TYPE": "Debug",
43 | "CMAKE_UNITY_BUILD": "ON",
44 | "CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
45 | }
46 | },
47 | {
48 | "name": "release",
49 | "displayName": "Build as release mode.",
50 | "generator": "Ninja",
51 | "binaryDir": "${sourceDir}/build-release",
52 | "cacheVariables": {
53 | "CMAKE_BUILD_TYPE": "Release"
54 | }
55 | },
56 | {
57 | "name": "profile",
58 | "displayName": "profile",
59 | "generator": "Ninja",
60 | "binaryDir": "${sourceDir}/build-profile",
61 | "cacheVariables": {
62 | "CMAKE_BUILD_TYPE": "RelWithDebInfo",
63 | "CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
64 | }
65 | },
66 | {
67 | "name": "clazy",
68 | "displayName": "clazy",
69 | "generator": "Ninja",
70 | "binaryDir": "${sourceDir}/build-clazy",
71 | "cacheVariables": {
72 | "CMAKE_BUILD_TYPE": "Debug"
73 | },
74 | "environment": {
75 | "CXX": "clazy",
76 | "CCACHE_DISABLE": "ON"
77 | }
78 | }
79 | ],
80 | "buildPresets": [
81 | {
82 | "name": "dev",
83 | "configurePreset": "dev"
84 | },
85 | {
86 | "name": "asan",
87 | "configurePreset": "asan"
88 | },
89 | {
90 | "name": "dev-disable-deprecated",
91 | "configurePreset": "dev-disable-deprecated"
92 | },
93 | {
94 | "name": "unity",
95 | "configurePreset": "unity"
96 | },
97 | {
98 | "name": "clazy",
99 | "configurePreset": "clazy",
100 | "environment": {
101 | "CLAZY_CHECKS" : "level0,level1,detaching-member,ifndef-define-typo,isempty-vs-count,qrequiredresult-candidates,reserve-candidates,signal-with-return-value,unneeded-cast,function-args-by-ref,function-args-by-value,returning-void-expression,no-ctor-missing-parent-argument,isempty-vs-count,qhash-with-char-pointer-key,raw-environment-function,qproperty-type-mismatch,old-style-connect,qstring-allocations,container-inside-loop,heap-allocated-small-trivial-type,inefficient-qlist,qstring-varargs,level2,detaching-member,heap-allocated-small-trivial-type,isempty-vs-count,qstring-varargs,qvariant-template-instantiation,raw-environment-function,reserve-candidates,signal-with-return-value,thread-with-slots,no-ctor-missing-parent-argument,no-missing-typeinfo",
102 | "CCACHE_DISABLE" : "ON"
103 | }
104 | }
105 | ]
106 | }
107 |
--------------------------------------------------------------------------------
/src/gui/digitdisplay.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2014 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #include "digitdisplay.h"
8 |
9 | #include
10 | #include
11 |
12 | DigitDisplay::DigitDisplay(QWidget *parent, Digits digits) : QWidget(parent)
13 | {
14 | auto layout = new QHBoxLayout {this};
15 | m_leftmostDigit = new QLabel {this};
16 | m_centerDigit = new QLabel {this};
17 | m_rightmostDigit = new QLabel {this};
18 |
19 | m_leftmostDigit->setAlignment(Qt::AlignCenter);
20 | m_centerDigit->setAlignment(Qt::AlignCenter);
21 | m_rightmostDigit->setAlignment(Qt::AlignCenter);
22 |
23 | layout->addWidget(m_leftmostDigit);
24 | layout->addWidget(m_centerDigit);
25 | layout->addWidget(m_rightmostDigit);
26 |
27 | setDigits(digits);
28 | }
29 |
30 | void DigitDisplay::setDigits(Digits digits)
31 | {
32 | m_digits = digits;
33 |
34 | switch (m_digits) {
35 | case Digits::One:
36 | m_leftmostDigit->show();
37 | m_centerDigit->hide();
38 | m_rightmostDigit->hide();
39 | break;
40 | case Digits::Two:
41 | m_leftmostDigit->show();
42 | m_centerDigit->show();
43 | m_rightmostDigit->hide();
44 | break;
45 | case Digits::Three:
46 | m_leftmostDigit->show();
47 | m_centerDigit->show();
48 | m_rightmostDigit->show();
49 | break;
50 | default:
51 | m_leftmostDigit->hide();
52 | m_centerDigit->hide();
53 | m_rightmostDigit->hide();
54 | break;
55 | }
56 | }
57 |
58 | void DigitDisplay::showDigits(const QString& digits) const
59 | {
60 | switch (m_digits) {
61 | case Digits::One:
62 | showOneDigit(digits);
63 | break;
64 | case Digits::Two:
65 | showTwoDigits(digits);
66 | break;
67 | case Digits::Three:
68 | showThreeDigits(digits);
69 | break;
70 | default:
71 | break;
72 | }
73 | }
74 |
75 | void DigitDisplay::setFont(const QFont& font)
76 | {
77 | m_displayFont = font;
78 |
79 | m_leftmostDigit->setFont(m_displayFont);
80 | m_centerDigit->setFont(m_displayFont);
81 | m_rightmostDigit->setFont(m_displayFont);
82 | }
83 |
84 | QSize DigitDisplay::minimumSizeHint() const
85 | {
86 | auto width = 0;
87 | auto fontMetrics = QFontMetrics {m_displayFont};
88 |
89 | switch (m_digits) {
90 | case Digits::One:
91 | width = fontMetrics.boundingRect(m_leftmostDigit->text()).width();
92 | break;
93 | case Digits::Two:
94 | width = fontMetrics.boundingRect(m_leftmostDigit->text()).width() + fontMetrics.boundingRect(m_centerDigit->text()).width();
95 | break;
96 | case Digits::Three:
97 | width = fontMetrics.boundingRect(m_leftmostDigit->text()).width() + fontMetrics.boundingRect(m_centerDigit->text()).width() + fontMetrics.boundingRect(m_rightmostDigit->text()).width();
98 | break;
99 | default:
100 | break;
101 | }
102 |
103 | width += (width * 10 / 100); // 10% used as padding between digits
104 |
105 | return {width, QWidget::minimumSizeHint().height()};
106 | }
107 |
108 | bool DigitDisplay::isValid(const QString &text) const
109 | {
110 | switch (m_digits) {
111 | case Digits::One:
112 | return text.size() == 1;
113 | case Digits::Two:
114 | return text.size() == 2;
115 | case Digits::Three:
116 | return text.size() == 3;
117 | default:
118 | return false;
119 | }
120 | }
121 |
122 | void DigitDisplay::showOneDigit(const QString& digit) const
123 | {
124 | if (!isValid(digit)) {
125 | return;
126 | }
127 |
128 | m_leftmostDigit->setText(digit.at(0));
129 | }
130 |
131 | void DigitDisplay::showTwoDigits(const QString& digits) const
132 | {
133 | if (!isValid(digits)) {
134 | return;
135 | }
136 |
137 | // digits are displayed from right to left
138 | m_centerDigit->setText(digits.at(1));
139 | m_leftmostDigit->setText(digits.at(0));
140 | }
141 |
142 | void DigitDisplay::showThreeDigits(const QString& digits) const
143 | {
144 | if (!isValid(digits)) {
145 | return;
146 | }
147 |
148 | // digits are displayed from right to left
149 | m_rightmostDigit->setText(digits.at(2));
150 | m_centerDigit->setText(digits.at(1));
151 | m_leftmostDigit->setText(digits.at(0));
152 | }
153 |
154 | #include "moc_digitdisplay.cpp"
155 |
--------------------------------------------------------------------------------
/src/gui/sessiondialog.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2015 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #include "sessiondialog.h"
8 | #include "sessionmodel.h"
9 |
10 | #include
11 | #include
12 | #include
13 | #include
14 |
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 |
22 | SessionDialog::SessionDialog(SessionModel *sessionModel, QWidget *parent) : QDialog(parent, Qt::Dialog)
23 | {
24 | setupUi(this);
25 | m_sessionModel = sessionModel;
26 |
27 | m_proxyModel = new QSortFilterProxyModel {this};
28 | m_proxyModel->setSourceModel(m_sessionModel);
29 |
30 | m_sessionView->setModel(m_proxyModel);
31 | m_sessionView->resizeColumnsToContents();
32 | // TODO: the user may want to select/remove more than one session
33 |
34 | m_msgWidget->hide();
35 | m_buttonBox->button(QDialogButtonBox::Ok)->setText(i18nc("@action:button", "Open session"));
36 |
37 | connect(m_sessionView, &QTableView::doubleClicked, this, &SessionDialog::slotDoubleClicked);
38 | connect(m_sessionView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &SessionDialog::slotSelectionChanged);
39 | connect(m_buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
40 | connect(m_sessionModel, &SessionModel::rowsInserted, this, &SessionDialog::slotSessionAdded);
41 | connect(m_sessionModel, &SessionModel::rowsRemoved, this, &SessionDialog::slotEmptyModel);
42 |
43 | slotEmptyModel();
44 | slotSelectionChanged();
45 |
46 | auto screens = QGuiApplication::screens();
47 | // Set a good default size, tested on 1920x1200 and 1366x768 screens.
48 | resize(screens[0]->size() / 2.5);
49 | }
50 |
51 | Session SessionDialog::selectedSession() const
52 | {
53 | return m_selectedSession;
54 | }
55 |
56 | void SessionDialog::keyPressEvent(QKeyEvent *event)
57 | {
58 | if (event->key() == Qt::Key_Delete && !m_sessionModel->isEmpty()) {
59 | removeDialog();
60 | }
61 |
62 | QDialog::keyPressEvent(event);
63 | }
64 |
65 | void SessionDialog::accept()
66 | {
67 | m_selectedSession = m_sessionModel->data(selectedIndex(), static_cast(SessionModel::Roles::SessionRole)).value();
68 | QDialog::accept();
69 | }
70 |
71 | void SessionDialog::slotDoubleClicked(const QModelIndex& index)
72 | {
73 | if (m_sessionModel->isEditable(index))
74 | return;
75 |
76 | this->accept();
77 | }
78 |
79 | void SessionDialog::slotSelectionChanged()
80 | {
81 | auto openButton = m_buttonBox->button(QDialogButtonBox::Ok);
82 | m_sessionView->selectionModel()->hasSelection() ? openButton->setEnabled(true) : openButton->setEnabled(false);
83 | }
84 |
85 | void SessionDialog::slotSessionAdded()
86 | {
87 | auto openButton = m_buttonBox->button(QDialogButtonBox::Ok);
88 |
89 | if (openButton->isEnabled())
90 | return;
91 |
92 | openButton->setEnabled(true);
93 | openButton->setToolTip(QString());
94 | }
95 |
96 | void SessionDialog::slotEmptyModel()
97 | {
98 | if (!m_sessionModel->isEmpty())
99 | return;
100 |
101 | const auto message = i18nc("@info", "You don't have any saved session yet.");
102 |
103 | auto openButton = m_buttonBox->button(QDialogButtonBox::Ok);
104 | openButton->setEnabled(false);
105 | openButton->setToolTip(message);
106 |
107 | m_msgWidget->setMessageType(KMessageWidget::Information);
108 | m_msgWidget->setText(message);
109 | m_msgWidget->animatedShow();
110 | }
111 |
112 | QModelIndex SessionDialog::selectedIndex()
113 | {
114 | auto sortedIndex = m_sessionView->selectionModel()->currentIndex();
115 |
116 | return m_proxyModel->mapToSource(sortedIndex);
117 | }
118 |
119 | void SessionDialog::removeDialog()
120 | {
121 | const auto buttonCode = KMessageBox::warningTwoActions(
122 | this,
123 | i18nc("@info", "Do you want to remove the selected session?"),
124 | i18nc("@title:window", "Confirm deletion"),
125 | KStandardGuiItem::remove(),
126 | KStandardGuiItem::cancel(),
127 | QStringLiteral("delete-session"));
128 |
129 | if (buttonCode != KMessageBox::PrimaryAction)
130 | return;
131 |
132 | m_sessionModel->removeRow(selectedIndex().row());
133 | }
134 |
135 |
136 | #include "moc_sessiondialog.cpp"
137 |
--------------------------------------------------------------------------------
/desktop/org.kde.kronometer.desktop:
--------------------------------------------------------------------------------
1 | [Desktop Entry]
2 | Type=Application
3 | Exec=kronometer
4 | Icon=kronometer
5 | Terminal=false
6 | Name=Kronometer
7 | Name[ar]=كرونومتر
8 | Name[bs]=Kronometer
9 | Name[ca]=Kronometer
10 | Name[ca@valencia]=Kronometer
11 | Name[cs]=Kronometer
12 | Name[da]=Kronometer
13 | Name[de]=Kronometer
14 | Name[el]=Kronometer
15 | Name[en_GB]=Kronometer
16 | Name[eo]=Kronometer
17 | Name[es]=Kronometer
18 | Name[et]=Kronometer
19 | Name[eu]=Kronometer
20 | Name[fi]=Kronometer
21 | Name[fr]=Kronometer
22 | Name[gl]=Kronometer
23 | Name[he]=קרונומטר
24 | Name[hu]=Kronometer
25 | Name[ia]=Kronometer
26 | Name[it]=Kronometer
27 | Name[ka]=Kronometer
28 | Name[ko]=Kronometer
29 | Name[lt]=Kronometer
30 | Name[lv]=Kronometer
31 | Name[nds]=Kronometer
32 | Name[nl]=Kronometer
33 | Name[nn]=Kronometer
34 | Name[pl]=Kronometer
35 | Name[pt]=Kronometer
36 | Name[pt_BR]=Kronometer
37 | Name[ro]=Kronometer
38 | Name[ru]=Kronometer
39 | Name[sa]=क्रोनोमीटर्
40 | Name[sk]=Kronometer
41 | Name[sl]=Kronometer
42 | Name[sv]=Kronometer
43 | Name[tr]=Kronometre
44 | Name[uk]=Kronometer
45 | Name[zh_CN]=Kronometer 计时器
46 | Name[zh_TW]=Kronometer
47 | GenericName=Chronometer
48 | GenericName[ar]=مقياس الزمن
49 | GenericName[bs]=Mjerač vremena
50 | GenericName[ca]=Cronòmetre
51 | GenericName[ca@valencia]=Cronòmetre
52 | GenericName[cs]=Stopky
53 | GenericName[da]=Kronometer
54 | GenericName[de]=Zeitmesser
55 | GenericName[el]=Χρονόμετρο
56 | GenericName[en_GB]=Chronometer
57 | GenericName[eo]=Kronometro
58 | GenericName[es]=Cronómetro
59 | GenericName[et]=Kronomeeter
60 | GenericName[eu]=kronometroa
61 | GenericName[fi]=Sekuntikello
62 | GenericName[fr]=Chronomètre
63 | GenericName[gl]=Cronómetro
64 | GenericName[he]=כרונומטר
65 | GenericName[hu]=Kronométer
66 | GenericName[ia]=Chronometro
67 | GenericName[it]=Cronometro
68 | GenericName[ka]=ქრონომეტრი
69 | GenericName[ko]=크로노미터
70 | GenericName[lt]=Chronometras
71 | GenericName[lv]=Hronometrs
72 | GenericName[nds]=Tietmeter
73 | GenericName[nl]=Chronometer
74 | GenericName[nn]=Kronometer
75 | GenericName[pl]=Chronometr
76 | GenericName[pt]=Cronómetro
77 | GenericName[pt_BR]=Cronômetro
78 | GenericName[ro]=Cronometru
79 | GenericName[ru]=Секундомер
80 | GenericName[sa]=क्रोनोमीटर
81 | GenericName[sk]=Chronometer
82 | GenericName[sl]=Časomer
83 | GenericName[sv]=Kronometer
84 | GenericName[tr]=Kronometre
85 | GenericName[uk]=Хронометр
86 | GenericName[zh_CN]=计时器
87 | GenericName[zh_TW]=精密計時器
88 | Comment=A simple chronometer application by KDE
89 | Comment[ar]=تطبيق مقياس زمن بسيط من كيدي
90 | Comment[ca]=Una aplicació senzilla de cronòmetre, creada per la comunitat KDE
91 | Comment[ca@valencia]=Una aplicació senzilla de cronòmetre, creada per la comunitat KDE
92 | Comment[cs]=Jednoduchá aplikace stopek od KDE
93 | Comment[da]=Et simpelt kronometerprogram af KDE
94 | Comment[de]=Eine einfache Anwendung für die Zeitmessung von KDE
95 | Comment[el]=Μια απλή εφαρμογή χρονομέτρου από το KDE
96 | Comment[en_GB]=A simple chronometer application by KDE
97 | Comment[eo]=Simpla kronometra aplikaĵo de KDE
98 | Comment[es]=Una sencilla aplicación de cronómetro creada por KDE
99 | Comment[et]=KDE lihtne stopperirakendus
100 | Comment[eu]=KDE-ren kronometro sinple aplikazioa
101 | Comment[fi]=KDE:n yksinkertainen sekuntikellosovellus
102 | Comment[fr]=Une simple application de chronomètre par KDE
103 | Comment[gl]=Unha aplicación sinxela creada por KDE para cronometrar
104 | Comment[he]=יישום כרונומטר פשוט מבית KDE
105 | Comment[ia]=Un simple applicatin de chronometro per KDE
106 | Comment[it]=Un semplice cronometro da KDE
107 | Comment[ka]=ქრონომეტრის მარტივი აპლიკაცია KDE-სგან
108 | Comment[ko]=KDE의 간단한 크로노미터 앱
109 | Comment[lt]=Paprasta KDE chronometro programa
110 | Comment[lv]=Vienkāršs KDE hronometrs
111 | Comment[nl]=Een eenvoudige chronometer-toepassing door KDE
112 | Comment[nn]=Enkelt kronometerprogram frå KDE
113 | Comment[pl]=Prosta aplikacja chronometru autorstwa KDE
114 | Comment[pt]=Uma aplicação simples de cronómetro do KDE
115 | Comment[pt_BR]=Um cronômetro simples do KDE
116 | Comment[ro]=Aplicație simplă de cronometru de la KDE
117 | Comment[ru]=Простое приложение-секундомер от KDE
118 | Comment[sa]=KDE द्वारा एकः सरलः क्रोनोमीटर् अनुप्रयोगः
119 | Comment[sk]=Jednoduchá aplikácia chronometra pre KDE
120 | Comment[sl]=Preprost časomer s strani KDE
121 | Comment[sv]=Ett enkelt kronometerprogram av KDE
122 | Comment[tr]=KDE tarafından yapılan yalın bir kronometre uygulaması
123 | Comment[uk]=Проста програма-хронометр від KDE
124 | Comment[zh_CN]=由 KDE 打造的简单计时器应用程序
125 | Comment[zh_TW]=來自 KDE 的精密計時應用程式
126 | Categories=Qt;KDE;Utility;Clock;
127 | X-DocPath=kronometer/index.html
128 |
--------------------------------------------------------------------------------
/src/core/stopwatch.h:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2014 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #ifndef STOPWATCH_H
8 | #define STOPWATCH_H
9 |
10 | #include
11 | #include
12 | #include
13 |
14 | class QTimerEvent;
15 |
16 | /**
17 | * @brief A Stopwatch class.
18 | * Stopwatch is a simple QObject implementing a real stopwatch.
19 | * The class provides public Q_SLOTS to start/pause/reset its internal timer.
20 | * A slot for laps recording exists too, but the computing of lap times is not a task of this class:
21 | * Stopwatch simply emits a signal, that the receiver can use to compute lap times.
22 | */
23 | class Stopwatch : public QObject
24 | {
25 | Q_OBJECT
26 |
27 | public:
28 |
29 | enum class Granularity : int
30 | {
31 | Milliseconds = 1, /**< Stopwatch refreshed every msec. */
32 | Hundredths = 10, /**< Stopwatch refreshed every 10 msec. */
33 | Tenths = 100, /**< Stopwatch refreshed every 100 msec. */
34 | Seconds = 1000 /**< Stopwatch refreshed every sec. */
35 | };
36 |
37 | explicit Stopwatch(QObject *parent = nullptr);
38 |
39 | /**
40 | * Set the stopwatch refresh granularity
41 | * @param g The granularity to be set.
42 | */
43 | void setGranularity(Granularity g);
44 |
45 | /**
46 | * Check if the stopwatch is running
47 | * @return true if running, false otherwise
48 | */
49 | bool isRunning() const;
50 |
51 | /**
52 | * Check if the stopwatch is paused
53 | * @return true if paused, false otherwise
54 | */
55 | bool isPaused() const;
56 |
57 | /**
58 | * Check if the stopwatch is inactive
59 | * @return true if inactive, false otherwise
60 | */
61 | bool isInactive() const;
62 |
63 | /**
64 | * Read-only access to the stopwatch underlying data
65 | * @return The stopwatch raw counter
66 | */
67 | int raw() const;
68 |
69 | /**
70 | * (Re)-initialize (deserialize) the stopwatch from the given raw data counter.
71 | * Only an inactive stopwatch is meant to be (re)-initialized (deserialized).
72 | * @param rawData The raw milliseconds counter for the stopwatch
73 | * @return true if the operation succeeds (i.e. the stopwatch was inactive), false otherwise
74 | */
75 | bool initialize(int rawData);
76 |
77 | public Q_SLOTS:
78 |
79 | /**
80 | * Start the stopwatch, if inactive or paused.
81 | */
82 | void start();
83 |
84 | /**
85 | * Pause the stopwatch, if running.
86 | */
87 | void pause();
88 |
89 | /**
90 | * Reset the stopwatch to the inactive state.
91 | */
92 | void reset();
93 |
94 | /**
95 | * Tells the stopwatch to compute a new lap time.
96 | */
97 | void storeLap();
98 |
99 | Q_SIGNALS:
100 |
101 | /**
102 | * The stopwatch has been started.
103 | */
104 | void running();
105 |
106 | /**
107 | * The stopwatch has been paused.
108 | */
109 | void paused();
110 |
111 | /**
112 | * The stopwatch has been reset.
113 | */
114 | void inactive();
115 |
116 | /**
117 | * Emits a signal with the last lap *absolute* time.
118 | * This class does not compute *relatives* lap times.
119 | * You can compute them simply by the difference between consecutives absolute times.
120 | * @param lapTime The absolute time of the last lap.
121 | */
122 | void lap(const QTime& lapTime);
123 |
124 | /**
125 | * Emits a signal with the current stopwatch time.
126 | * @param t Current stopwatch time.
127 | */
128 | void time(int t);
129 |
130 | protected:
131 |
132 | void timerEvent(QTimerEvent *event) override;
133 |
134 | private:
135 |
136 | int granularity() const;
137 |
138 | enum class State
139 | {
140 | Inactive, /**< Inactive stopwatch. */
141 | Running, /**< Running stopwatch. */
142 | Paused /**< Paused stopwatch. */
143 | };
144 |
145 | static constexpr int INACTIVE_TIMER_ID = -1; /** Used for timerId initialization */
146 |
147 | int m_timerId = INACTIVE_TIMER_ID; /** ID for the QObject timer */
148 | int m_accumulator = 0; /** milliseconds internal counter */
149 | State m_state = State::Inactive; /** Stopwatch current state */
150 | Granularity m_granularity = Granularity::Hundredths; /** Stopwatch current granularity */
151 |
152 | QElapsedTimer m_elapsedTimer; /** Stopwatch core class*/
153 |
154 | Q_DISABLE_COPY(Stopwatch)
155 | };
156 |
157 |
158 |
159 | #endif
160 |
--------------------------------------------------------------------------------
/src/models/lapmodel.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2014 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #include "lapmodel.h"
8 |
9 | #include
10 |
11 | #include
12 |
13 | LapModel::LapModel(QObject* parent) : QAbstractTableModel(parent)
14 | {}
15 |
16 | int LapModel::columnCount(const QModelIndex& parent) const
17 | {
18 | Q_UNUSED(parent)
19 |
20 | return m_roles.count();
21 | }
22 |
23 | int LapModel::rowCount(const QModelIndex& parent) const
24 | {
25 | Q_UNUSED(parent)
26 |
27 | return m_laps.size();
28 | }
29 |
30 | QVariant LapModel::data(const QModelIndex& index, int role) const
31 | {
32 | if (!index.isValid()) {
33 | return QVariant::Invalid;
34 | }
35 |
36 | if (index.row() >= rowCount() || index.row() < 0) {
37 | return QVariant::Invalid;
38 | }
39 |
40 | if (role == Qt::DisplayRole) {
41 | return data(index, Qt::UserRole + index.column());
42 | }
43 |
44 | switch (static_cast(role)) {
45 | case Roles::LapIdRole:
46 | return index.row() + 1;
47 | case Roles::RelativeTimeRole:
48 | return m_laps.at(index.row()).relativeTime();
49 | case Roles::AbsoluteTimeRole:
50 | return m_laps.at(index.row()).absoluteTime();
51 | case Roles::NoteRole:
52 | return m_laps.at(index.row()).note();
53 | case Roles::LapRole:
54 | return QVariant::fromValue(m_laps.at(index.row()));
55 | }
56 |
57 | if (role == Qt::EditRole && index.column() == columnForRole(Roles::NoteRole)) {
58 | // prevent the disappear of the old value when double-clicking the item
59 | return m_laps.at(index.row()).note();
60 | }
61 |
62 | return QVariant::Invalid;
63 | }
64 |
65 | QVariant LapModel::headerData(int section, Qt::Orientation orientation, int role) const
66 | {
67 | if (role != Qt::DisplayRole || orientation != Qt::Horizontal)
68 | return QVariant::Invalid;
69 |
70 | switch (roleForColumn(section)) {
71 | case Roles::LapIdRole:
72 | return i18nc("lap number", "Lap #");
73 | case Roles::RelativeTimeRole:
74 | return i18nc("@title:column", "Lap Time");
75 | case Roles::AbsoluteTimeRole:
76 | return i18nc("@title:column", "Global Time");
77 | case Roles::NoteRole:
78 | return i18nc("@title:column", "Note");
79 | case Roles::LapRole:
80 | break;
81 | }
82 |
83 | return QVariant::Invalid;
84 | }
85 |
86 | bool LapModel::setData(const QModelIndex& index, const QVariant& value, int role)
87 | {
88 | if (!index.isValid() || role != Qt::EditRole)
89 | return false;
90 |
91 | if (index.column() != columnForRole(Roles::NoteRole))
92 | return false;
93 |
94 | m_laps[index.row()].setNote(value.toString());
95 | Q_EMIT dataChanged(index, index);
96 |
97 | return true;
98 | }
99 |
100 | Qt::ItemFlags LapModel::flags(const QModelIndex& index) const
101 | {
102 | if (!index.isValid())
103 | return Qt::ItemIsEnabled;
104 |
105 | if (index.column() != columnForRole(Roles::NoteRole))
106 | return QAbstractTableModel::flags(index);
107 |
108 | return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;
109 | }
110 |
111 | void LapModel::setTimeFormat(const TimeFormat& format)
112 | {
113 | m_timeFormat = format;
114 |
115 | if (!isEmpty()) {
116 | reload();
117 | }
118 | }
119 |
120 | void LapModel::append(const Lap& lap)
121 | {
122 | // Append the new row at the end.
123 | beginInsertRows(QModelIndex(), rowCount(), rowCount());
124 |
125 | // Either the time of the first lap or the time relative to the last lap.
126 | const auto relativeTime = m_laps.isEmpty() ? lap.time() : m_laps.last().timeTo(lap);
127 |
128 | auto newLap = Lap {lap};
129 | newLap.setRelativeTime(m_timeFormat.format(relativeTime));
130 | newLap.setAbsoluteTime(m_timeFormat.format(newLap.time()));
131 |
132 | m_laps.append(newLap);
133 | endInsertRows();
134 | }
135 |
136 | bool LapModel::isEmpty() const
137 | {
138 | return m_laps.isEmpty();
139 | }
140 |
141 | int LapModel::columnForRole(LapModel::Roles role) const
142 | {
143 | return m_roles.indexOf(role);
144 | }
145 |
146 | void LapModel::addLap(const QTime& lapTime)
147 | {
148 | append(Lap {lapTime});
149 | }
150 |
151 | void LapModel::clear()
152 | {
153 | beginResetModel();
154 | m_laps.clear();
155 | endResetModel();
156 | }
157 |
158 | void LapModel::reload()
159 | {
160 | const auto laps = m_laps;
161 | clear();
162 |
163 | for (const auto& lap : laps) {
164 | append(lap);
165 | }
166 | }
167 |
168 | LapModel::Roles LapModel::roleForColumn(int column) const
169 | {
170 | return m_roles.at(column);
171 | }
172 |
173 | #include "moc_lapmodel.cpp"
174 |
--------------------------------------------------------------------------------
/src/core/timeformat.h:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2014 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #ifndef TIMEFORMAT_H
8 | #define TIMEFORMAT_H
9 |
10 | #include
11 |
12 | class QTime;
13 |
14 | /**
15 | * @brief A wrapper for a QTime-like format time string.
16 | * A TimeFormat is an abstraction for a QTime-like string used for time formats.
17 | * A TimeFormat can be customized using booleans in the constructor.
18 | * The QTime-syntax used is the following:
19 | * "hh:" whether to show hours (00 to 24)
20 | * "mm:" whether to show minutes (00 to 59)
21 | * "ss." whether to show seconds (00 to 59). Seconds are always showed.
22 | * "zzz" whether to show second fractions (tenths or hundredths or milliseconds)
23 | * An example of time formatted with the complete syntax might be the following: 0:05:38.582
24 | */
25 | class TimeFormat
26 | {
27 |
28 | public:
29 |
30 | enum SecondFraction
31 | {
32 | UpToTenths, /**< Second fraction is tenths of second. */
33 | UpToHundredths, /**< Second fraction is hundrdths of second. */
34 | UpToMilliseconds, /**< Second fraction is milliseconds. */
35 | NoFractions /**< Second fraction disabled. */
36 | };
37 |
38 | explicit TimeFormat(bool showHours = false, bool showMinutes = true, SecondFraction fractions = UpToHundredths);
39 |
40 | /**
41 | * Format the given time with the current time format.
42 | * @param time The time to be formatted.
43 | * @return The time formatted as string.
44 | */
45 | QString format(const QTime& time) const;
46 |
47 | /**
48 | * Format the given time's hours with the current time format.
49 | * @param time The time to be formatted.
50 | * @return The time's hours formatted as string, or empty string if hour is not in the format.
51 | */
52 | QString formatHours(const QTime& time) const;
53 |
54 | /**
55 | * Format the given time's minutes with the current time format.
56 | * @param time The time to be formatted.
57 | * @return The time's minutes formatted as string, or empty string if minute is not in the format.
58 | */
59 | QString formatMinutes(const QTime& time) const;
60 |
61 | /**
62 | * Format the given time's seconds with the current time format.
63 | * @param time The time to be formatted.
64 | * @return The time's seconds formatted as string, or empty string if second is not in the format.
65 | */
66 | QString formatSeconds(const QTime& time) const;
67 |
68 | /**
69 | * Format the given time's second fractions with the current time format.
70 | * @param time The time to be formatted.
71 | * @return The time's second fractions formatted as string, or empty string if second fraction is not in the format.
72 | */
73 | QString formatFractions(const QTime& time) const;
74 |
75 | /**
76 | * Enable the hours in the time format.
77 | */
78 | void overrideHours();
79 |
80 | /**
81 | * Enable minutes in the time format.
82 | */
83 | void overrideMinutes();
84 |
85 | /**
86 | * Whether the hour is in the time format.
87 | * @return true if hour is in the format, false otherwise.
88 | */
89 | bool hasHours() const;
90 |
91 | /**
92 | * Whether the minute is in the time format.
93 | * @return true if minute is in the format, false otherwise.
94 | */
95 | bool hasMinutes() const;
96 |
97 | /**
98 | * Whether the second fraction is in the time format.
99 | * @return true if second fraction is in the format, false otherwise.
100 | */
101 | bool hasFractions() const;
102 |
103 | /**
104 | * @return The current FractionType in the time format.
105 | */
106 | SecondFraction secondFractions() const;
107 |
108 | /**
109 | * Whether to show the symbols ':' and '.' used as dividers in the time format.
110 | * @param show true Whether to show the dividers.
111 | */
112 | void showDividers(bool show);
113 |
114 | bool operator==(const TimeFormat& right) const;
115 | bool operator!=(const TimeFormat& right) const;
116 |
117 | private:
118 |
119 | bool m_showHours; /** Whether hour is in the internal time format */
120 | bool m_showMinutes; /** Whether minute is in the internal time format */
121 | bool m_showDividers = true; /** Whether to show the symbols used as dividers */
122 |
123 | QString m_hourFormat; /** Hour string format */
124 | QString m_minFormat; /** Minute string format */
125 | QString m_secFormat; /** Secondstring format */
126 | SecondFraction m_fractions; /** Second fraction internal time format */
127 |
128 | /**
129 | * Setup the format strings based on the internal formats
130 | */
131 | void setupFormat();
132 | };
133 |
134 | #endif
135 |
--------------------------------------------------------------------------------
/src/gui/timedisplay.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2014 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #include "timedisplay.h"
8 | #include "digitdisplay.h"
9 |
10 | #include
11 |
12 | #include
13 |
14 | TimeDisplay::TimeDisplay(QWidget *parent) : QWidget(parent)
15 | {
16 | setupUi(this);
17 |
18 | m_hourDisplay->setDigits(DigitDisplay::Digits::Two);
19 | m_minDisplay->setDigits(DigitDisplay::Digits::Two);
20 | m_secDisplay->setDigits(DigitDisplay::Digits::Two);
21 |
22 | m_hourDisplay->showDigits(m_currentFormat.formatHours(m_displayTime));
23 | m_minDisplay->showDigits(m_currentFormat.formatMinutes(m_displayTime));
24 | m_secDisplay->showDigits(m_currentFormat.formatSeconds(m_displayTime));
25 | m_fracDisplay->showDigits(m_currentFormat.formatFractions(m_displayTime));
26 | }
27 |
28 | void TimeDisplay::setTimeFormat(const TimeFormat& format)
29 | {
30 | m_defaultFormat = format;
31 | m_currentFormat = format;
32 | updateTimeFormat();
33 | }
34 |
35 | void TimeDisplay::setHoursFont(const QFont& font)
36 | {
37 | m_hourDisplay->setFont(font);
38 | updateWidth();
39 | }
40 |
41 | void TimeDisplay::setMinutesFont(const QFont& font)
42 | {
43 | m_minDisplay->setFont(font);
44 | updateWidth();
45 | }
46 |
47 | void TimeDisplay::setSecondsFont(const QFont& font)
48 | {
49 | m_secDisplay->setFont(font);
50 | updateWidth();
51 | }
52 |
53 | void TimeDisplay::setFractionsFont(const QFont& font)
54 | {
55 | m_fracDisplay->setFont(font);
56 | updateWidth();
57 | }
58 |
59 | void TimeDisplay::setBackgroundColor(const QColor& color)
60 | {
61 | setGroupboxColor(m_hourGroup, m_hourGroup->backgroundRole(), color);
62 | setGroupboxColor(m_minGroup, m_minGroup->backgroundRole(), color);
63 | setGroupboxColor(m_secGroup, m_secGroup->backgroundRole(), color);
64 | setGroupboxColor(m_fracGroup, m_fracGroup->backgroundRole(), color);
65 | update();
66 | }
67 |
68 | void TimeDisplay::setTextColor(const QColor& color)
69 | {
70 | setGroupboxColor(m_hourGroup, m_hourGroup->foregroundRole(), color);
71 | setGroupboxColor(m_minGroup, m_minGroup->foregroundRole(), color);
72 | setGroupboxColor(m_secGroup, m_secGroup->foregroundRole(), color);
73 | setGroupboxColor(m_fracGroup, m_fracGroup->foregroundRole(), color);
74 | update();
75 | }
76 |
77 | QString TimeDisplay::currentTime()
78 | {
79 | m_currentFormat.showDividers(true);
80 | const auto currentTime = m_currentFormat.format(m_displayTime);
81 | m_currentFormat.showDividers(false);
82 |
83 | return currentTime;
84 | }
85 |
86 | void TimeDisplay::setTime(int time)
87 | {
88 | m_displayTime.setHMS(time / MSECS_PER_HOUR,
89 | (time % MSECS_PER_HOUR) / MSECS_PER_MIN,
90 | (time / MSECS_PER_SEC) % 60,
91 | time % MSECS_PER_SEC);
92 |
93 | updateTimer();
94 | }
95 |
96 | void TimeDisplay::reset()
97 | {
98 | if (m_currentFormat == m_defaultFormat)
99 | return;
100 |
101 | setTimeFormat(m_defaultFormat);
102 | }
103 |
104 | void TimeDisplay::updateTimer()
105 | {
106 | if (m_currentFormat.hasHours()) {
107 | m_hourDisplay->showDigits(m_currentFormat.formatHours(m_displayTime));
108 | }
109 | else if (m_displayTime.hour() >= 1) {
110 | m_currentFormat.overrideHours();
111 | updateTimeFormat();
112 | }
113 |
114 | if (m_currentFormat.hasMinutes()) {
115 | m_minDisplay->showDigits(m_currentFormat.formatMinutes(m_displayTime));
116 | }
117 | else if (m_displayTime.minute() >= 1) {
118 | m_currentFormat.overrideMinutes();
119 | updateTimeFormat();
120 | }
121 |
122 | m_secDisplay->showDigits(m_currentFormat.formatSeconds(m_displayTime));
123 |
124 | if (m_currentFormat.hasFractions()) {
125 | m_fracDisplay->showDigits(m_currentFormat.formatFractions(m_displayTime));
126 | }
127 | }
128 |
129 | void TimeDisplay::updateWidth()
130 | {
131 | auto width = qMax(qMax(m_hourDisplay->minimumSizeHint().width(),
132 | m_minDisplay->minimumSizeHint().width()),
133 | qMax(m_secDisplay->minimumSizeHint().width(),
134 | m_fracDisplay->minimumSizeHint().width()));
135 |
136 | width = width + (width * 40 / 100); // 40% as padding, i.e. 20% as right padding and 20% as left padding
137 |
138 | m_hourGroup->setMinimumWidth(width);
139 | m_minGroup->setMinimumWidth(width);
140 | m_secGroup->setMinimumWidth(width);
141 | m_fracGroup->setMinimumWidth(width);
142 | }
143 |
144 | void TimeDisplay::updateTimeFormat()
145 | {
146 | m_hourGroup->setVisible(m_currentFormat.hasHours());
147 | m_minGroup->setVisible(m_currentFormat.hasMinutes());
148 | m_fracGroup->setVisible(m_currentFormat.hasFractions());
149 |
150 | if (m_currentFormat.hasFractions()) {
151 | switch (m_currentFormat.secondFractions()) {
152 | case TimeFormat::UpToTenths:
153 | m_fracGroup->setTitle(i18nc("@title:column", "Tenths"));
154 | m_fracDisplay->setDigits(DigitDisplay::Digits::One);
155 | break;
156 | case TimeFormat::UpToHundredths:
157 | m_fracGroup->setTitle(i18nc("@title:column", "Hundredths"));
158 | m_fracDisplay->setDigits(DigitDisplay::Digits::Two);
159 | break;
160 | case TimeFormat::UpToMilliseconds:
161 | m_fracGroup->setTitle(i18nc("@title:column", "Milliseconds"));
162 | m_fracDisplay->setDigits(DigitDisplay::Digits::Three);
163 | break;
164 | default:
165 | break;
166 | }
167 | }
168 |
169 | updateTimer();
170 | }
171 |
172 | void TimeDisplay::setGroupboxColor(QGroupBox *groupBox, QPalette::ColorRole role, const QColor& color)
173 | {
174 | if (!groupBox) {
175 | return;
176 | }
177 |
178 | auto palette = QPalette {groupBox->palette()};
179 | palette.setColor(role, color);
180 | groupBox->setPalette(palette);
181 | }
182 |
183 |
184 | #include "moc_timedisplay.cpp"
185 |
--------------------------------------------------------------------------------
/src/gui/mainwindow.h:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2014 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 |
8 | #ifndef MAINWINDOW_H
9 | #define MAINWINDOW_H
10 |
11 | #include "session.h"
12 |
13 | #include
14 |
15 | #include
16 | #include
17 |
18 | #include
19 |
20 | class LapModel;
21 | class SessionModel;
22 | class Stopwatch;
23 | class TimeDisplay;
24 |
25 | class KToggleAction;
26 |
27 | class QAction;
28 | class QDBusInterface;
29 | class QLabel;
30 | class QSortFilterProxyModel;
31 | class QSplitter;
32 | class QTableView;
33 | class QTextStream;
34 | class QToolButton;
35 |
36 | /**
37 | * @brief Kronometer main window.
38 | */
39 | class MainWindow : public KXmlGuiWindow
40 | {
41 | Q_OBJECT
42 |
43 | public:
44 |
45 | explicit MainWindow(SessionModel *sessionModel, QWidget *parent = nullptr, const Session& session = Session {});
46 | virtual ~MainWindow();
47 |
48 | /**
49 | * @param title The title for this window.
50 | */
51 | void setWindowTitle(const QString& title);
52 |
53 | void enableLapShortcuts(bool enable);
54 |
55 | protected:
56 |
57 | bool queryClose() override;
58 |
59 | private Q_SLOTS:
60 |
61 | /**
62 | * Stopwatch running state triggers.
63 | */
64 | void slotRunning();
65 |
66 | /**
67 | * Stopwatch paused state triggers.
68 | */
69 | void slotPaused();
70 |
71 | /**
72 | * Stopwatch inactive state triggers.
73 | */
74 | void slotInactive();
75 |
76 | /**
77 | * Slot for the system bus PrepareForSleep signal.
78 | * @param beforeSleep Whether the signal has been emitted before suspension.
79 | */
80 | void slotPrepareForSleep(bool beforeSleep);
81 |
82 | /**
83 | * Setup the settings dialog.
84 | */
85 | void slotShowSettings();
86 |
87 | /**
88 | * Write the new settings on filesystem.
89 | */
90 | void slotWriteSettings();
91 |
92 | /**
93 | * Fix lap dock appereance.
94 | */
95 | void slotUpdateLapDock();
96 |
97 | /**
98 | * Open a new MainWindow instance.
99 | */
100 | void slotNewSession();
101 |
102 | /**
103 | * Open an existing session in a new MainWindow instance.
104 | */
105 | void slotOpenSession();
106 |
107 | /**
108 | * Save current times in the current session.
109 | */
110 | void slotSaveSession();
111 |
112 | /**
113 | * Save current times as a new session.
114 | */
115 | void slotSaveSessionAs();
116 |
117 | /**
118 | * Export current lap times on a file.
119 | */
120 | void slotExportLapsAs();
121 |
122 | /**
123 | * Copy current stopwatch time to clipboard.
124 | */
125 | void slotCopyToClipboard();
126 |
127 | /**
128 | * Toggle menubar visibility.
129 | */
130 | void slotToggleMenuBar();
131 |
132 | void slotUpdateControlMenu();
133 |
134 | void slotToolBarUpdated();
135 |
136 | private:
137 |
138 | bool m_startTimerImmediately = false;
139 | Stopwatch *m_stopwatch;
140 | TimeDisplay *m_stopwatchDisplay;
141 | QTableView *m_lapView;
142 |
143 | QAction *m_startAction;
144 | QAction *m_pauseAction;
145 | QAction *m_resetAction;
146 | QAction *m_lapAction;
147 | QAction *m_exportAction;
148 | std::unique_ptr m_controlMenuTimer;
149 | QPointer m_controlMenuButton;
150 | KToggleAction *m_toggleMenuAction;
151 |
152 | LapModel *m_lapModel;
153 | SessionModel *m_sessionModel;
154 |
155 | Session m_session;
156 |
157 | #ifndef Q_OS_WINDOWS
158 | QDBusInterface *m_screensaverInterface = nullptr;
159 | quint32 m_screenInhibitCookie = 0;
160 | #endif
161 |
162 | /**
163 | * Setup the central widget of the window.
164 | */
165 | void setupCentralWidget();
166 |
167 | /**
168 | * Setup standard and custom QActions.
169 | */
170 | void setupActions();
171 |
172 | /**
173 | * Load settings from app Config and apply them to the other objects.
174 | */
175 | void loadSettings();
176 |
177 | /**
178 | * Set the stopwatch refresh granularity.
179 | */
180 | void setupGranularity();
181 |
182 | /**
183 | * Create a session with the current stopwatch time and lap times.
184 | * @param name The name of the session to be saved.
185 | */
186 | void saveSessionAs(const QString& name);
187 |
188 | /**
189 | * Load a saved session.
190 | */
191 | void loadSession();
192 |
193 | /**
194 | * Export current lap times on a new file.
195 | * @param name The name of the file to be created.
196 | * @param mimeType The mime type of the file to be created.
197 | */
198 | void exportLapsAs(const QString& name, const QString& mimeType);
199 |
200 | /**
201 | * Write the JSON laps representation on the given object.
202 | * @param json The JSON object to be written.
203 | */
204 | void exportLapsAsJson(QJsonObject& json);
205 |
206 | /**
207 | * Write the CSV laps representation on the given stream.
208 | * @param out The stream to be written.
209 | */
210 | void exportLapsAsCsv(QTextStream& out);
211 |
212 | /**
213 | * @return Whether there is a window size saved in the kronometer config.
214 | */
215 | bool isWindowSizeSaved() const;
216 |
217 | /**
218 | * A "comment" message with timestamp, to be used in the created files.
219 | * @return The string "Created by Kronomer on "
220 | */
221 | QString timestampMessage();
222 |
223 | void createControlMenuButton();
224 |
225 | void deleteControlMenuButton();
226 |
227 | /**
228 | * @return true if @p action has been added to @p menu;
229 | * false if @p action or @p menu is null, or if @p action
230 | * is already on the toolBar().
231 | */
232 | bool addActionToMenu(QAction* action, QMenu* menu);
233 |
234 | void activateScreenInhibition();
235 |
236 | void disactivateScreenInhibition();
237 |
238 | Q_DISABLE_COPY(MainWindow)
239 | };
240 |
241 |
242 | #endif
243 |
--------------------------------------------------------------------------------
/src/gui/fontsettings.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | FontSettings
4 |
5 |
6 |
7 | 0
8 | 0
9 | 1031
10 | 681
11 |
12 |
13 |
14 | -
15 |
16 |
-
17 |
18 |
-
19 |
20 |
-
21 |
22 |
23 | Hours Font:
24 |
25 |
26 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
27 |
28 |
29 |
30 | -
31 |
32 |
33 |
34 | 0
35 | 0
36 |
37 |
38 |
39 |
40 | Sans Serif
41 | 54
42 | 50
43 | false
44 | false
45 |
46 |
47 |
48 |
49 |
50 |
51 | -
52 |
53 |
-
54 |
55 |
56 | Minutes Font:
57 |
58 |
59 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
60 |
61 |
62 |
63 | -
64 |
65 |
66 |
67 | 0
68 | 0
69 |
70 |
71 |
72 |
73 | Sans Serif
74 | 54
75 | 50
76 | false
77 | false
78 |
79 |
80 |
81 |
82 |
83 |
84 | -
85 |
86 |
-
87 |
88 |
89 | Seconds Font:
90 |
91 |
92 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
93 |
94 |
95 |
96 | -
97 |
98 |
99 |
100 | 0
101 | 0
102 |
103 |
104 |
105 |
106 | Sans Serif
107 | 54
108 | 50
109 | false
110 | false
111 |
112 |
113 |
114 |
115 |
116 |
117 | -
118 |
119 |
-
120 |
121 |
122 | Second Fractions Font:
123 |
124 |
125 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
126 |
127 |
128 |
129 | -
130 |
131 |
132 |
133 | 0
134 | 0
135 |
136 |
137 |
138 |
139 | Sans Serif
140 | 54
141 | 50
142 | false
143 | false
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 | -
153 |
154 |
155 | Qt::Horizontal
156 |
157 |
158 |
159 | 40
160 | 20
161 |
162 |
163 |
164 |
165 |
166 |
167 | -
168 |
169 |
170 | Qt::Vertical
171 |
172 |
173 |
174 | 20
175 | 278
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 | KFontRequester
185 | QWidget
186 |
187 |
188 |
189 |
190 |
191 |
192 |
--------------------------------------------------------------------------------
/CHANGELOG:
--------------------------------------------------------------------------------
1 | v2.3.0
2 | * Introduced Qt6 support.
3 | * Added option to start the stopwatch automatically (thanks to Miguel Carrillo).
4 | * Added support for HiDpi screens.
5 | * Fixed wrong times restored from session (BUG 421515)
6 | * Fixed stopwatch restart after system sleep (BUG 439998)
7 | * Fixed deletion of sessions (BUG 353077, thanks to Johnny Jazeix)
8 | * Qt 5.15 and C++17 are now required.
9 | * Fixed compilation on Windows (thanks to Johnny Jazeix).
10 | * Updated translations.
11 |
12 | v2.2.3
13 | * Fixed bug #349861 (thanks to Gaurav Shah): https://bugs.kde.org/show_bug.cgi?id=349861
14 | * Updated translations.
15 |
16 | v2.2.2
17 | * Updated translations.
18 |
19 | v2.2.1
20 | * Fixed laps sorting.
21 | * Updated translations.
22 |
23 | v2.2.0
24 | * Fixed laps export feature.
25 | * Implemented screen inhibition while a stopwatch is running.
26 |
27 | v2.1.5
28 | * Fixed width of columns in the laps view.
29 | * Updated translations.
30 |
31 | v2.1.4
32 | * Updated homepage links
33 |
34 | v2.1.3
35 | * Fix build with ECM >= 5.31
36 | * Prevent warning messagebox with kxmlgui >= 5.30
37 |
38 | v2.1.2
39 | * Fix default size of Session dialog.
40 | * Don't assume there are always sessions saved.
41 | * Updated translations.
42 |
43 | v2.1.1
44 | * Window size can now be restored (BUG 361494)
45 | * Fix wrongly-enabled Save action (BUG 352993)
46 | * Fix appereance of Lap View (BUG 365101)
47 |
48 | v2.1.0
49 | * Improved usability of dialogs.
50 | * Moved toolbar to top position.
51 | * Menubar is now hidden by default.
52 | * Dropped statusbar.
53 |
54 | v2.0.2
55 | * Fixed invisible main window with Qt 5.6
56 |
57 | v2.0.1
58 | * Fixed default height of the Kronometer window (BUG 351746)
59 |
60 | v2.0.0
61 | * Port to Qt5 and KDE Frameworks 5
62 | * New Breeze icons: app icon and start/pause/reset/lap icons
63 | * Sessions persistence through a simple Session dialog, instead of XML files
64 | * Improved the Settings dialog and removed useless settings
65 | * Hours are now hidden by default, both in stopwatch time and laps times.
66 | * Laps absolute times are now hidden by default
67 | * Laps notes can now be hidden
68 | * Suspension awareness: pause running stopwatch if the OS is going to sleep (BUG 349824)
69 | * Cleaned up UI and visible string messages
70 | * Stopwatch time format is automatically ovverridden when needed (BUG 343130)
71 | * Fixed BUG 344714
72 | * Laps can now be exported to the JSON format, but not anymore to XML
73 | * Fixed Kronometer handbook not being shown from Help -> Kronometer Handbook
74 | * Added manpage
75 | * Development: added autotests
76 |
77 | v1.6.0
78 | * UI cleanup in the Settings dialog (bug 343127: http://bugs.kde.org/show_bug.cgi?id=343127)
79 | * Removed the 'Ask On Exit' option (bug 343126: http://bugs.kde.org/show_bug.cgi?id=343126)
80 | * Lap times format is no more ignored (bug 343128: http://bugs.kde.org/show_bug.cgi?id=343128)
81 |
82 | v1.5.2
83 | * Fixed wrong GPLv2 version in COPYING file
84 |
85 | v1.5.1
86 | * Fixed error preventing the building of Opensuse RPM packages
87 |
88 | v1.5.0
89 | * Laps annotations: now you can place a custom text note over a certain lap time
90 | * Option to disable the laps feature and hide the lap button and table
91 | * AppData support
92 | * Fixed bug 338540: https://bugs.kde.org/show_bug.cgi?id=338540
93 |
94 | v1.4.2
95 | * Removed option to hide the statusbar, since it's a built-in KDE feature
96 | * Small fix for digits appearance
97 |
98 | v1.4.1
99 | * Upper toolbar is now correctly removed from the UI
100 |
101 | v1.4.0
102 | * Latest lap time is now automatically selected
103 | * Fixed bug 336904: https://bugs.kde.org/show_bug.cgi?id=336904
104 | * First release with localization in over 11 languages
105 |
106 | v1.3.0
107 | * Major improvements in the stopwatch display UI
108 | * Fixed critical bug with exotic fonts in the stopwatch display
109 | * Removed the upper toolbar to make the UI less crowded (those actions are always available in the File menu)
110 | * Use the official KDE bugtracking system
111 | * Minor layout fix in the settings dialog
112 |
113 | v1.2.2
114 | * Fixed small bug preventing compilation on old compilers
115 |
116 | v1.2.1
117 | * Option to hide the statusbar from the main window
118 | * Official documentation, *Kronometer Handbook* now available in the Help menu
119 |
120 | v1.1.2
121 | * Fixed window-modified placeholder (*) bug on stopwatch reset
122 |
123 | v1.1.1
124 | * Minor bug fixes and improvements
125 |
126 | v1.1.0
127 | * Export lap times to CSV (Comma Separated Values) format
128 | * Export lap times to XML format
129 |
130 | v1.0.0
131 | * First "stable" release of Kronometer
132 | * Fixed the appereance of the laps table-widget
133 | * Added tooltips in Settings dialogs
134 |
135 | v0.9.0
136 | * Times saved on XML files instead of binary files
137 | * Fixed bug on aborting a file opening
138 |
139 | v0.8.0
140 | * Added *Edit* menu with the ability to copy current stopwatch time to clipboard
141 | * Color settings: choose stopwatch display background/text color
142 |
143 | v0.7.1
144 | * Fix compilation bug
145 |
146 | v0.7.0
147 | * Timer central *display* re-designed
148 | * Now each time "slot" has its own display
149 | * The displays are *splittable* between them
150 | * Display *time headers*, which can be disabled from settings
151 |
152 | v0.6.0
153 | * Initial implementation of times saving on binary files
154 | * You can save a stopwatch *frame* (time and laps) to a file and resume it (open it) later
155 | * Due to the new *save toolbar* (new/open/save/save as buttons), the old *main* toolbar is moved on the window bottom by default. If you don't like it, you can always move it by right-clicking on it
156 | * Added **Kronometer** menu, separating the *save* actions (menu File) from the *stopwatch* actions
157 | * Save settings. You can disable the dialog on application exit if there are unsaved times
158 |
159 | v0.5.0
160 | * Now you can choose also the time format for lap times
161 | * Font settings for timer display font
162 | * Fixed general settings appereance, with a scrollable layout
163 |
164 | v0.4.0
165 | * Initial implementantation of Kronometer settings dialog (Settings -> Configure Kronometer)
166 | * Stopwatch time format settings: show or not show hours/minutes/seconds/tenths/hundredths/milliseconds
167 | * Now you can resize time label and lap times table without resize the application window
168 |
169 | v0.3.0
170 | * Lap recording feature
171 | * Lap times sorting
172 |
173 | v0.2.0
174 | * *Panel-like* look for time label
175 | * Time format in statusbar
176 | * Tooltip messages for labels in statusbar
177 |
178 | v0.1.2
179 | * Switched install prefix from (cmake-default) **/usr/local** to **/usr**
180 |
181 | v0.1.1
182 | * Added **.desktop** file for KMenu integration
183 |
184 | v0.1.0
185 | * First public and stable release
186 | * Initial basic features: start, pause, resume and reset the stopwatch widget
187 | * Basic KDE settings: toolbar/shortcuts configuration, statusbar visibility
188 |
--------------------------------------------------------------------------------
/LICENSES/CC0-1.0.txt:
--------------------------------------------------------------------------------
1 | Creative Commons Legal Code
2 |
3 | CC0 1.0 Universal
4 |
5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
12 | HEREUNDER.
13 |
14 | Statement of Purpose
15 |
16 | The laws of most jurisdictions throughout the world automatically confer
17 | exclusive Copyright and Related Rights (defined below) upon the creator
18 | and subsequent owner(s) (each and all, an "owner") of an original work of
19 | authorship and/or a database (each, a "Work").
20 |
21 | Certain owners wish to permanently relinquish those rights to a Work for
22 | the purpose of contributing to a commons of creative, cultural and
23 | scientific works ("Commons") that the public can reliably and without fear
24 | of later claims of infringement build upon, modify, incorporate in other
25 | works, reuse and redistribute as freely as possible in any form whatsoever
26 | and for any purposes, including without limitation commercial purposes.
27 | These owners may contribute to the Commons to promote the ideal of a free
28 | culture and the further production of creative, cultural and scientific
29 | works, or to gain reputation or greater distribution for their Work in
30 | part through the use and efforts of others.
31 |
32 | For these and/or other purposes and motivations, and without any
33 | expectation of additional consideration or compensation, the person
34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she
35 | is an owner of Copyright and Related Rights in the Work, voluntarily
36 | elects to apply CC0 to the Work and publicly distribute the Work under its
37 | terms, with knowledge of his or her Copyright and Related Rights in the
38 | Work and the meaning and intended legal effect of CC0 on those rights.
39 |
40 | 1. Copyright and Related Rights. A Work made available under CC0 may be
41 | protected by copyright and related or neighboring rights ("Copyright and
42 | Related Rights"). Copyright and Related Rights include, but are not
43 | limited to, the following:
44 |
45 | i. the right to reproduce, adapt, distribute, perform, display,
46 | communicate, and translate a Work;
47 | ii. moral rights retained by the original author(s) and/or performer(s);
48 | iii. publicity and privacy rights pertaining to a person's image or
49 | likeness depicted in a Work;
50 | iv. rights protecting against unfair competition in regards to a Work,
51 | subject to the limitations in paragraph 4(a), below;
52 | v. rights protecting the extraction, dissemination, use and reuse of data
53 | in a Work;
54 | vi. database rights (such as those arising under Directive 96/9/EC of the
55 | European Parliament and of the Council of 11 March 1996 on the legal
56 | protection of databases, and under any national implementation
57 | thereof, including any amended or successor version of such
58 | directive); and
59 | vii. other similar, equivalent or corresponding rights throughout the
60 | world based on applicable law or treaty, and any national
61 | implementations thereof.
62 |
63 | 2. Waiver. To the greatest extent permitted by, but not in contravention
64 | of, applicable law, Affirmer hereby overtly, fully, permanently,
65 | irrevocably and unconditionally waives, abandons, and surrenders all of
66 | Affirmer's Copyright and Related Rights and associated claims and causes
67 | of action, whether now known or unknown (including existing as well as
68 | future claims and causes of action), in the Work (i) in all territories
69 | worldwide, (ii) for the maximum duration provided by applicable law or
70 | treaty (including future time extensions), (iii) in any current or future
71 | medium and for any number of copies, and (iv) for any purpose whatsoever,
72 | including without limitation commercial, advertising or promotional
73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
74 | member of the public at large and to the detriment of Affirmer's heirs and
75 | successors, fully intending that such Waiver shall not be subject to
76 | revocation, rescission, cancellation, termination, or any other legal or
77 | equitable action to disrupt the quiet enjoyment of the Work by the public
78 | as contemplated by Affirmer's express Statement of Purpose.
79 |
80 | 3. Public License Fallback. Should any part of the Waiver for any reason
81 | be judged legally invalid or ineffective under applicable law, then the
82 | Waiver shall be preserved to the maximum extent permitted taking into
83 | account Affirmer's express Statement of Purpose. In addition, to the
84 | extent the Waiver is so judged Affirmer hereby grants to each affected
85 | person a royalty-free, non transferable, non sublicensable, non exclusive,
86 | irrevocable and unconditional license to exercise Affirmer's Copyright and
87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the
88 | maximum duration provided by applicable law or treaty (including future
89 | time extensions), (iii) in any current or future medium and for any number
90 | of copies, and (iv) for any purpose whatsoever, including without
91 | limitation commercial, advertising or promotional purposes (the
92 | "License"). The License shall be deemed effective as of the date CC0 was
93 | applied by Affirmer to the Work. Should any part of the License for any
94 | reason be judged legally invalid or ineffective under applicable law, such
95 | partial invalidity or ineffectiveness shall not invalidate the remainder
96 | of the License, and in such case Affirmer hereby affirms that he or she
97 | will not (i) exercise any of his or her remaining Copyright and Related
98 | Rights in the Work or (ii) assert any associated claims and causes of
99 | action with respect to the Work, in either case contrary to Affirmer's
100 | express Statement of Purpose.
101 |
102 | 4. Limitations and Disclaimers.
103 |
104 | a. No trademark or patent rights held by Affirmer are waived, abandoned,
105 | surrendered, licensed or otherwise affected by this document.
106 | b. Affirmer offers the Work as-is and makes no representations or
107 | warranties of any kind concerning the Work, express, implied,
108 | statutory or otherwise, including without limitation warranties of
109 | title, merchantability, fitness for a particular purpose, non
110 | infringement, or the absence of latent or other defects, accuracy, or
111 | the present or absence of errors, whether or not discoverable, all to
112 | the greatest extent permissible under applicable law.
113 | c. Affirmer disclaims responsibility for clearing rights of other persons
114 | that may apply to the Work or any use thereof, including without
115 | limitation any person's Copyright and Related Rights in the Work.
116 | Further, Affirmer disclaims responsibility for obtaining any necessary
117 | consents, permissions or other rights required for any use of the
118 | Work.
119 | d. Affirmer understands and acknowledges that Creative Commons is not a
120 | party to this document and has no duty or obligation with respect to
121 | this CC0 or use of the Work.
122 |
--------------------------------------------------------------------------------
/src/models/sessionmodel.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | SPDX-FileCopyrightText: 2015 Elvis Angelaccio
3 |
4 | SPDX-License-Identifier: GPL-2.0-or-later
5 | */
6 |
7 | #include "sessionmodel.h"
8 |
9 | #include
10 |
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 |
18 | SessionModel::SessionModel(QObject *parent) : QAbstractTableModel(parent)
19 | {
20 | QFile saveFile {QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + QLatin1String("/sessions.json")};
21 | if (saveFile.exists()) {
22 | if (saveFile.open(QIODevice::ReadOnly)) {
23 | auto saveData = saveFile.readAll();
24 | auto saveDoc = QJsonDocument::fromJson(saveData);
25 | read(saveDoc.object());
26 | } else {
27 | qDebug().nospace() << "cannot open " << saveFile.fileName() << ": " << saveFile.errorString();
28 | }
29 | }
30 |
31 | connect(this, &QAbstractTableModel::dataChanged, this, &SessionModel::slotWriteData);
32 | connect(this, &QAbstractTableModel::rowsInserted, this, &SessionModel::slotWriteData);
33 | connect(this, &QAbstractTableModel::rowsRemoved, this, &SessionModel::slotWriteData);
34 | }
35 |
36 | int SessionModel::columnCount(const QModelIndex& parent) const
37 | {
38 | Q_UNUSED(parent)
39 |
40 | return m_roles.count();
41 | }
42 |
43 | int SessionModel::rowCount(const QModelIndex& parent) const
44 | {
45 | Q_UNUSED(parent)
46 |
47 | return m_sessionList.size();
48 | }
49 |
50 | QVariant SessionModel::data(const QModelIndex& index, int role) const
51 | {
52 | if (!index.isValid()) {
53 | return QVariant::Invalid;
54 | }
55 |
56 | if (index.row() >= rowCount() || index.row() < 0) {
57 | return QVariant::Invalid;
58 | }
59 |
60 | if (role == Qt::DisplayRole) {
61 | return data(index, Qt::UserRole + index.column());
62 | }
63 |
64 | switch (static_cast(role)) {
65 | case Roles::SessionIdRole:
66 | return QString::number(index.row() + 1);
67 | case Roles::NameRole:
68 | return m_sessionList.at(index.row()).name();
69 | case Roles::DateRole:
70 | return m_sessionList.at(index.row()).date();
71 | case Roles::NoteRole:
72 | return m_sessionList.at(index.row()).note();
73 | case Roles::SessionRole:
74 | return QVariant::fromValue(m_sessionList.at(index.row()));
75 | }
76 |
77 | if (role == Qt::EditRole && index.column() == columnForRole(Roles::NameRole)) {
78 | // prevent the disappear of the old value when double-clicking the item
79 | return m_sessionList.at(index.row()).name();
80 | }
81 |
82 | if (role == Qt::EditRole && index.column() == columnForRole(Roles::NoteRole)) {
83 | return m_sessionList.at(index.row()).note();
84 | }
85 |
86 | return QVariant::Invalid;
87 | }
88 |
89 |
90 | QVariant SessionModel::headerData(int section, Qt::Orientation orientation, int role) const
91 | {
92 | if (role != Qt::DisplayRole || orientation != Qt::Horizontal)
93 | return QVariant::Invalid;
94 |
95 | switch (roleForColumn(section)) {
96 | case Roles::SessionIdRole:
97 | return i18nc("session number", "Session #");
98 | case Roles::NameRole:
99 | return i18n("Name");
100 | case Roles::DateRole:
101 | return i18n("Date");
102 | case Roles::NoteRole:
103 | return i18n("Note");
104 | case Roles::SessionRole:
105 | break;
106 | }
107 |
108 | return QVariant::Invalid;
109 | }
110 |
111 | bool SessionModel::setData(const QModelIndex& index, const QVariant& value, int role)
112 | {
113 | if (!index.isValid() || role != Qt::EditRole)
114 | return false;
115 |
116 | if (index.column() == columnForRole(Roles::NameRole)) {
117 | if (value.toString().isEmpty())
118 | return false;
119 |
120 | m_sessionList[index.row()].setName(value.toString());
121 | Q_EMIT dataChanged(index, index);
122 |
123 | return true;
124 | }
125 |
126 | if (index.column() == columnForRole(Roles::NoteRole)) {
127 | m_sessionList[index.row()].setNote(value.toString());
128 | Q_EMIT dataChanged(index, index);
129 |
130 | return true;
131 | }
132 |
133 | return false;
134 | }
135 |
136 | Qt::ItemFlags SessionModel::flags(const QModelIndex& index) const
137 | {
138 | if (!index.isValid())
139 | return Qt::ItemIsEnabled;
140 |
141 | if (isEditable(index))
142 | return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;
143 |
144 | return QAbstractTableModel::flags(index);
145 | }
146 |
147 | bool SessionModel::removeRows(int row, int count, const QModelIndex& parent)
148 | {
149 | if (row < 0 || row + count - 1 >= rowCount())
150 | return false;
151 |
152 | beginRemoveRows(parent, row, row + count - 1);
153 |
154 | for (int i = 0; i < count; i++) {
155 | m_sessionList.removeAt(row);
156 | }
157 |
158 | endRemoveRows();
159 |
160 | return true;
161 | }
162 |
163 | void SessionModel::append(const Session& session)
164 | {
165 | beginInsertRows(QModelIndex(), rowCount(), rowCount()); // i.e. append the new row at the table end
166 | m_sessionList.append(session);
167 | endInsertRows();
168 | }
169 |
170 | void SessionModel::update(Session& session)
171 | {
172 | int i = m_sessionList.indexOf(session);
173 |
174 | if (i == -1)
175 | return;
176 |
177 | session.setDate(QDateTime::currentDateTime());
178 | m_sessionList[i] = session;
179 |
180 | Q_EMIT dataChanged({}, {});
181 | }
182 |
183 | bool SessionModel::isEmpty() const
184 | {
185 | return m_sessionList.isEmpty();
186 | }
187 |
188 | bool SessionModel::isEditable(const QModelIndex& index) const
189 | {
190 | auto role = roleForColumn(index.column());
191 | return role == Roles::NameRole || role == Roles::NoteRole;
192 | }
193 |
194 | void SessionModel::read(const QJsonObject& json)
195 | {
196 | const auto sessions = json[QStringLiteral("sessions")].toArray();
197 | for (const auto& session : sessions) {
198 | append(Session::fromJson(session.toObject()));
199 | }
200 | }
201 |
202 | void SessionModel::slotWriteData()
203 | {
204 | QFile saveFile {QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + QLatin1String("/sessions.json")};
205 | if (!saveFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
206 | qDebug().nospace() << "cannot open " << saveFile.fileName() << ": " << saveFile.errorString();
207 | return;
208 | }
209 |
210 | auto json = QJsonObject {};
211 | json[QStringLiteral("sessions")] = jsonSessions();
212 |
213 | auto saveDoc = QJsonDocument {json};
214 | saveFile.write(saveDoc.toJson());
215 | }
216 |
217 | int SessionModel::columnForRole(SessionModel::Roles role) const
218 | {
219 | return m_roles.indexOf(role);
220 | }
221 |
222 | SessionModel::Roles SessionModel::roleForColumn(int column) const
223 | {
224 | return m_roles.at(column);
225 | }
226 |
227 | QJsonArray SessionModel::jsonSessions() const
228 | {
229 | auto array = QJsonArray {};
230 | const auto sessions = m_sessionList;
231 | for (const auto& session : sessions) {
232 | auto object = QJsonObject {};
233 | session.write(object);
234 | array.append(object);
235 | }
236 |
237 | return array;
238 | }
239 |
240 |
241 | #include "moc_sessionmodel.cpp"
242 |
--------------------------------------------------------------------------------
/doc/index.docbook:
--------------------------------------------------------------------------------
1 |
2 | Kronometer">
4 |
5 |
6 |
7 | ]>
8 |
9 |
10 |
11 |
12 | The &kronometer; Handbook
13 |
14 |
15 | ElvisAngelaccio
16 |
17 |
18 | elvis.angelaccio@kde.org
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | 2014-2016
27 | Elvis Angelaccio
28 |
29 |
30 | 2016-04-10
31 | &kronometer; 2.1
32 |
33 |
34 | &FDLNotice;
35 |
36 |
37 |
38 |
39 | &kronometer; is a stopwatch application. It can be used for basic tasks like timer start/pause/resume, as well as lap times recording.
40 |
41 |
42 | &kronometer; is able to save a complete session (timer and lap times) and to restore it later.
43 |
44 |
45 |
46 |
47 | KDE
48 | Kronometer
49 | stopwatch
50 |
51 |
52 |
53 |
54 |
55 | Introduction
56 |
57 | &kronometer; is a simple stopwatch application. It is meant to be simple and pleasant to use, thanks to a use cases driven development.
58 |
59 |
60 | &kronometer; main features are the following:
61 |
62 |
63 |
64 |
65 | &kronometer; provides a timer that can be started, paused, resumed and reset.
66 |
67 |
68 |
69 |
70 | &kronometer; allows you to record lap times and export them to a file.
71 |
72 |
73 |
74 |
75 | &kronometer; allows you to save a session and restore it later.
76 |
77 |
78 |
79 |
80 | &kronometer; allows you to copy the timer numbers from its display.
81 |
82 |
83 |
84 |
85 |
86 |
87 | Usage
88 |
89 | General Usage
90 |
91 | &kronometer; main use case is of course the interaction with the timer. You can start/pause/resume the timer by clicking on the proper actions in the toolbar or in the &kronometer; menu.
92 |
93 |
94 | Even simpler, you can use the keyboard instead of the mouse: you start the timer with the keyboard's Space and you pause the timer with Space too. You might recognize this behavior from many media player applications.
95 |
96 |
97 | By pressing the &Enter; key when the timer is running, you freeze that particular time and you create a new lap time. These times are always visible in the table on the left of the application, where you can sort them by clicking the Lap time column's header.
98 | You can also add a custom text annotation to each lap, by double-clicking the cells within the Note column.
99 |
100 |
101 | The menubar (hidden by default) provides access to all commands and configuration options.
102 | The menubar can be toggled with Show Menubar (&Ctrl;M)
103 | from the Settings menu or the menu button in the toolbar.
104 |
105 |
106 | Save and Restore Sessions
107 |
108 | When you pause a running stopwatch you create a session: a stopwatch time and zero or more lap times.
109 | You can save a session and you can restore it later.
110 |
111 |
112 |
113 | Save a Session
114 |
115 | Pause a running stopwatch, then click on the Save As button in the File menu.
116 | You can choose a name for the session that you are going to save.
117 |
118 |
119 |
120 | Restore a Session
121 |
122 | Click the Open button on the toolbar or in the File menu.
123 | Then choose an existing session to be loaded from the session's dialog.
124 |
125 |
126 |
127 | Update a Session
128 |
129 | When the session is restored, you can resume the stopwatch and you can record new lap times.
130 | If you want to save the updated session, you can simply click the Save button in the File menu.
131 |
132 |
133 |
134 | Edit a Session
135 |
136 | Click the Open button on the toolbar or in the File menu.
137 | If you select an existing session in the session's dialog, you will be able to:
138 |
139 |
140 | Rename the session, by double-clicking on its name.
141 |
142 |
143 | Delete the session, by pressing Del.
144 |
145 |
146 | Add a note to the session or edit it.
147 |
148 |
149 |
150 |
151 |
152 |
153 | Additional Features
154 |
155 | Export Lap Times
156 |
157 | When you record one or more lap times, the export features in the File menu is made available, under the entry Export laps as.
158 | Click on it and then choose a name for the exported file.
159 | You can export in the Comma Separated Values (CSV) format or in the JSON one.
160 |
161 |
162 |
163 | Clipboard Support
164 |
165 | &kronometer; is able to copy the current stopwatch time to the system clipboard.
166 | Use the &Ctrl;C key combination or the Copy entry in the Edit menu.
167 |
168 |
169 |
170 |
171 |
172 |
173 | Configuration
174 |
175 | Settings Dialog
176 |
177 | &kronometer; is customizable in many aspects.
178 | You can open the settings dialog clicking on the Configure &kronometer; entry in the Settings menu.
179 | The settings dialog is organized in the following categories.
180 |
181 |
182 | General Settings
183 |
184 | In the general settings page you can find the settings for the stopwatch and for the laps.
185 | Under the stopwatch tab you can set your preferred time format for the stopwatch display.
186 | You can choose whether to show hours, minutes or second fractions (while seconds are always shown).
187 | &kronometer; supports time granularity up to millisecond, although this requires high CPU usage due to the high refresh rate of the User Interface.
188 |
189 |
190 | Within the laps tab you can enable or disable the laps recording feature.
191 | If the laps are enabled, you can choose their time format, whether to show their notes and whether to show their absolute times, which are the stopwatch times when they were recorded.
192 |
193 |
194 |
195 | Font Settings
196 |
197 | In the font settings page you can customize the font of the stopwatch display.
198 | You can choose different font families, styles and sizes for each timer component (hours, minutes, &etc;).
199 | By default every timer component will use the same font, according the current default font in the system.
200 |
201 |
202 |
203 | Color Settings
204 |
205 | In the color settings page you can customize the default color of the stopwatch display.
206 | You can change the background color and the text color.
207 | The default colors will respect the currently selected system's theme.
208 |
209 |
210 |
211 | &kde; Built-in Settings
212 |
213 | &kronometer; makes use of the standard &kde; configuration tools.
214 | You find them in the Settings menu, under the Configure shortcuts and Configure Toolbars entries.
215 | They allow you to change the shortcuts of the &kronometer;'s actions, and to change the position of the toolbar and its content.
216 |
217 |
218 |
219 |
220 |
221 |
222 | Credits and License
223 |
224 | &kronometer;
225 |
226 |
227 | Program copyright © 2014-2016 Elvis Angelaccio
228 | elvis.angelaccio@kde.org
229 |
230 |
231 | Documentation copyright © 2014-2016 Elvis Angelaccio
232 | elvis.angelaccio@kde.org
233 |
234 |
235 | &underFDL;
236 | &underGPL;
237 |
238 |
239 | &documentation.index;
240 |
241 |
242 |
243 |
254 |
--------------------------------------------------------------------------------
/po/sv/docs/kronometer/index.docbook:
--------------------------------------------------------------------------------
1 |
2 | Kronometer">
6 |
7 |
8 |
9 | ]>
10 |
11 |
12 |
13 |
14 | Handbok &kronometer;
16 |
17 |
18 | ElvisAngelaccio elvis.angelaccio@kde.org
27 |
28 |
29 |
30 | Stefan Asserhäll stefan.asserhall@gmail.com Översättare
45 |
46 |
47 |
48 | 2014-2016
50 | Elvis Angelaccio
52 |
53 |
54 | 2016-04-10
56 | &kronometer; 2.1
58 |
59 |
60 | &FDLNotice;
61 |
62 |
63 |
64 | &kronometer; är ett tidtagarurprogram. Det kan användas för grundfunktioner som att starta, pausa och återstarta tidtagning, samt för att mäta varvtider.
66 | &kronometer; kan spara en hel session (tid och varvtider) och återställa den senare.
68 |
69 |
70 |
71 | KDE
73 | Kronometer
75 | tidtagarur
77 |
78 |
79 |
80 |
81 |
82 | Inledning
84 | &kronometer; är ett enkelt tidtagarur. Det är avsett att vara enkelt och bekvämt att använda, tack vara en utveckling baserad på användarfall.
86 | Huvudfunktionerna i &kronometer; är följande:
88 |
89 |
90 | &kronometer; tillhandahåller ett tidtagarur som kan startas, pausas, återstartas och nollställas.
92 |
93 |
94 | &kronometer; låter dig mäta varvtider och exportera dem till en fil.
96 |
97 |
98 | &kronometer; låter dig spara en session och återställa den senare.
100 |
101 |
102 | &kronometer; låter dig kopiera tiderna från dess urtavla.
104 |
105 |
106 |
107 |
108 |
109 | Användning
111 |
112 | Allmän användning
114 | Huvudanvändningen av &kronometer; är förstås interaktion med tidtagningen. Man kan starta, pausa, återstarta tidtagning genom att klicka på lämpliga alternativ i verktygsraden eller i &kronometer;s meny.
116 | Det är ännu enklare att använda tangentbordet istället för musen: Man startar tidtagning med Mellanslag på tangentbordet och pausar också med Mellanslag. Beteendet kanske känns igen från många mediaspelare.
122 | Genom att trycka på returtangenten när tidtagningen pågår, kan man frysa den specifika tiden och skapa en ny varvtid. Tiderna är alltid synliga i tabellen till vänster i programmet, där de kan sorteras genom att klicka på kolumnrubriken Varvtid. Det går också att lägga till en egen textanmärkning för varje varv genom att dubbelklicka på cellerna i kolumnen Anmärkning.
130 | Menyraden (normalt dold), ger tillgång till alla kommandon och inställningsalternativ. Menyraden kan visas eller döljas med Visa menyrad (&Ctrl;M) i menyn Inställningar eller menyknappen i verktygsraden.
140 |
141 | Spara och återställa sessioner
143 | När ett tidtagarur som mäter pausas, skapas en session: en tid mätt med tidtagaruret och noll eller flera varvtider. En session kan sparas och kan senare återställas.
145 |
146 |
147 | Spara en session
149 | Pausa ett tidtagarur som mäter, klicka därefter på knappen Spara som i menyn Arkiv. Därefter kan du välja ett namn på sessionen som ska lagras.
155 |
156 |
157 | Återställa en session
159 | Klicka på knappen Öppna på verktygsraden eller i menyn Arkiv. Välj därefter en befintlig session som ska läsas in i sessionens dialogruta.
165 |
166 |
167 | Uppdatera en session
169 | När sessionen har återställts, kan man återstarta tidtagaruret och mäta nya varvtider. Om man vill spara den uppdaterade sessionen kan man helt enkelt klicka på knappen Spara i menyn Arkiv.
175 |
176 |
177 | Redigera en session
179 | Klicka på knappen Öppna på verktygsraden eller i menyn Arkiv. Om du väljer en befintlig session i sessionens dialogruta kan du:
185 |
186 | Byta namn på sessionen genom att dubbelklicka på dess namn.
188 |
189 |
190 | Ta bort sessionen genom att trycka på Delete.
194 |
195 |
196 | Lägga till en anmärkning i sessionen eller redigera den.
198 |
199 |
200 |
201 |
202 |
203 |
204 | Ytterligare funktioner
206 |
207 | Exportera varvtider
209 | När en eller flera varvtider mäts, blir exportfunktionen i menyn Arkiv tillgänglig, med alternativet Exportera varv som. Klicka på det och väl ett namn på den exporterade filen. Du kan exportera med formaten CSV (värden åtskilda med kommatecken) eller JSON.
215 |
216 |
217 | Stöd för klippbordet
219 | &kronometer; kan kopiera den aktuella tiden i tidtagaruret till systemets klippbord. Använd tangentkombinationen &Ctrl;C eller alternativet Kopiera i menyn Redigera.
229 |
230 |
231 |
232 |
233 |
234 | Inställning
236 |
237 | Inställningsdialogruta
239 | &kronometer; kan anpassas på många sätt. Det går att visa inställningsdialogrutan genom att klicka på Anpassa &kronometer; i menyn Inställningar. Inställningsdialogrutan är organiserad i följande kategorier:
245 |
246 | Allmänna inställningar
248 | På den allmänna inställningssidan finns tidtagarurets inställningar och för varvtiderna. Under tidtagarursfliken kan önskat tidsformat för tidtagarurets urtavla ställas in. Man kan välja att visa timmar, minuter eller delar av sekunder (medan sekunder alltid visas). &kronometer; stöder tidsupplösning ner till millisekunder, även om det kräver hög processoranvändning på grund av den höga uppdateringsfrekvensen av användargränssnittet.
250 | Under varvtidsfliken kan du aktivera eller inaktivera lagringsfunktionen för varvtider. Om varvtider är aktiverade kan deras tidsformat väljas, om deras anmärkningar ska visas, och om deras absoluta tider ska visas, vilka är tidtagarurets tider när de lagrades.
252 |
253 |
254 | Teckensnittsinställningar
256 | På inställningssidan för teckensnitt kan man anpassa teckensnittet för tidtagarurets urtavla. Det går att välja olika teckenfamiljer, stilar och storlekar för varje tidskomponent (timmar, minuter, etc.). Normalt använder alla tidskomponenter samma teckensnitt enligt systemets nuvarande standardteckensnitt.
258 |
259 |
260 | Färginställningar
262 | På färginställningssidan kan man ställa in den normala färgen på tidtagarurets urtavla. Det går att ändra bakgrundsfärg och textfärg. Standardfärgerna följer temat som för närvarande är valt i systemet.
264 |
265 |
266 | &kde;:s inbyggda inställningar
268 | &kronometer; använder &kde;:s vanliga inställningsverktyg. De finns i menyn Inställningar under alternativen Anpassa genvägar och Anpassa verktygsrader. De gör det möjligt att ändra genvägarna för &kronometer;s funktioner, och ändra verktygsradens plats och dess innehåll.
276 |
277 |
278 |
279 |
280 |
281 | Tack till och licens
283 | &kronometer;
285 | Program copyright © 2014-2016 Elvis Angelaccio elvis.angelaccio@kde.org
289 | Dokumentation copyright © 2014-2016 Elvis Angelaccio elvis.angelaccio@kde.org
293 | Översättning Stefan Asserhäll stefan.asserhall@gmail.com &underFDL; &underGPL;
298 |
299 | &documentation.index;
300 |
301 |
302 |
303 |
314 |
--------------------------------------------------------------------------------
/po/nl/docs/kronometer/index.docbook:
--------------------------------------------------------------------------------
1 |
2 | Kronometer">
6 |
7 |
8 |
9 | ]>
10 |
11 |
12 |
13 |
14 | Het handboek van &kronometer;
16 |
17 |
18 | ElvisAngelaccio elvis.angelaccio@kde.org
27 |
28 |
29 |
30 | &Freek.de.Kruijf;&Ronald.Stroethoff;
31 |
32 |
33 |
34 | 2014-2016
36 | Elvis Angelaccio
38 |
39 |
40 | 2016-04-10
42 | &kronometer; 2.1
44 |
45 |
46 | &FDLNotice;
47 |
48 |
49 |
50 | &kronometer; is een stopwatch-toepassing. Het kan gebruikt worden voor basistaken zoals starten/pauzeren/doorgaan van een stopwatch, evenals opnemen van rondetijden.
52 | &kronometer; kan een volledige sessie opslaan (stopwatch en rondetijden) en deze later herstellen.
54 |
55 |
56 |
57 | KDE
59 | Kronometer
61 | stopwatch
63 |
64 |
65 |
66 |
67 |
68 | Inleiding
70 | &kronometer; is een toepassing met een eenvoudige stopwatch. Het is bedoeld om eenvoudig te zijn en prettig in gebruik, dankzij op gebruik gerichte ontwikkeling.
72 | De hoofdfunctie van &kronometer; zijn als volgt:
74 |
75 |
76 | &kronometer; biedt een stopwatch die gestart, gepauzeerd, doorgestart en gereset kan worden.
78 |
79 |
80 | &kronometer; kan rondetijden opnemen en ze exporteren naar een bestand.
82 |
83 |
84 | &kronometer; kan een sessie opslaan en deze later herstellen.
86 |
87 |
88 | &kronometer; kan de stopwatchgetallen vanaf zijn scherm kopiëren.
90 |
91 |
92 |
93 |
94 |
95 | Gebruik
97 |
98 | Algemeen gebruik
100 | De hoofdfunctie van &kronometer; is natuurlijk de interactie met de stopwatch. U kunt de stopwatch starten/pauzeren/laten doorgaan door te klikken op de juiste acties in de werkbalk of in het menu van &kronometer;.
102 | Nog makkelijker, u kunt in plaats van de muis het toetsenbord gebruiken: u start de stopwatch met de toets Space en u zet de stopwatch op pauze ook met Space. U herkent dit wellicht van vele media spelers.
108 | Door op de toets &Enter; te drukken, wanneer de timer loopt, kunt u die specifieke tijd bevriezen en u kunt een nieuwe rondetijd maken. Deze tijden zijn altijd zichtbaar in de tabel aan de linkerkant van de toepassing, waar u ze kunt sorteren door te klikken op de kolomkop van Rondetijden. U kunt ook een eigen tekstannotatie aan elke ronde toevoegen door dubbel te klikken in de cellen in de kolom Notitie.
116 | De menubalk (standaard verborgen) biedt toegang tot alle commando en configuratie opties. De menubalk kan omgeschakeld worden met Menubalk tonen (&Ctrl;M) uit het menu Instellingen of de menuknop in de werkbalk.
126 |
127 | Opslaan en herstellen van sessies
129 | Als u een lopende stopwatch pauzeert dan creëert u een sessie: een stopwatchtijd en een of meer rondetijden. U kunt een sessie opslaan en u kunt deze later weer herstellen.
131 |
132 |
133 | Sessie opslaan
135 | Pauzeer een lopende stopwatch, klik vervolgens op de knop Opslaan als of in het menu Bestand. U kunt een naam voor de sessie die u wilt opslaan kiezen.
141 |
142 |
143 | Sessie herstellen
145 | Klik op de knop Openen op de werkbalk of in het menu Bestand. Kies vervolgens een bestaand sessie-bestand dat u wilt laden in de sessie-dialoog.
151 |
152 |
153 | Sessie bijwerken
155 | Als de sessie is hersteld, dan kunt u de stopwatch zijn taak laten hervatten en weer rondetijden laten registreren. Als u de bijgewerkte sessie weer wilt opslaan, dan kunt u weer op de knop Opslaan of in het menu Bestand klikken.
161 |
162 |
163 | Sessie bewerken
165 | Klik op de knop Openen op de werkbalk of in het menu Bestand. Als u een bestaande sessie in de sessie-dialoog selecteert, zult in staat zijn:
171 |
172 | De sessie te hernoemen door dubbel te klikken op zijn naam.
174 |
175 |
176 | De sessie verwijderen door op Del te drukken.
180 |
181 |
182 | Een notitie aan de sessie toevoegen of deze bewerken.
184 |
185 |
186 |
187 |
188 |
189 |
190 | Verdere mogelijkheden
192 |
193 | Rondetijden te exporteren
195 | Nadat u een of meerdere rondetijden heeft opgenomen, komt in het menuitem Ronden exporteren als van het menu Bestand de mogelijkheid tot exporteren beschikbaar. Klik erop en kies een naam voor het te exporteren bestand. U kunt exporteren naar het formaat Comma Separated Values (CSV) of naar het JSON-bestand.
201 |
202 |
203 | Ondersteuning van het klembord
205 | &kronometer; is in staat om de huidige stopwatchtijd naar klembord van het systeem te kopiëren. Gebruik de toetscombinatie &Ctrl;C of het item Kopiërenuit het menu Bewerken.
215 |
216 |
217 |
218 |
219 |
220 | Configuratie
222 |
223 | Instellingendialoog
225 | U kunt vele aspecten van &kronometer; aanpassen. U kunt de instellingendialoog openen door op het item &kronometer; instellen te klikken in het menu Instellingen. De instellingendialoog heeft de volgende categorieën.
231 |
232 | Algemene instellingen
234 | In de algemene instellingenpagina kunt u de instellingen vinden voor de stopwatch en de rondetijden. Onder het tabblad stopwatch kunt u uw voorkeur voor het tijdsindeling op de display van de stopwatch instellen. U kunt kiezen of u fracties van uren, minuten of seconden laat tonen (terwijl seconden altijd getoond worden). &kronometer; ondersteunt tijden tot op de milliseconde, hoewel dat een hoog CPU-gebruik eist vanwege de hoge snelheid voor verversing van het gebruikersinterface.
236 | In het tabblad rondentijden kunt u het opnemen van rondetijden aan of uitschakelen. Als deze zijn ingeschakeld kunt u hun tijdindeling kiezen, om hun notities te tonen en hun absolute tijden, die de tijden van de stopwatch zijn op het moment dat ze zijn opgenomen.
238 |
239 |
240 | Lettertype-instellingen
242 | In pagina voor instellingen voor lettertypen kunt de keuze voor het lettertype van het stopwatchbeeldscherm aanpassen. U kunt verschillende families lettertypen, stijlen en formaten voor elke tijdseenheid (uren, minuten, &etc;) kiezen. Standaard zal elke component van de timer hetzelfde lettertype gebruiken, overeenkomstig het huidige standaard lettertype van het systeem.
244 |
245 |
246 | Kleurinstellingen
248 | In de pagina voor de kleurinstellingen kunt u de standaard kleur van het beeldscherm van de stopwatch aanpassen. U kunt de achtergrondkleur en de tekstkleur wijzigen. De standaard kleuren volgen het huidige geselecteerde thema van het systeem.
250 |
251 |
252 | &kde; ingebouwde instellingen
254 | &kronometer; maakt gebruik van de standaard &kde;-hulpmiddelen voor instellingen. U kunt ze vinden in het menu Instellingen, onder de items Sneltoetsen instellen en Werkbalken instellen. U kunt hier de sneltoetsen voor de acties in &kronometer;, de locatie van de werkbalk en zijn inhoud wijzigen.
262 |
263 |
264 |
265 |
266 |
267 | Dankbetuigingen en licentie
269 | &kronometer;
271 | Programma copyright © 2014-2016 Elvis Angelaccio elvis.angelaccio@kde.org
275 | Documentatie copyright © 2014-2016 Elvis Angelaccio elvis.angelaccio@kde.org
279 | &meld.fouten;&vertaling.freek;&vertaling.ronald;&nagelezen.freek; &underFDL; &underGPL;
280 |
281 | &documentation.index;
282 |
283 |
284 |
285 |
296 |
--------------------------------------------------------------------------------