Compare commits

...

58 Commits

Author SHA1 Message Date
LoudSnorer
d16e40388d Changed pholy to CrimsonNape 2024-10-04 17:44:06 -04:00
LoudSnorer
ffa9f9d8c4 PRS1 Handle Empty sdcards property file if backup file 2024-10-01 21:02:27 -04:00
LoudSnorer
30c9f95537 default value for notify message box 2024-09-20 10:14:17 -04:00
LoudSnorer
af82004f56 FIX Unkownen Issue for AC11 vAuto and ASV 2024-09-19 20:08:43 -04:00
LoudSnorer
a9ad89cd19 Profile: Height Metric - English converison 2024-08-27 20:48:40 -04:00
LoudSnorer
91fd2b30fa mkOSDistDeb-NN.sh per Crimson Nape request 2024-08-26 18:04:22 -04:00
Crimson Nape
eac74fd2ac Revert "Revert "Update mkOSDistDeb-NN.sh for libqt5core versions""
This reverts commit 4e6721e6af
2024-08-26 04:35:04 +00:00
LoudSnorer
74c2df6c69 Decrease timeout for notify message box 2024-08-24 21:53:12 -04:00
Crimson Nape
4e6721e6af Revert "Update mkOSDistDeb-NN.sh for libqt5core versions"
This reverts commit b0274154b5
2024-08-25 00:47:10 +00:00
Crimson Nape
b0274154b5 Update mkOSDistDeb-NN.sh for libqt5core versions 2024-08-24 13:47:54 +00:00
LoudSnorer
67b0854b1c Fix Import Journal - issue 108 2024-08-23 19:58:36 -04:00
LoudSnorer
d9a75e3930 FIX: compile error on ubuntu 18.04 2024-08-18 19:50:33 -04:00
LoudSnorer
9b041cf22d Support for 'Wellue O2Ring S' code author:P. Fisher 2024-08-18 11:32:22 -04:00
LoudSnorer
d6b7c05ed2 Part2: restore last used CSV export data folder 2024-08-07 20:40:01 -04:00
LoudSnorer
4043761486 New: restore last used CSV export data folder 2024-08-07 19:44:34 -04:00
LoudSnorer
2ad41e3c7b Updated Language Files 2024-08-05 13:12:10 -04:00
LoudSnorer
a1ae9f9200 Fix English Grammer - Oximeter Wizard Menu 2024-07-29 06:41:49 -04:00
LoudSnorer
2859eab67c NEW: restore last used oximeter folder 2024-07-27 18:40:15 -04:00
LoudSnorer
56f815d44a FIX Compilation Issues with uBuntu24.04 and Clang compiler 2024-07-27 12:06:02 -04:00
LoudSnorer
fa725e3d14 fix: Keyboard navigation doesn't work with bookmarks: OSCAR issue #103 problem/code by hansendc 2024-07-11 14:46:57 -04:00
LoudSnorer
f2fd17f68f Fix Crash during change of high resolution checkbox 2024-07-10 13:00:21 -04:00
LoudSnorer
c4c0bf5596 Fix: ClockDrift issues (from grnbrg) resolves oscar issue #101 2024-07-10 09:33:21 -04:00
LoudSnorer
453e16cfc6 Linux Compile error. worked on Linux VM & windows 2024-07-10 08:05:29 -04:00
LoudSnorer
652635f192 new: replace notify mssages with a messageBox that expires.
notify messages are now appear on linux systems.
     ability to stop timer and quickly dismiss the messaheBox.
     ability to revert to previous notification in preferences
2024-07-09 21:00:27 -04:00
LoudSnorer
0334dd792b Warning message when no cpap data and validate oximeter data 2024-07-09 20:11:24 -04:00
LoudSnorer
89eec381c8 New - added option to disable daily Graph titles
requested for high resolution displays
2024-07-09 14:52:25 -04:00
LoudSnorer
4c1c17287d Fix Crash due loader not found 2024-07-06 12:01:53 -04:00
LoudSnorer
6acbe28566 update test_macros.h 2024-07-02 11:25:42 -04:00
LoudSnorer
90e98ccfda fix statistics display of months not used 2024-07-02 11:18:34 -04:00
LoudSnorer
4931e60bd5 Fix Crash: Display error message instead of crashing 2024-06-19 21:25:10 -04:00
sgearhart
7267dafa46 Merge remote-tracking branch 'origin' 2024-04-14 07:40:39 -04:00
Steve Gearhart
31a436c672 Version 1.5.3 Update 2024-04-14 11:38:56 +00:00
sgearhart
afd12b3e19 Version 1.5.3 Update 2024-04-14 07:36:39 -04:00
Steve Gearhart
49e11c3b5c Merge branch 'docedit' into 'master'
Docedit

See merge request sgearhart/OSCAR-code!1
2024-04-11 15:57:40 +00:00
sgearhart
0ebe80c6e5 Added changes for 1.5.3 2024-04-11 10:20:48 -04:00
sgearhart
4a8fd9a521 Member updates 2024-04-11 10:07:03 -04:00
LoudSnorer
e828e7dc6d FIX main.cpp 'make exist option --profile work properly' 2024-03-31 20:28:18 -04:00
Steve Gearhart
50ee0d8ccc Update mkOSDistDeb-NN.sh - replace tilde with dash in test versions build name. 2024-03-28 11:03:02 +00:00
Steve Gearhart
ad526e846c Update mkOSDistDeb.xx -replace tilde with dash in build name. 2024-03-28 10:57:38 +00:00
LoudSnorer
2cac1da0a3 FIX OSCAR Login: User can not access data after upgrade to 1.5.2 2024-03-25 20:04:37 -04:00
LoudSnorer
c53c22bc90 Add Daily Search Item; searh for any Journal item. notes,bookmarks,weight,feelings 2024-03-25 19:48:54 -04:00
LoudSnorer
37097ee3ce [Fix Daily Search] add search at first imstall 2024-03-25 19:30:50 -04:00
LoudSnorer
d18826266b [New Feature] Add Import(restore) Journal 2024-03-25 15:48:41 -04:00
LoudSnorer
62e87fe0bd [Refactor Journal Interface] in daily.cpp for Import Journal Feature 2024-03-25 15:36:42 -04:00
LoudSnorer
f2686b7487 New Feature: Confgurable Daily Left Side Bar 2024-03-20 12:59:40 -04:00
LoudSnorer
a2f12cba3a Fix Statstics:Data Range was 8 months in future 2024-03-20 12:56:36 -04:00
Steve Gearhart
57cea6bcd5 Update common.cpp - replaced nonexistent filename for directory validation. 2024-03-16 15:49:51 +00:00
Steve Gearhart
2e98100ba7 Merge branch OSCAR-code:master into master 2024-03-15 18:59:25 +00:00
Steve Gearhart
a33c4f546c Update release_notes.html 2024-03-15 18:10:04 +00:00
Steve Gearhart
2c22546d93 Update VERSION 2024-03-15 17:34:45 +00:00
Steve Gearhart
b7b9607933 Update release_notes.html 2024-03-15 14:34:09 +00:00
LoudSnorer
9d78bab20c Fix High Resolution Control File Location. Now in Oscar Data Folder, was outside. 2024-03-07 16:52:24 -05:00
Steve Gearhart
98403d4dc3 Update resmed_loader.cpp - added AS11 #39520 2024-03-06 17:16:57 +00:00
Steve Gearhart
78b5303dbc Update resmed_loader.cpp- Renamed BiPAP to BiLevel 2024-03-05 18:48:13 +00:00
LoudSnorer
fa9de24c38 Fix Branch: Removed new feature added in beta. Restored daily.h/cpp to same as f4c612774 (beta 2) 2024-02-27 19:12:08 -05:00
LoudSnorer
4d1f0ef44d Fix Statistics: Add configuration of alternating colored lines background 2024-02-26 20:59:18 -05:00
LoudSnorer
dcbbf3c052 New Feature: Confgurable Daily Left Side Bar 2024-02-25 13:42:18 -05:00
LoudSnorer
082a29495a Arie's request to delete translation files 2024-02-25 05:40:25 -05:00
106 changed files with 39230 additions and 56153 deletions

View File

@ -17,7 +17,7 @@ After installing the required packages:
$ mkdir OSCAR
$ cd OSCAR
$ git clone https://gitlab.com/pholy/OSCAR-code.git
$ git clone https://gitlab.com/CrimsonNape/OSCAR-code.git
$ mkdir build
$ cd build
$ qmake ../OSCAR-code/OSCAR_QT.pro.

View File

@ -93,7 +93,7 @@ if [[ ${VERSION} == *-* ]]; then
if [[ ${PRERELEASE} == *rc* ]]; then
RC=1
fi
VERSION="${VERSION}~${PRERELEASE}"
VERSION="${VERSION}-${PRERELEASE}"
fi
GIT_REVISION=`awk '/#define GIT_REVISION / { gsub(/"/, "", $3); print $3 }' ${SRC}/git_info.h`
echo Version: ${VERSION}
@ -142,14 +142,15 @@ if [ -f "./$deb_file" ]; then
exit
fi
# retrieve packages version for the dependencies
## retrieve packages version for the dependencies
getPkg libqt5core
qtver=$PKGVERS
corePkg=$PKGNAME
getPkg libdouble
dblPkg=$PKGNAME
echo "QT version " $qtver
echo "QT name version " $corePkg $qtver
echo "DblConv package " $dblPkg
# clean folders need to create the package
@ -241,7 +242,7 @@ fpm --input-type dir --output-type deb \
--depends $dblPkg \
--depends libpcre16-3 \
--depends qttranslations5-l10n \
--depends "libqt5core5a >= 5.9" \
--depends "${corePkg} >= ${qtver}" \
--depends libqt5serialport5 \
--depends libqt5xml5 \
--depends libqt5network5 \

View File

@ -47,7 +47,7 @@ if [[ ${VERSION} == *-* ]]; then
if [[ ${PRERELEASE} == *rc* ]]; then
RC=1
fi
VERSION="${VERSION}~${PRERELEASE}"
VERSION="${VERSION}-${PRERELEASE}"
fi
GIT_REVISION=`awk '/#define GIT_REVISION / { gsub(/"/, "", $3); print $3 }' ${SRC}/git_info.h`
echo Version: ${VERSION}

View File

@ -52,7 +52,7 @@ NOTE: Official builds are currently made with [macOS 10.14 Mojave] and Command-L
1. Build OSCAR:
git clone https://gitlab.com/pholy/OSCAR-code.git
git clone https://gitlab.com/CrimsonNape/OSCAR-code.git
cd OSCAR-code
mkdir build
cd build

View File

@ -181,7 +181,7 @@ This also allows building using windows shortcuts.
## Start Developing Oscar in Qt Creator
In browser, log into your account at gitlab.com. Select the Oscar project at https://gitlab.com/pholy/OSCAR-code. Clone a copy of the repository to a location on your computer.
In browser, log into your account at gitlab.com. Select the Oscar project at https://gitlab.com/CrimsonNape/OSCAR-code. Clone a copy of the repository to a location on your computer.
Start QT. There are two QT Oscar project files: OSCAR_QT.pro in the Oscar-code directory, and Oscar.pro in the Oscar-code\\oscar directory. You may use *either* project file. Both will create a running version of Oscar. I find building with Oscar.pro in the Oscar-code\\oscar directory to be very slightly faster, but the difference is negligible.

View File

@ -22,7 +22,7 @@ Setting aside the religious wars that can arise over any development methodology
### How Do I Develop in a Branch?
0. Create your own fork of the repo and configure it to stay up-to-date with the upstream repo.
* Go to https://gitlab.com/pholy/OSCAR-code and click on **Fork** in the top right of the project page.
* Go to https://gitlab.com/CrimsonNape/OSCAR-code and click on **Fork** in the top right of the project page.
* In your fork's sidebar, go to **Settings > Repository** then click on **Expand** for "Mirroring repositories".
* Enter "https://gitlab.com/pholy/OSCAR-code.git" for the repository **URL**, make sure the mirror is set to **Pull** and then click **Mirror repository**.

View File

@ -16,31 +16,31 @@
<b>OSCAR</b> is a derivative of the SleepyHead program written by Mark Watkins, during the years 2011 to 2018. The current project is the combined effort of people from CPAPtalk.com, ApneaBoard.com, and other volunteers, starting in 2019.</p>
<p>
<b>OpenSource Libraries</b>
<br>OSCAR uses the OpenSource version of the Qt cross-platform toolkit available from
<a href="http://qt.io" >https://qt.io</a> which itself draws from many smaller open source libraries. You can read the individual licensing for many of these components that are used under the hood of OSCAR at
<br>OSCAR uses the OpenSource version of the Qt cross-platform toolkit available from
<a href="http://qt.io" >https://qt.io</a> which itself draws from many smaller open source libraries. You can read the individual licensing for many of these components that are used under the hood of OSCAR at
<a href="https://doc.qt.io/qt-5/licenses-used-in-qt.html" >https://doc.qt.io/qt-5/licenses-used-in-qt.html</a></p>
<p>
<b>Data formats</b>
<br>The CPAP device data formats are mostly undocumented. Getting them working in OSCAR involved a lot of investigation, together with a lot of SD card data samples, many patient users willing to put up with crashes and data issues, and plenty of help from fellow developers out there who shared in the workload of decoding data formats.Thanks to all of you who have helped in the fight to protect our right to keep our own data open and accessible!</p>
<h2>The OSCAR team currently consists of the following persons (with their ApneaBoard names):</h2>
<p>
<i>Fred Bonjour</i> (Gideon) : Project Manager &amp; Lead Tester,
<i>Phil Olynyk</i> (pholynyk) : Lead Developer,
<i>Fred Bonjour</i> (Gideon) : Project Manager &amp; Lead Tester,
<i>Phil Olynyk</i> (pholynyk) : Lead Developer,
<i>Arie Klerk</i> (A KLERK): Translations Team Coordinator</p>
<p>
<b>Developers</b>
<br>
Phil Olynyk (pholynyk) (<i>Lead Developer</i>), GuyScharf, sawinglogz, Ray Elliott (LoudSnorer), untoutseul05</p>
Phil Olynyk (pholynyk) (<i>Lead Developer</i>), GuyScharf, sawinglogz, Ray Elliott (LoudSnorer), sgearhart (Crimson Nape), untoutseul05</p>
<p>
<b>Reporters</b>
<br>Crimson Nape, palerider</p>
<br>palerider, TechieHusband</p>
<p>
<b>Testers</b>
<br>
Fred Bonjour (Gideon) (<i>Lead Tester</i>), GuyScharf, Jeff8356, bollar, c137jayde, cberistain, coldfeet7, geraldbergeron, Homerec130, johnnyb00, jr3586, minderbinder, ScottZZZ, Shnorky, SleepyHenry, stbrown3rd, unidee</p>
Fred Bonjour (Gideon) (<i>Lead Tester</i>), ARBatteiger, ArcherNeedsSleep, bollar, c137jayde, cberistain, coldfeet7, dohm, Expat31, fishfinderG, Frankiboy, geraldbergeron, Gooffy44, Gralli, GuyScharf, Homerec130, JJJ, johnnyb00, jr3586, minderbinder, motorsrunnin, NicoFR, pilothaz, ronfario, Ruud J, ScottZZZ, Shnorky, silverdr, Sleepy Quixote, SleepyHenry, SleepyJoseph, stbrown3rd, Tdragone, TechieHippie, TechieHusband, tedpearson, unidee, untoutseul05</p>
<p>
<b>Advisors</b>
<br>SkepticDoc, Sleeprider, srlevine1, harre, rhashimoto </p>
<br>Sleeprider, srlevine1, harre, rhashimoto </p>
<p>
<b>Translators</b>
<br>
@ -50,7 +50,7 @@
<b>OSCAR is always looking for help: programmers, testers, or translators. If you are interested, please PM &#39;Gideon&#39; on the Apnea Board Forum.</b>
</p>
<hr style="width: 100%; height: 2px;" >
<p>A special mention to the ApneaBoard for providing a development forum for OSCAR and for providing the primary download site for OSCAR at
<p>A special mention to the ApneaBoard for providing a development forum for OSCAR and for providing the primary download site for OSCAR at
<a href="https://sleepfiles.com/OSCAR" >https://sleepfiles.com/OSCAR</a>.</p>
<p>Also acknowledging ApneaBoard for their support of software for CPAP users for many years.</p>

View File

@ -10,10 +10,28 @@
<p>
<b>This page in other languages:</b>
<br><a href=http://www.apneaboard.com/wiki/index.php/OSCAR_Release_Notes>http://www.apneaboard.com/wiki/index.php/OSCAR_Release_Notes</a></p>
<p>
<p>
<b>Changes and fixes in OSCAR v1.5.3</b>
<br>Portions of OSCAR are &copy; 2019-2024 by
<i>The OSCAR Team</i></p>
<ul>
<li>[fix] No name in user profile - user unable to access data.</li>
<li>[fix] Daily Search: Add search at first imstall.</li>
<li>[fix] Statstics: Prevent Data Range from listing future dates.</li>
<li>[fix] Correct validation for Lanuage and Help files.</li>
<li>[added] Daily Search Item: Searh for any Journal item (notes,bookmarks,weight,feelings).</li>
<li>[added] Import(restore) Journal.</li>
<li>[added] Confgurable Daily Left Side Bar.</li>
<li>[update] Credits.html - Member updates. </li>
</ul>
<b>Changes and fixes in OSCAR v1.5.2</b>
<br>Portions of OSCAR are &copy; 2019-2024 by
<i>The OSCAR Team</i></p>
<ul>
<li>[fix] VHigh Resolution Control File Location. Now in Oscar Data Folder.</li>
<li>[fix] Statistics: Add configuration of alternating colored lines background.</li>
<li>[fix] Viatom/Wellue file extension (.dat) was preventing the name from changing the start time</li>
<li>[fix] Time display issues encountered when summer time is changed to winter time.</li>
<li>[fix] Statistics display mode is now restored when Oscar starts.</li>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="af_ZA" sourcelanguage="en">
<context>
<name>QShortcut</name>
<message>
<source>No</source>
<translation>Nee</translation>
</message>
<message>
<source>Yes</source>
<translation>Ja</translation>
</message>
</context>
<context>
<name>QPlatformTheme</name>
<message>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
<source>&amp;No</source>
<translation>&amp;Nee</translation>
</message>
<message>
<source>&amp;Yes</source>
<translation>&amp;Ja</translation>
</message>
<message>
<source>Help</source>
<translation>Hulp</translation>
</message>
<message>
<source>Open</source>
<translation>Oopmaak</translation>
</message>
<message>
<source>Save</source>
<translation>Stoor</translation>
</message>
<message>
<source>Abort</source>
<translation>Afbreek</translation>
</message>
<message>
<source>Apply</source>
<translation>Toepas</translation>
</message>
<message>
<source>Close</source>
<translation>Sluit</translation>
</message>
<message>
<source>Reset</source>
<translation>Herstel</translation>
</message>
<message>
<source>Retry</source>
<translation>Weer</translation>
</message>
<message>
<source>Restore Defaults</source>
<translation>Herstel verstek</translation>
</message>
<message>
<source>Cancel</source>
<translation>Kanselleer</translation>
</message>
<message>
<source>Ignore</source>
<translation>Ignoreer</translation>
</message>
<message>
<source>N&amp;o to All</source>
<translation>N&amp;ee vir almal</translation>
</message>
<message>
<source>Save All</source>
<translation>Spaar alles</translation>
</message>
<message>
<source>Discard</source>
<translation>Weggooi</translation>
</message>
<message>
<source>Yes to &amp;All</source>
<translation>Ja vir &amp;alles</translation>
</message>
</context>
</TS>

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="ar">
<context>
<name>QShortcut</name>
<message>
<source>No</source>
<translation>لا</translation>
</message>
<message>
<source>Yes</source>
<translation>نعم</translation>
</message>
</context>
<context>
<name>QPlatformTheme</name>
<message>
<source>OK</source>
<translation>حسنًا</translation>
</message>
<message>
<source>&amp;No</source>
<translation>&amp;لا</translation>
</message>
<message>
<source>&amp;Yes</source>
<translation>&amp;نعم</translation>
</message>
<message>
<source>Help</source>
<translation>مساعدة</translation>
</message>
<message>
<source>Open</source>
<translation>افتح</translation>
</message>
<message>
<source>Save</source>
<translation>احفظ</translation>
</message>
<message>
<source>Abort</source>
<translation>أجهض</translation>
</message>
<message>
<source>Apply</source>
<translation>طبّق</translation>
</message>
<message>
<source>Close</source>
<translation>أغلق</translation>
</message>
<message>
<source>Reset</source>
<translation>صفّر</translation>
</message>
<message>
<source>Retry</source>
<translation>حاول مجدّدًا</translation>
</message>
<message>
<source>Restore Defaults</source>
<translation>استعد الافتراضيّات</translation>
</message>
<message>
<source>Cancel</source>
<translation>ألغِ</translation>
</message>
<message>
<source>Ignore</source>
<translation>تجاهل</translation>
</message>
<message>
<source>N&amp;o to All</source>
<translation>لا لل&amp;كلّ</translation>
</message>
<message>
<source>Save All</source>
<translation>احفظ الكلّ</translation>
</message>
<message>
<source>Discard</source>
<translation>ارفض</translation>
</message>
<message>
<source>Yes to &amp;All</source>
<translation>ن&amp;عم للكلّ</translation>
</message>
</context>
</TS>

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="bg">
<context>
<name>QShortcut</name>
<message>
<source>No</source>
<translation>Не</translation>
</message>
<message>
<source>Yes</source>
<translation>Да</translation>
</message>
</context>
<context>
<name>QPlatformTheme</name>
<message>
<source>OK</source>
<translation>Добре</translation>
</message>
<message>
<source>&amp;No</source>
<translation>&amp;Не</translation>
</message>
<message>
<source>&amp;Yes</source>
<translation>&amp;Да</translation>
</message>
<message>
<source>Help</source>
<translation>Помощ</translation>
</message>
<message>
<source>Open</source>
<translation>Отваряне</translation>
</message>
<message>
<source>Save</source>
<translation>Запазване</translation>
</message>
<message>
<source>Abort</source>
<translation>Прекъсване</translation>
</message>
<message>
<source>Apply</source>
<translation>Прилагане</translation>
</message>
<message>
<source>Close</source>
<translation>Затваряне</translation>
</message>
<message>
<source>Reset</source>
<translation>Нулиране</translation>
</message>
<message>
<source>Retry</source>
<translation>Повторен опит</translation>
</message>
<message>
<source>Restore Defaults</source>
<translation>По подразбиране</translation>
</message>
<message>
<source>Cancel</source>
<translation>Отказ</translation>
</message>
<message>
<source>Ignore</source>
<translation>Пренебрегване</translation>
</message>
<message>
<source>N&amp;o to All</source>
<translation>Н&amp;е за всички</translation>
</message>
<message>
<source>Save All</source>
<translation>Запазване на всичко</translation>
</message>
<message>
<source>Discard</source>
<translation>Отхвърляне</translation>
</message>
<message>
<source>Yes to &amp;All</source>
<translation>Да за &amp;всички</translation>
</message>
</context>
</TS>

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="da">
<context>
<name>QShortcut</name>
<message>
<source>No</source>
<translation>Ingen</translation>
</message>
<message>
<source>Yes</source>
<translation>Ja</translation>
</message>
</context>
<context>
<name>QPlatformTheme</name>
<message>
<source>OK</source>
<translation>Okay</translation>
</message>
<message>
<source>&amp;No</source>
<translation>&amp;Ingen</translation>
</message>
<message>
<source>&amp;Yes</source>
<translation>&amp;Ja</translation>
</message>
<message>
<source>Help</source>
<translation>Hjælp</translation>
</message>
<message>
<source>Open</source>
<translation>Åben</translation>
</message>
<message>
<source>Save</source>
<translation>Gemme</translation>
</message>
<message>
<source>Abort</source>
<translation>Abort</translation>
</message>
<message>
<source>Apply</source>
<translation>Ansøge</translation>
</message>
<message>
<source>Close</source>
<translation>Tæt</translation>
</message>
<message>
<source>Reset</source>
<translation>Nulstil</translation>
</message>
<message>
<source>Retry</source>
<translation>Prøve igen</translation>
</message>
<message>
<source>Restore Defaults</source>
<translation>Gendanne standardindstillingerne</translation>
</message>
<message>
<source>Cancel</source>
<translation>Afbestille</translation>
</message>
<message>
<source>Ignore</source>
<translation>Ignorere</translation>
</message>
<message>
<source>N&amp;o to All</source>
<translation>&amp;Ingen for alle</translation>
</message>
<message>
<source>Save All</source>
<translation>Gem alle</translation>
</message>
<message>
<source>Discard</source>
<translation>Kassér</translation>
</message>
<message>
<source>Yes to &amp;All</source>
<translation>Ja til &amp;alle</translation>
</message>
</context>
</TS>

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="de">
<context>
<name>QShortcut</name>
<message>
<source>No</source>
<translation>Nein</translation>
</message>
<message>
<source>Yes</source>
<translation>Ja</translation>
</message>
</context>
<context>
<name>QPlatformTheme</name>
<message>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
<source>&amp;No</source>
<translation>&amp;Nein</translation>
</message>
<message>
<source>&amp;Yes</source>
<translation>&amp;Ja</translation>
</message>
<message>
<source>Help</source>
<translation>Hilfe</translation>
</message>
<message>
<source>Open</source>
<translation>Öffnen</translation>
</message>
<message>
<source>Save</source>
<translation>Speichern</translation>
</message>
<message>
<source>Abort</source>
<translation>Abbrechen</translation>
</message>
<message>
<source>Apply</source>
<translation>Anwenden</translation>
</message>
<message>
<source>Close</source>
<translation>Schließen</translation>
</message>
<message>
<source>Reset</source>
<translation>Zurücksetzen</translation>
</message>
<message>
<source>Retry</source>
<translation>Wiederholen</translation>
</message>
<message>
<source>Restore Defaults</source>
<translation>Voreinstellungen</translation>
</message>
<message>
<source>Cancel</source>
<translation>Abbrechen</translation>
</message>
<message>
<source>Ignore</source>
<translation>Ignorieren</translation>
</message>
<message>
<source>N&amp;o to All</source>
<translation>N&amp;ein, keine</translation>
</message>
<message>
<source>Save All</source>
<translation>Alles speichern</translation>
</message>
<message>
<source>Discard</source>
<translation>Verwerfen</translation>
</message>
<message>
<source>Yes to &amp;All</source>
<translation>Ja, &amp;alle</translation>
</message>
</context>
</TS>

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="el_GR">
<context>
<name>QShortcut</name>
<message>
<source>No</source>
<translation>Οχι</translation>
</message>
<message>
<source>Yes</source>
<translation>Ναί</translation>
</message>
</context>
<context>
<name>QPlatformTheme</name>
<message>
<source>OK</source>
<translation>Εντάξει</translation>
</message>
<message>
<source>&amp;No</source>
<translation>&amp;Οχι</translation>
</message>
<message>
<source>&amp;Yes</source>
<translation>&amp;Ναί</translation>
</message>
<message>
<source>Help</source>
<translation>Βοήθεια</translation>
</message>
<message>
<source>Open</source>
<translation>Ανοιξε</translation>
</message>
<message>
<source>Save</source>
<translation>Σώσει</translation>
</message>
<message>
<source>Abort</source>
<translation>Αποβάλλω</translation>
</message>
<message>
<source>Apply</source>
<translation>Ισχύουν</translation>
</message>
<message>
<source>Close</source>
<translation>Κλείσε</translation>
</message>
<message>
<source>Reset</source>
<translation>Επαναφορά</translation>
</message>
<message>
<source>Retry</source>
<translation>Προσπαθησε ξανα</translation>
</message>
<message>
<source>Restore Defaults</source>
<translation>Επαναφέρετε τις προεπιλογές</translation>
</message>
<message>
<source>Cancel</source>
<translation>Ματαίωση</translation>
</message>
<message>
<source>Ignore</source>
<translation>Αγνοώ</translation>
</message>
<message>
<source>N&amp;o to All</source>
<translation>N&amp;o σε όλους</translation>
</message>
<message>
<source>Save All</source>
<translation>Αποθήκευση όλων</translation>
</message>
<message>
<source>Discard</source>
<translation>Απορρίπτω</translation>
</message>
<message>
<source>Yes to &amp;All</source>
<translation>Ν&amp;αι σε όλα</translation>
</message>
</context>
</TS>

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="es">
<context>
<name>QShortcut</name>
<message>
<source>No</source>
<translation>No</translation>
</message>
<message>
<source>Yes</source>
<translation></translation>
</message>
</context>
<context>
<name>QPlatformTheme</name>
<message>
<source>OK</source>
<translation>Aceptar</translation>
</message>
<message>
<source>&amp;No</source>
<translation>&amp;No</translation>
</message>
<message>
<source>&amp;Yes</source>
<translation>&amp;</translation>
</message>
<message>
<source>Help</source>
<translation>Ayuda</translation>
</message>
<message>
<source>Open</source>
<translation>Abrir</translation>
</message>
<message>
<source>Save</source>
<translation>Guardar</translation>
</message>
<message>
<source>Abort</source>
<translation>Interrumpir</translation>
</message>
<message>
<source>Apply</source>
<translation>Aplicar</translation>
</message>
<message>
<source>Close</source>
<translation>Cerrar</translation>
</message>
<message>
<source>Reset</source>
<translation>Reinicializar</translation>
</message>
<message>
<source>Retry</source>
<translation>Reintentar</translation>
</message>
<message>
<source>Restore Defaults</source>
<translation>Restaurar los valores predeterminados</translation>
</message>
<message>
<source>Cancel</source>
<translation>Cancelar</translation>
</message>
<message>
<source>Ignore</source>
<translation>Ignorar</translation>
</message>
<message>
<source>N&amp;o to All</source>
<translation>N&amp;o a todo</translation>
</message>
<message>
<source>Save All</source>
<translation>Guardar todo</translation>
</message>
<message>
<source>Discard</source>
<translation>Descartar</translation>
</message>
<message>
<source>Yes to &amp;All</source>
<translation> a &amp;todo</translation>
</message>
</context>
</TS>

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="fi">
<context>
<name>QShortcut</name>
<message>
<source>No</source>
<translation>Ei</translation>
</message>
<message>
<source>Yes</source>
<translation>Kyllä</translation>
</message>
</context>
<context>
<name>QPlatformTheme</name>
<message>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
<source>&amp;No</source>
<translation>&amp;Ei</translation>
</message>
<message>
<source>&amp;Yes</source>
<translation>&amp;Kyllä</translation>
</message>
<message>
<source>Help</source>
<translation>Ohje</translation>
</message>
<message>
<source>Open</source>
<translation>Avaa</translation>
</message>
<message>
<source>Save</source>
<translation>Tallenna</translation>
</message>
<message>
<source>Abort</source>
<translation>Keskeytä</translation>
</message>
<message>
<source>Apply</source>
<translation>Käytä</translation>
</message>
<message>
<source>Close</source>
<translation>Sulje</translation>
</message>
<message>
<source>Reset</source>
<translation>Palauta</translation>
</message>
<message>
<source>Retry</source>
<translation>Yritä uudelleen</translation>
</message>
<message>
<source>Restore Defaults</source>
<translation>Palauta oletukset</translation>
</message>
<message>
<source>Cancel</source>
<translation>Peru</translation>
</message>
<message>
<source>Ignore</source>
<translation>Ohita</translation>
</message>
<message>
<source>N&amp;o to All</source>
<translation>E&amp;i kaikkiin</translation>
</message>
<message>
<source>Save All</source>
<translation>Tallenna kaikki</translation>
</message>
<message>
<source>Discard</source>
<translation>Hylkää</translation>
</message>
<message>
<source>Yes to &amp;All</source>
<translation>Kyllä k&amp;aikkiin</translation>
</message>
</context>
</TS>

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="fil_PH">
<context>
<name>QShortcut</name>
<message>
<source>No</source>
<translation>Hindi</translation>
</message>
<message>
<source>Yes</source>
<translation>Oo</translation>
</message>
</context>
<context>
<name>QPlatformTheme</name>
<message>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
<source>&amp;No</source>
<translation>&amp;Hindi</translation>
</message>
<message>
<source>&amp;Yes</source>
<translation>&amp;Oo</translation>
</message>
<message>
<source>Help</source>
<translation>Tulong</translation>
</message>
<message>
<source>Open</source>
<translation>Buksan</translation>
</message>
<message>
<source>Save</source>
<translation>I-save</translation>
</message>
<message>
<source>Abort</source>
<translation>Abort</translation>
</message>
<message>
<source>Apply</source>
<translation>Mag-apply</translation>
</message>
<message>
<source>Close</source>
<translation>Isara</translation>
</message>
<message>
<source>Reset</source>
<translation>I-reset</translation>
</message>
<message>
<source>Retry</source>
<translation>Ulitin</translation>
</message>
<message>
<source>Restore Defaults</source>
<translation>Ibalik sa dating ayos</translation>
</message>
<message>
<source>Cancel</source>
<translation>Pagkansela</translation>
</message>
<message>
<source>Ignore</source>
<translation>ignorahin</translation>
</message>
<message>
<source>N&amp;o to All</source>
<translation>H&amp;indi sa lahat</translation>
</message>
<message>
<source>Save All</source>
<translation>Iligtas lahat</translation>
</message>
<message>
<source>Discard</source>
<translation>Itapon</translation>
</message>
<message>
<source>Yes to &amp;All</source>
<translation>Oo sa &amp;lahat</translation>
</message>
</context>
</TS>

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="fr">
<context>
<name>QShortcut</name>
<message>
<source>No</source>
<translation>Non</translation>
</message>
<message>
<source>Yes</source>
<translation>Oui</translation>
</message>
</context>
<context>
<name>QPlatformTheme</name>
<message>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
<source>&amp;No</source>
<translation>&amp;Non</translation>
</message>
<message>
<source>&amp;Yes</source>
<translation>&amp;Oui</translation>
</message>
<message>
<source>Help</source>
<translation>Aide</translation>
</message>
<message>
<source>Open</source>
<translation>Ouvrir</translation>
</message>
<message>
<source>Save</source>
<translation>Enregistrer</translation>
</message>
<message>
<source>Abort</source>
<translation>Abandonner</translation>
</message>
<message>
<source>Apply</source>
<translation>Appliquer</translation>
</message>
<message>
<source>Close</source>
<translation>Fermer</translation>
</message>
<message>
<source>Reset</source>
<translation>Réinitialiser</translation>
</message>
<message>
<source>Retry</source>
<translation>Réessayer</translation>
</message>
<message>
<source>Restore Defaults</source>
<translation>Restaurer les valeurs par défaut</translation>
</message>
<message>
<source>Cancel</source>
<translation>Annuler</translation>
</message>
<message>
<source>Ignore</source>
<translation>Ignorer</translation>
</message>
<message>
<source>N&amp;o to All</source>
<translation>Non à to&amp;ut</translation>
</message>
<message>
<source>Save All</source>
<translation>Tout enregistrer</translation>
</message>
<message>
<source>Discard</source>
<translation>Ne pas tenir compte</translation>
</message>
<message>
<source>Yes to &amp;All</source>
<translation>Oui à &amp;tout</translation>
</message>
</context>
</TS>

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="he_IL">
<context>
<name>QShortcut</name>
<message>
<source>No</source>
<translation>לא</translation>
</message>
<message>
<source>Yes</source>
<translation>כן</translation>
</message>
</context>
<context>
<name>QPlatformTheme</name>
<message>
<source>OK</source>
<translation>בסדר</translation>
</message>
<message>
<source>&amp;No</source>
<translation>&amp;לא</translation>
</message>
<message>
<source>&amp;Yes</source>
<translation>&amp;כן</translation>
</message>
<message>
<source>Help</source>
<translation>עזרה</translation>
</message>
<message>
<source>Open</source>
<translation>פתוח</translation>
</message>
<message>
<source>Save</source>
<translation>לְהוֹשִׁיעַ</translation>
</message>
<message>
<source>Abort</source>
<translation>בטל</translation>
</message>
<message>
<source>Apply</source>
<translation>שלח</translation>
</message>
<message>
<source>Close</source>
<translation>סגור</translation>
</message>
<message>
<source>Reset</source>
<translation>אפס</translation>
</message>
<message>
<source>Retry</source>
<translation>נסה שוב</translation>
</message>
<message>
<source>Restore Defaults</source>
<translation>לשחזר את ברירות מחדל</translation>
</message>
<message>
<source>Cancel</source>
<translation>ביטול</translation>
</message>
<message>
<source>Ignore</source>
<translation>להתעלם</translation>
</message>
<message>
<source>N&amp;o to All</source>
<translation>לא לכולם</translation>
</message>
<message>
<source>Save All</source>
<translation>שמור הכל</translation>
</message>
<message>
<source>Discard</source>
<translation>להשליך</translation>
</message>
<message>
<source>Yes to &amp;All</source>
<translation>כן לכולם</translation>
</message>
</context>
</TS>

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="it">
<context>
<name>QShortcut</name>
<message>
<source>No</source>
<translation>No</translation>
</message>
<message>
<source>Yes</source>
<translation></translation>
</message>
</context>
<context>
<name>QPlatformTheme</name>
<message>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
<source>&amp;No</source>
<translation>&amp;No</translation>
</message>
<message>
<source>&amp;Yes</source>
<translation>&amp;</translation>
</message>
<message>
<source>Help</source>
<translation>Aiuto</translation>
</message>
<message>
<source>Open</source>
<translation>Apri</translation>
</message>
<message>
<source>Save</source>
<translation>Salva</translation>
</message>
<message>
<source>Abort</source>
<translation>Interrompi</translation>
</message>
<message>
<source>Apply</source>
<translation>Applica</translation>
</message>
<message>
<source>Close</source>
<translation>Chiudi</translation>
</message>
<message>
<source>Reset</source>
<translation>Ripristina</translation>
</message>
<message>
<source>Retry</source>
<translation>Riprova</translation>
</message>
<message>
<source>Restore Defaults</source>
<translation>Ripristina valori predefiniti</translation>
</message>
<message>
<source>Cancel</source>
<translation>Annulla</translation>
</message>
<message>
<source>Ignore</source>
<translation>Ignora</translation>
</message>
<message>
<source>N&amp;o to All</source>
<translation>N&amp;o a tutti</translation>
</message>
<message>
<source>Save All</source>
<translation>Salva tutti</translation>
</message>
<message>
<source>Discard</source>
<translation>Tralascia</translation>
</message>
<message>
<source>Yes to &amp;All</source>
<translation> &amp;a tutti</translation>
</message>
</context>
</TS>

View File

@ -1,91 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="ja_JP">
<context>
<name>QShortcut</name>
<message>
<source>No</source>
<translation></translation>
</message>
<message>
<source>Yes</source>
<translation></translation>
</message>
</context>
<context>
<name>QPlatformTheme</name>
<message>
<source>OK</source>
<translatorcomment>I believe this is a better fit.</translatorcomment>
<translation></translation>
</message>
<message>
<source>&amp;No</source>
<translation>&amp;N </translation>
</message>
<message>
<source>&amp;Yes</source>
<translation>&amp;Y </translation>
</message>
<message>
<source>Help</source>
<translation></translation>
</message>
<message>
<source>Open</source>
<translation></translation>
</message>
<message>
<source>Save</source>
<translation></translation>
</message>
<message>
<source>Abort</source>
<translation></translation>
</message>
<message>
<source>Apply</source>
<translation></translation>
</message>
<message>
<source>Close</source>
<translation></translation>
</message>
<message>
<source>Reset</source>
<translation></translation>
</message>
<message>
<source>Retry</source>
<translation></translation>
</message>
<message>
<source>Restore Defaults</source>
<translation></translation>
</message>
<message>
<source>Cancel</source>
<translation></translation>
</message>
<message>
<source>Ignore</source>
<translation></translation>
</message>
<message>
<source>N&amp;o to All</source>
<translation>&amp;o </translation>
</message>
<message>
<source>Save All</source>
<translation></translation>
</message>
<message>
<source>Discard</source>
<translation></translation>
</message>
<message>
<source>Yes to &amp;All</source>
<translation>&amp;A </translation>
</message>
</context>
</TS>

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="ko">
<context>
<name>QShortcut</name>
<message>
<source>No</source>
<translation></translation>
</message>
<message>
<source>Yes</source>
<translation></translation>
</message>
</context>
<context>
<name>QPlatformTheme</name>
<message>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
<source>&amp;No</source>
<translation></translation>
</message>
<message>
<source>&amp;Yes</source>
<translation></translation>
</message>
<message>
<source>Help</source>
<translation></translation>
</message>
<message>
<source>Open</source>
<translation></translation>
</message>
<message>
<source>Save</source>
<translation></translation>
</message>
<message>
<source>Abort</source>
<translation></translation>
</message>
<message>
<source>Apply</source>
<translation></translation>
</message>
<message>
<source>Close</source>
<translation></translation>
</message>
<message>
<source>Reset</source>
<translation></translation>
</message>
<message>
<source>Retry</source>
<translation></translation>
</message>
<message>
<source>Restore Defaults</source>
<translation> </translation>
</message>
<message>
<source>Cancel</source>
<translation></translation>
</message>
<message>
<source>Ignore</source>
<translation></translation>
</message>
<message>
<source>N&amp;o to All</source>
<translation> </translation>
</message>
<message>
<source>Save All</source>
<translation> </translation>
</message>
<message>
<source>Discard</source>
<translation></translation>
</message>
<message>
<source>Yes to &amp;All</source>
<translation> </translation>
</message>
</context>
</TS>

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="nl">
<context>
<name>QShortcut</name>
<message>
<source>No</source>
<translation>Nee</translation>
</message>
<message>
<source>Yes</source>
<translation>Ja</translation>
</message>
</context>
<context>
<name>QPlatformTheme</name>
<message>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
<source>&amp;No</source>
<translation>&amp;Nee</translation>
</message>
<message>
<source>&amp;Yes</source>
<translation>&amp;Ja</translation>
</message>
<message>
<source>Help</source>
<translation>Hulp</translation>
</message>
<message>
<source>Open</source>
<translation>Openen</translation>
</message>
<message>
<source>Save</source>
<translation>Opslaan</translation>
</message>
<message>
<source>Abort</source>
<translation>Afbreken</translation>
</message>
<message>
<source>Apply</source>
<translation>Toepassen</translation>
</message>
<message>
<source>Close</source>
<translation>Sluiten</translation>
</message>
<message>
<source>Reset</source>
<translation>Herstellen</translation>
</message>
<message>
<source>Retry</source>
<translation>Opnieuw</translation>
</message>
<message>
<source>Restore Defaults</source>
<translation>Standaardwaarden</translation>
</message>
<message>
<source>Cancel</source>
<translation>Annuleren</translation>
</message>
<message>
<source>Ignore</source>
<translation>Negeren</translation>
</message>
<message>
<source>N&amp;o to All</source>
<translation>N&amp;ee, geen enkele</translation>
</message>
<message>
<source>Save All</source>
<translation>Sla alles op</translation>
</message>
<message>
<source>Discard</source>
<translation>Verwijderen</translation>
</message>
<message>
<source>Yes to &amp;All</source>
<translation>Ja, &amp;allemaal</translation>
</message>
</context>
</TS>

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="nn_NO">
<context>
<name>QShortcut</name>
<message>
<source>No</source>
<translation>Nei</translation>
</message>
<message>
<source>Yes</source>
<translation>Ja</translation>
</message>
</context>
<context>
<name>QPlatformTheme</name>
<message>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
<source>&amp;No</source>
<translation>&amp;Nei</translation>
</message>
<message>
<source>&amp;Yes</source>
<translation>&amp;Ja</translation>
</message>
<message>
<source>Help</source>
<translation>Hjelp</translation>
</message>
<message>
<source>Open</source>
<translation>Åpen</translation>
</message>
<message>
<source>Save</source>
<translation>Lagre</translation>
</message>
<message>
<source>Abort</source>
<translation>Avbryte</translation>
</message>
<message>
<source>Apply</source>
<translation>Søke om</translation>
</message>
<message>
<source>Close</source>
<translation>lukke</translation>
</message>
<message>
<source>Reset</source>
<translation>tilbakestille</translation>
</message>
<message>
<source>Retry</source>
<translation>Prøv nytt</translation>
</message>
<message>
<source>Restore Defaults</source>
<translation>Gjenopprett standardverdier</translation>
</message>
<message>
<source>Cancel</source>
<translation>kansellere</translation>
</message>
<message>
<source>Ignore</source>
<translation>Overse</translation>
</message>
<message>
<source>N&amp;o to All</source>
<translation>N&amp;ei til alle</translation>
</message>
<message>
<source>Save All</source>
<translation>Lagre alt</translation>
</message>
<message>
<source>Discard</source>
<translation>Forkast</translation>
</message>
<message>
<source>Yes to &amp;All</source>
<translation>Ja til &amp;alt</translation>
</message>
</context>
</TS>

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="pl">
<context>
<name>QShortcut</name>
<message>
<source>No</source>
<translation>Nie</translation>
</message>
<message>
<source>Yes</source>
<translation>Tak</translation>
</message>
</context>
<context>
<name>QPlatformTheme</name>
<message>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
<source>&amp;No</source>
<translation>&amp;Nie</translation>
</message>
<message>
<source>&amp;Yes</source>
<translation>&amp;Tak</translation>
</message>
<message>
<source>Help</source>
<translation>Pomoc</translation>
</message>
<message>
<source>Open</source>
<translation>Otwórz</translation>
</message>
<message>
<source>Save</source>
<translation>Zachowaj</translation>
</message>
<message>
<source>Abort</source>
<translation>Przerwij</translation>
</message>
<message>
<source>Apply</source>
<translation>Zastosuj</translation>
</message>
<message>
<source>Close</source>
<translation>Zamknij</translation>
</message>
<message>
<source>Reset</source>
<translation>Zresetuj</translation>
</message>
<message>
<source>Retry</source>
<translation>Ponów</translation>
</message>
<message>
<source>Restore Defaults</source>
<translation>Przywróć domyślne</translation>
</message>
<message>
<source>Cancel</source>
<translation>Anuluj</translation>
</message>
<message>
<source>Ignore</source>
<translation>Zignoruj</translation>
</message>
<message>
<source>N&amp;o to All</source>
<translation>Ni&amp;e dla wszystkich</translation>
</message>
<message>
<source>Save All</source>
<translation>Zachowaj wszystko</translation>
</message>
<message>
<source>Discard</source>
<translation>Odrzuć</translation>
</message>
<message>
<source>Yes to &amp;All</source>
<translation>Ta&amp;k dla wszystkich</translation>
</message>
</context>
</TS>

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="pt">
<context>
<name>QShortcut</name>
<message>
<source>No</source>
<translation>Não</translation>
</message>
<message>
<source>Yes</source>
<translation>sim</translation>
</message>
</context>
<context>
<name>QPlatformTheme</name>
<message>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
<source>&amp;No</source>
<translation>&amp;Não</translation>
</message>
<message>
<source>&amp;Yes</source>
<translation>&amp;sim</translation>
</message>
<message>
<source>Help</source>
<translation>Socorro</translation>
</message>
<message>
<source>Open</source>
<translation>Abrir</translation>
</message>
<message>
<source>Save</source>
<translation>salvar</translation>
</message>
<message>
<source>Abort</source>
<translation>Abortar</translation>
</message>
<message>
<source>Apply</source>
<translation>aplicar</translation>
</message>
<message>
<source>Close</source>
<translation>Fechar</translation>
</message>
<message>
<source>Reset</source>
<translation>Restabelecer</translation>
</message>
<message>
<source>Retry</source>
<translation>Repetir</translation>
</message>
<message>
<source>Restore Defaults</source>
<translation>Restaurar padrões</translation>
</message>
<message>
<source>Cancel</source>
<translation>Cancelar</translation>
</message>
<message>
<source>Ignore</source>
<translation>Ignorar</translation>
</message>
<message>
<source>N&amp;o to All</source>
<translation>&amp;o para todos</translation>
</message>
<message>
<source>Save All</source>
<translation>Salvar tudo</translation>
</message>
<message>
<source>Discard</source>
<translation>Descartar</translation>
</message>
<message>
<source>Yes to &amp;All</source>
<translation>Sim para &amp;tudo</translation>
</message>
</context>
</TS>

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="ro_RO">
<context>
<name>QShortcut</name>
<message>
<source>No</source>
<translation>Nu</translation>
</message>
<message>
<source>Yes</source>
<translation>da</translation>
</message>
</context>
<context>
<name>QPlatformTheme</name>
<message>
<source>OK</source>
<translation>O.K</translation>
</message>
<message>
<source>&amp;No</source>
<translation>&amp;Nu</translation>
</message>
<message>
<source>&amp;Yes</source>
<translation>&amp;Da</translation>
</message>
<message>
<source>Help</source>
<translation>Ajutor</translation>
</message>
<message>
<source>Open</source>
<translation>Deschis</translation>
</message>
<message>
<source>Save</source>
<translation>salva</translation>
</message>
<message>
<source>Abort</source>
<translation>Abandonați</translation>
</message>
<message>
<source>Apply</source>
<translation>aplica</translation>
</message>
<message>
<source>Close</source>
<translation>Închide</translation>
</message>
<message>
<source>Reset</source>
<translation>Resetați</translation>
</message>
<message>
<source>Retry</source>
<translation>Reîncercați</translation>
</message>
<message>
<source>Restore Defaults</source>
<translation>Restabiliti setarile de baza</translation>
</message>
<message>
<source>Cancel</source>
<translation>Anulare</translation>
</message>
<message>
<source>Ignore</source>
<translation>Ignora</translation>
</message>
<message>
<source>N&amp;o to All</source>
<translation>N&amp;u tuturor</translation>
</message>
<message>
<source>Save All</source>
<translation>Salvează tot</translation>
</message>
<message>
<source>Discard</source>
<translation>Renunțați</translation>
</message>
<message>
<source>Yes to &amp;All</source>
<translation>D&amp;a la toate</translation>
</message>
</context>
</TS>

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="ru" sourcelanguage="en">
<context>
<name>QShortcut</name>
<message>
<source>No</source>
<translation>Нет</translation>
</message>
<message>
<source>Yes</source>
<translation>Да</translation>
</message>
</context>
<context>
<name>QPlatformTheme</name>
<message>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
<source>&amp;No</source>
<translation>&amp;Нет</translation>
</message>
<message>
<source>&amp;Yes</source>
<translation>&amp;Да</translation>
</message>
<message>
<source>Help</source>
<translation>Помощь</translation>
</message>
<message>
<source>Open</source>
<translation>Открыть</translation>
</message>
<message>
<source>Save</source>
<translation>Сохранить</translation>
</message>
<message>
<source>Abort</source>
<translation>Прервать</translation>
</message>
<message>
<source>Apply</source>
<translation>Применить</translation>
</message>
<message>
<source>Close</source>
<translation>Закрыть</translation>
</message>
<message>
<source>Reset</source>
<translation>Сброс</translation>
</message>
<message>
<source>Retry</source>
<translation>Повторная попытка</translation>
</message>
<message>
<source>Restore Defaults</source>
<translation>Восстановление настроек по умолчанию</translation>
</message>
<message>
<source>Cancel</source>
<translation>Отмена</translation>
</message>
<message>
<source>Ignore</source>
<translation>Игнорировать</translation>
</message>
<message>
<source>N&amp;o to All</source>
<translation>Н&amp;ет всем</translation>
</message>
<message>
<source>Save All</source>
<translation>Сохранить все</translation>
</message>
<message>
<source>Discard</source>
<translation>Отбросить</translation>
</message>
<message>
<source>Yes to &amp;All</source>
<translation>Д&amp;а всем</translation>
</message>
</context>
</TS>

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="sv_SE">
<context>
<name>QShortcut</name>
<message>
<source>No</source>
<translation>Nej</translation>
</message>
<message>
<source>Yes</source>
<translation>Ja</translation>
</message>
</context>
<context>
<name>QPlatformTheme</name>
<message>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
<source>&amp;No</source>
<translation>&amp;Nej</translation>
</message>
<message>
<source>&amp;Yes</source>
<translation>&amp;Ja</translation>
</message>
<message>
<source>Help</source>
<translation>Hjälp</translation>
</message>
<message>
<source>Open</source>
<translation>Öppen</translation>
</message>
<message>
<source>Save</source>
<translation>Spara</translation>
</message>
<message>
<source>Abort</source>
<translation>Avbryta</translation>
</message>
<message>
<source>Apply</source>
<translation>Tillämpa</translation>
</message>
<message>
<source>Close</source>
<translation>Stänga</translation>
</message>
<message>
<source>Reset</source>
<translation>Återställa</translation>
</message>
<message>
<source>Retry</source>
<translation>Försök igen</translation>
</message>
<message>
<source>Restore Defaults</source>
<translation>Återgå till grundinställningarna</translation>
</message>
<message>
<source>Cancel</source>
<translation>Avbryt</translation>
</message>
<message>
<source>Ignore</source>
<translation>Ignorera</translation>
</message>
<message>
<source>N&amp;o to All</source>
<translation>&amp;Inte till alla</translation>
</message>
<message>
<source>Save All</source>
<translation>Rädda alla</translation>
</message>
<message>
<source>Discard</source>
<translation>Kassera</translation>
</message>
<message>
<source>Yes to &amp;All</source>
<translation>Ja till &amp;allt</translation>
</message>
</context>
</TS>

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="th_TH" sourcelanguage="en">
<context>
<name>QShortcut</name>
<message>
<source>No</source>
<translation></translation>
</message>
<message>
<source>Yes</source>
<translation></translation>
</message>
</context>
<context>
<name>QPlatformTheme</name>
<message>
<source>OK</source>
<translation></translation>
</message>
<message>
<source>&amp;No</source>
<translation>&amp;</translation>
</message>
<message>
<source>&amp;Yes</source>
<translation>&amp;</translation>
</message>
<message>
<source>Help</source>
<translation></translation>
</message>
<message>
<source>Open</source>
<translation></translation>
</message>
<message>
<source>Save</source>
<translation></translation>
</message>
<message>
<source>Abort</source>
<translation></translation>
</message>
<message>
<source>Apply</source>
<translation></translation>
</message>
<message>
<source>Close</source>
<translation></translation>
</message>
<message>
<source>Reset</source>
<translation></translation>
</message>
<message>
<source>Retry</source>
<translation></translation>
</message>
<message>
<source>Restore Defaults</source>
<translation></translation>
</message>
<message>
<source>Cancel</source>
<translation></translation>
</message>
<message>
<source>Ignore</source>
<translation></translation>
</message>
<message>
<source>N&amp;o to All</source>
<translation>&amp;</translation>
</message>
<message>
<source>Save All</source>
<translation></translation>
</message>
<message>
<source>Discard</source>
<translation></translation>
</message>
<message>
<source>Yes to &amp;All</source>
<translation>&amp;</translation>
</message>
</context>
</TS>

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="tr_TR">
<context>
<name>QShortcut</name>
<message>
<source>No</source>
<translation>Hayır</translation>
</message>
<message>
<source>Yes</source>
<translation>Evet</translation>
</message>
</context>
<context>
<name>QPlatformTheme</name>
<message>
<source>OK</source>
<translation>Tamam</translation>
</message>
<message>
<source>&amp;No</source>
<translation>&amp;Hayır</translation>
</message>
<message>
<source>&amp;Yes</source>
<translation>&amp;Evet</translation>
</message>
<message>
<source>Help</source>
<translation>Yardım</translation>
</message>
<message>
<source>Open</source>
<translation></translation>
</message>
<message>
<source>Save</source>
<translation>Kaydet</translation>
</message>
<message>
<source>Abort</source>
<translation>Durdur</translation>
</message>
<message>
<source>Apply</source>
<translation>Uygula</translation>
</message>
<message>
<source>Close</source>
<translation>Kapat</translation>
</message>
<message>
<source>Reset</source>
<translation>Sıfırla</translation>
</message>
<message>
<source>Retry</source>
<translation>Tekrar Dene</translation>
</message>
<message>
<source>Restore Defaults</source>
<translation>Varsayılanları Geri Yükle</translation>
</message>
<message>
<source>Cancel</source>
<translation>İptal</translation>
</message>
<message>
<source>Ignore</source>
<translation>Görmezden Gel</translation>
</message>
<message>
<source>N&amp;o to All</source>
<translation>&amp;Tümüne Hayır</translation>
</message>
<message>
<source>Save All</source>
<translation>Hepsini Kaydet</translation>
</message>
<message>
<source>Discard</source>
<translation>At</translation>
</message>
<message>
<source>Yes to &amp;All</source>
<translation>Tümüne E&amp;vet</translation>
</message>
</context>
</TS>

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="zh">
<context>
<name>QShortcut</name>
<message>
<source>No</source>
<translation></translation>
</message>
<message>
<source>Yes</source>
<translation></translation>
</message>
</context>
<context>
<name>QPlatformTheme</name>
<message>
<source>OK</source>
<translation></translation>
</message>
<message>
<source>&amp;No</source>
<translation>(&amp;N)</translation>
</message>
<message>
<source>&amp;Yes</source>
<translation>(&amp;Y)</translation>
</message>
<message>
<source>Help</source>
<translation></translation>
</message>
<message>
<source>Open</source>
<translation></translation>
</message>
<message>
<source>Save</source>
<translation></translation>
</message>
<message>
<source>Abort</source>
<translation></translation>
</message>
<message>
<source>Apply</source>
<translation></translation>
</message>
<message>
<source>Close</source>
<translation></translation>
</message>
<message>
<source>Reset</source>
<translation></translation>
</message>
<message>
<source>Retry</source>
<translation></translation>
</message>
<message>
<source>Restore Defaults</source>
<translation></translation>
</message>
<message>
<source>Cancel</source>
<translation></translation>
</message>
<message>
<source>Ignore</source>
<translation></translation>
</message>
<message>
<source>N&amp;o to All</source>
<translation>(&amp;O)</translation>
</message>
<message>
<source>Save All</source>
<translation></translation>
</message>
<message>
<source>Discard</source>
<translation></translation>
</message>
<message>
<source>Yes to &amp;All</source>
<translation>(&amp;A)</translation>
</message>
</context>
</TS>

View File

@ -462,7 +462,6 @@ void RecalcMAP::updateSpanData(int &currentLoc, int & currentEL,int& currentData
void RecalcMAP::updateEventsChannel(Session*sess,ChannelID chanId, QVector<int> &dataArray, PressureInfo & info )
{
this->chanId=chanId;
int qtyEvents=0;
EventDataType duration = 0, gain;
qint64 t , start;
@ -502,7 +501,6 @@ void RecalcMAP::updateEventsChannel(Session*sess,ChannelID chanId, QVector<int>
if (ts>maxx) continue;
if (ts<minx) ts=minx;
if (t>maxx) t=maxx;
qtyEvents++;
updateSpanData(currentLoc , currentEL , currentData , ts , t , dataArray , info ) ;
} else {
if (t>maxx) continue;
@ -625,6 +623,10 @@ void RecalcMAP::updateTimes(PressureInfo & info) {
void RecalcMAP:: setSelectionRange(gGraph* graph) {
graph->graphView()->GetXBounds(minTime, maxTime);
// changes suggested by grnbrg
qint64 clockdrift = qint64(p_profile->cpap->clockDrift()) * 1000L;
minTime -= clockdrift;
maxTime -= clockdrift;
}
void RecalcMAP::run()

View File

@ -1413,9 +1413,15 @@ bool gGraphView::renderGraphs(QPainter &painter)
// Calculate the height of pinned graphs
float pinned_height = 0; // pixel height total
int pinned_graphs = 0; // count
bool showTitle=!AppSetting->disableDailyGraphTitles();
bool dailyGraph= mainwin->getDaily()->graphView() == this;
for (auto & g : m_graphs) {
if (dailyGraph) {
// suppress graph titles in daily graphs based on user preferences
g->setShowTitle(showTitle) ;
}
int minh = g->minHeight();
if (g->height() < minh) {
g->setHeight(minh);
@ -1428,7 +1434,6 @@ bool gGraphView::renderGraphs(QPainter &painter)
h = g->height() * m_scaleY;
pinned_height += h + graphSpacer;
pinned_graphs++;
}
py += pinned_height; // start drawing at the end of pinned space

View File

@ -468,11 +468,8 @@ void gOverviewGraph::paint(QPainter &painter, gGraph &w, const QRegion &region)
l_height = height;
float py;
EventDataType total;
int daynum = 0;
EventDataType h, tmp;
l_offset = (minx) % 86400000L;
offset = float(l_offset) / 86400000.0;
@ -559,7 +556,6 @@ void gOverviewGraph::paint(QPainter &painter, gGraph &w, const QRegion &region)
float compliance_hours = 0;
int incompliant = 0;
Day *day;
EventDataType hours;
@ -725,7 +721,6 @@ void gOverviewGraph::paint(QPainter &painter, gGraph &w, const QRegion &region)
if (type == ST_HOURS) {
if (tmp < compliance_hours) {
col = QColor("#f04040");
incompliant++;
} else if (summary_only) {
col = summaryColor;
}
@ -834,10 +829,6 @@ void gOverviewGraph::paint(QPainter &painter, gGraph &w, const QRegion &region)
lastdaygood = true;
// if (Q>maxx+extra) break;
} else {
if (Q < maxx) {
incompliant++;
}
lastdaygood = false;
}
@ -849,8 +840,6 @@ jumpnext:
px += barw;
daynum++;
//lastQ=Q;
}
painter.setClipping(false);

View File

@ -28,6 +28,7 @@ AppWideSetting::AppWideSetting(Preferences *pref) : PrefSettings(pref)
initPref(STR_AS_IncludeSerial, false);
initPref(STR_AS_MonochromePrinting, false);
//initPref(STR_AS_EventFlagSessionBar, false);
initPref(STR_AS_DisableDailyGraphTitles, false);
initPref(STR_AS_ShowPieChart, false);
m_animations = initPref(STR_AS_Animations, true).toBool();
m_squareWavePlots = initPref(STR_AS_SquareWave, false).toBool();
@ -35,6 +36,8 @@ AppWideSetting::AppWideSetting(Preferences *pref) : PrefSettings(pref)
m_graphTooltips = initPref(STR_AS_GraphTooltips, true).toBool();
m_usePixmapCaching = initPref(STR_AS_UsePixmapCaching, false).toBool();
m_odt = (OverlayDisplayType)initPref(STR_AS_OverlayType, (int)ODT_Bars).toInt();
initPref(STR_AS_GraphTooltips, 0);
m_alternatingColorsCombo = initPref(STR_AS_setAlternatingColorsCombo, 0).toInt();
#ifndef REMOVE_FITNESS
m_olm = (OverviewLinechartModes)initPref(STR_AS_OverviewLinechartMode, (int)OLC_Bartop).toInt();
#endif
@ -49,6 +52,7 @@ AppWideSetting::AppWideSetting(Preferences *pref) : PrefSettings(pref)
initPref(STR_US_AutoLaunchImport, false);
m_cacheSessions = initPref(STR_IS_CacheSessions, false).toBool();
initPref(STR_US_RemoveCardReminder, true);
initPref(STR_US_NotifyMessagBoxOption, false);
initPref(STR_US_DontAskWhenSavingScreenshots, false);
m_profileName = initPref(STR_GEN_Profile, "").toString();
initPref(STR_GEN_AutoOpenLastUsed, true);

View File

@ -39,6 +39,7 @@ const QString STR_AS_ShowPieChart = "EnablePieChart";
const QString STR_AS_Animations = "AnimationsAndTransitions";
const QString STR_AS_SquareWave = "SquareWavePlots";
const QString STR_AS_OverlayType = "OverlayType";
const QString STR_AS_setAlternatingColorsCombo = "AlternatingColorsCombo";
#ifndef REMOVE_FITNESS
const QString STR_AS_OverviewLinechartMode = "OverviewLinechartMode";
#endif
@ -47,6 +48,7 @@ const QString STR_AS_AllowYAxisScaling = "AllowYAxisScaling";
const QString STR_AS_IncludeSerial = "IncludeSerial";
const QString STR_AS_MonochromePrinting = "PrintBW";
//const QString STR_AS_EventFlagSessionBar = "EventFlagSessionBar";
const QString STR_AS_DisableDailyGraphTitles = "DisableDailyGraphTitles";
const QString STR_AS_GraphTooltips = "GraphTooltips";
const QString STR_AS_LineThickness = "LineThickness";
const QString STR_AS_LineCursorMode = "LineCursorMode";
@ -61,6 +63,7 @@ const QString STR_US_OpenTabAtStart = "OpenTabAtStart";
const QString STR_US_OpenTabAfterImport = "OpenTabAfterImport";
const QString STR_US_AutoLaunchImport = "AutoLaunchImport";
const QString STR_US_RemoveCardReminder = "RemoveCardReminder";
const QString STR_US_NotifyMessagBoxOption = "NotifyMessagBoxOption";
const QString STR_US_DontAskWhenSavingScreenshots = "DontAskWhenSavingScreenshots";
const QString STR_US_ShowPersonalData = "ShowPersonalData";
const QString STR_IS_CacheSessions = "MemoryHog";
@ -87,6 +90,7 @@ public:
bool m_usePixmapCaching, m_antiAliasing, m_squareWavePlots,m_graphTooltips, m_lineCursorMode, m_animations;
bool m_showPerformance, m_showDebug;
int m_tooltipTimeout, m_graphHeight, m_scrollDampening;
int m_alternatingColorsCombo;
bool m_multithreading, m_cacheSessions;
float m_lineThickness;
@ -139,9 +143,11 @@ public:
//! \brief Whether to print reports in black and white, which can be more legible on non-color printers
bool monochromePrinting() const { return getPref(STR_AS_MonochromePrinting).toBool(); }
//bool eventFlagSessionBar() const { return getPref(STR_AS_EventFlagSessionBar).toBool(); }
bool disableDailyGraphTitles() const { return getPref(STR_AS_DisableDailyGraphTitles).toBool(); }
//! \Allow disabling of sessions
//! \brief Whether to show graph tooltips
inline bool graphTooltips() const { return m_graphTooltips; }
inline int alternatingColorsCombo() { return m_alternatingColorsCombo;}
//! \brief Pen width of line plots
inline float lineThickness() const { return m_lineThickness; }
//! \brief Whether to show line cursor
@ -159,6 +165,7 @@ public:
int openTabAtStart() const { return getPref(STR_US_OpenTabAtStart).toInt(); }
int openTabAfterImport() const { return getPref(STR_US_OpenTabAfterImport).toInt(); }
bool removeCardReminder() const { return getPref(STR_US_RemoveCardReminder).toBool(); }
bool notifyMessagBoxOption() const { return getPref(STR_US_NotifyMessagBoxOption).toBool(); }
bool dontAskWhenSavingScreenshots() const { return getPref(STR_US_DontAskWhenSavingScreenshots).toBool(); }
bool autoOpenLastUsed() const { return getPref(STR_GEN_AutoOpenLastUsed).toBool(); }
inline const QString & language() const { return m_language; }
@ -200,9 +207,11 @@ public:
//! \brief Sets whether to print reports in black and white, which can be more legible on non-color printers
void setMonochromePrinting(bool b) { setPref(STR_AS_MonochromePrinting, b); }
// void setEventFlagSessionBar(bool b) { setPref(STR_AS_EventFlagSessionBar, b); }
void setDisableDailyGraphTitles(bool b) { setPref(STR_AS_DisableDailyGraphTitles, b); }
//! \brief Sets whether to allow double clicking on Y-Axis labels to change vertical scaling mode
void setGraphTooltips(bool b) { setPref(STR_AS_GraphTooltips, m_graphTooltips=b); }
//! \brief Sets the type of overlay flags (which are displayed over the Flow Waveform)
void setAlternatingColorsCombo(int b) { setPref(STR_AS_setAlternatingColorsCombo, m_alternatingColorsCombo=b); }
#ifndef REMOVE_FITNESS
void setOverviewLinechartMode(OverviewLinechartModes olm) { setPref(STR_AS_OverviewLinechartMode, (int)(m_olm=olm)); }
#endif
@ -217,6 +226,7 @@ public:
void setOpenTabAtStart(int idx) { setPref(STR_US_OpenTabAtStart, idx); }
void setOpenTabAfterImport(int idx) { setPref(STR_US_OpenTabAfterImport, idx); }
void setRemoveCardReminder(bool b) { setPref(STR_US_RemoveCardReminder, b); }
void setNotifyMessagBoxOption(bool b) { setPref(STR_US_NotifyMessagBoxOption, b); }
void setDontAskWhenSavingScreenshots(bool b) { setPref(STR_US_DontAskWhenSavingScreenshots, b); }
void setShowPersonalData(bool b) { setPref(STR_US_ShowPersonalData, b); }

View File

@ -1,7 +1,7 @@
/* Custom CPAP/Oximetry Calculations Header
*
* Copyright (c) 2019-2024 The OSCAR Team
* Copyright (c) 2011-2018 Mark Watkins
* Copyright (c) 2011-2018 Mark Watkins
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of the source code
@ -1498,7 +1498,7 @@ int calcSPO2Drop(Session *session)
//qint64 rtime[ringsize]={0};
//int rp=0;
int min;
int cnt = 0;
// int cnt = 0;
// tmp = 0;
qint64 start = 0;
@ -1520,7 +1520,7 @@ int calcSPO2Drop(Session *session)
if (time > start + 3600000) { break; } // just look at the first hour
// tmp += val;
cnt++;
// cnt++;
}
}
@ -1551,7 +1551,8 @@ int calcSPO2Drop(Session *session)
if (!current) { continue; }
time = el->time(i);
/*ring[rp]=val;
/*
ring[rp]=val;
rtime[rp]=time;
rp++;
rp=rp % ringsize;
@ -1572,7 +1573,8 @@ int calcSPO2Drop(Session *session)
if (!cnt) {
unsigned j=abs((rp-1) % ringsize);
tmp=(ring[j]+val)/2;
} else tmp/=EventDataType(cnt); */
} else tmp/=EventDataType(cnt);
*/
val = baseline;
lastt = 0;

View File

@ -256,7 +256,7 @@ QString appResourcePath()
paths.append( QString( "/usr/local/share/" ) + appName );
#endif
for (auto p = begin(paths); p != end(paths); ++p ) {
QString fname = *p+QString("/Translations/oscar_qt_fr.qm");
QString fname = *p+QString("/Html/about.html"); // was "/Translations/oscar_qt_fr.qm" - Crimson Nape
qDebug() << "Trying" << fname;
QFileInfo f = QFileInfo(fname);
if ( f.exists() ) {

View File

@ -158,7 +158,9 @@ const QString STR_GEN_DataFolder = "DataFolder";
const QString STR_PREF_ReimportBackup = "ReimportBackup";
const QString STR_PREF_LastCPAPPath = "LastCPAPPath";
const QString STR_PREF_LastJournalPath = "LastJouralPath";
const QString STR_PREF_LastOximetryPath = "LastOximetryPath";
const QString STR_PREF_LastExportCsvPath = "LastExportCsvPath";
const QString STR_MACH_ResMed = "ResMed";
const QString STR_MACH_PRS1 = "PRS1";

View File

@ -1,7 +1,7 @@
/* SleepLib Day Class Implementation
*
* Copyright (c) 2019-2024 The OSCAR Team
* Copyright (c) 2011-2018 Mark Watkins
* Copyright (c) 2011-2018 Mark Watkins
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of the source code
@ -136,7 +136,7 @@ void Day::addSession(Session *s)
<< "from machine" << s->machine()->serial() << "with first=0";
return;
}
for (auto & sess : sessions) {
if (sess->session() == s->session() && sess->type() == s->type()) {
// This usually indicates a problem in purging or cleanup somewhere,
@ -854,7 +854,7 @@ ChannelID Day::getPressureChannelID() {
return preferredID;
}
}
qDebug() << "No pressure channel for " << getCPAPModeStr();
return NoChannel;
}
@ -1419,7 +1419,7 @@ void Day::removeMachine(Machine * mach)
//
// This has no functional use and can be removed when the data structures are cleaned up
// with better encapsulation and fewer unnecessary references between each other.
QList<Session*> list = sessions; // make a copy so the iterator doesn't get broken by removals
for (auto & sess : list) {
if (sess->machine() == mach) {
@ -1430,7 +1430,7 @@ void Day::removeMachine(Machine * mach)
removeSession(sess);
}
}
for (auto & m : machines.keys()) {
if (machines[m] == mach) {
// This indicates a problem internal to the Day class, since removeSession should remove
@ -1452,6 +1452,7 @@ int Day::getCPAPMode()
if (!mach) return 0;
CPAPLoader * loader = qobject_cast<CPAPLoader *>(mach->loader());
if (!loader) return 0;
ChannelID modechan = loader->CPAPModeChannel();
*/
@ -1472,6 +1473,9 @@ QString Day::getCPAPModeStr()
if (!mach) return STR_MessageBox_Error;
CPAPLoader * loader = qobject_cast<CPAPLoader *>(mach->loader());
if (!loader) {
return QObject::tr("ERROR:NOT AVAILABLE"); //STR_MessageBox_Error;
}
ChannelID modechan = loader->CPAPModeChannel();
@ -1511,8 +1515,9 @@ QString Day::getPressureRelief()
if (!mach) return STR_MessageBox_Error;
CPAPLoader * loader = qobject_cast<CPAPLoader *>(mach->loader());
if (!loader) return STR_MessageBox_Error;
if (!loader) {
return QObject::tr("ERROR:NOT AVAILABLE"); //STR_MessageBox_Error;
}
QString pr_str;
@ -1633,7 +1638,7 @@ QString Day::getPressureSettings()
arg(validPressure(settings_max(CPAP_IPAPLo))).
arg(validPressure(settings_max(CPAP_IPAPHi))).
arg(units);
else
else
retStr = QObject::tr("EPAP %1-%2 IPAP %3-%4 (%5)").
arg(validPressure(settings_min(CPAP_EPAPLo))).
arg(validPressure(settings_min(CPAP_EPAPHi))).

View File

@ -1,216 +1,36 @@
/* SleepLib Journal Implementation
*
* Copyright (c) 2019-2024 The OSCAR Team
* Copyright (c) 2011-2018 Mark Watkins
* Copyright (c) 2011-2018 Mark Watkins
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of the source code
* for more details. */
#define TEST_MACROS_ENABLEDoff
#define TEST_MACROS_ENABLED
#include <test_macros.h>
#include "journal.h"
#include "machine_common.h"
#include <QMessageBox>
#include <QDomDocument>
#include <QDomElement>
#include <QFile>
#include <QTextStream>
#include <QXmlStreamWriter>
#include <QDir>
#include <QMessageBox>
#include "journal.h"
#include "daily.h"
#include "SleepLib/common.h"
#include "SleepLib/machine_common.h"
#include "SleepLib/session.h"
#include "SleepLib/profiles.h"
#include "mainwindow.h"
const int journal_data_version = 1;
extern MainWindow * mainwin;
const QString OLD_ZOMBIE = QString("zombie");
const QString ZOMBIE = QString("Feelings");
const QString WEIGHT = QString("weight");
JournalEntry::JournalEntry(QDate date)
{
Machine * jmach = p_profile->GetMachine(MT_JOURNAL);
if (jmach == nullptr) { // Create Journal Device record if it doesn't already exist
MachineInfo info(MT_JOURNAL,0, "Journal", QObject::tr("Journal Data"), QString(), QString(), QString(), QString("OSCAR"), QDateTime::currentDateTime(), journal_data_version);
// Using device ID 1 rather than a random number, so in future, if profile.xml gets screwed up they'll get their data back..
// TODO: Perhaps search for unlinked journal folders here to save some anger and frustration? :P
MachineID machid = 1;
QString path = p_profile->Get("{" + STR_GEN_DataFolder + "}");
QDir dir(path);
QStringList filters;
filters << "Journal_*";
QStringList dirs = dir.entryList(filters,QDir::Dirs);
int journals = dirs.size();
if (journals > 0) {
QString tmp = dirs[0].section("_", -1);
bool ok;
machid = tmp.toUInt(&ok, 16);
if (!ok) {
QMessageBox::warning(nullptr, STR_MessageBox_Warning,
QObject::tr("OSCAR found an old Journal folder, but it looks like it's been renamed:")+"\n\n"+
QString("%1").arg(dirs[0])+
QObject::tr("OSCAR will not touch this folder, and will create a new one instead.")+"\n\n"+
QObject::tr("Please be careful when playing in OSCAR's profile folders :-P"), QMessageBox::Ok);
// User renamed the folder.. report this
machid = 1;
}
if (journals > 1) {
QMessageBox::warning(nullptr, STR_MessageBox_Warning,
QObject::tr("For some reason, OSCAR couldn't find a journal object record in your profile, but did find multiple Journal data folders.\n\n")+
QObject::tr("OSCAR picked only the first one of these, and will use it in future:\n\n")+
QString("%1").arg(dirs[0])+
QObject::tr("If your old data is missing, copy the contents of all the other Journal_XXXXXXX folders to this one manually."), QMessageBox::Ok);
// more then one.. report this.
}
}
jmach = p_profile->CreateMachine(info, machid);
}
m_date = date;
session = nullptr;
day = p_profile->GetDay(date, MT_JOURNAL);
if (day != nullptr) {
session = day->firstSession(MT_JOURNAL);
} else {
// Doesn't exist.. create a new one..
session = new Session(jmach,0);
qint64 st,et;
QDateTime dt(date,QTime(22,0)); // 10pm localtime
st=qint64(dt.toTime_t())*1000L;
et=st+3600000L;
session->set_first(st);
session->set_last(et);
// Let it live in memory...but not on disk unless data is changed...
jmach->AddSession(session, true);
// and where does day get set??? does day actually need to be set??
day = p_profile->GetDay(date, MT_JOURNAL);
}
}
JournalEntry::~JournalEntry()
{
if (session && session->IsChanged()) {
Save();
}
}
bool JournalEntry::Save()
{
if (session && session->IsChanged()) {
qDebug() << "Saving journal session for" << m_date;
// just need to write bookmarks, the rest are already stored in the session
QVariantList start;
QVariantList end;
QStringList notes;
int size = bookmarks.size();
for (int i=0; i<size; ++i) {
const Bookmark & bm = bookmarks.at(i);
start.append(bm.start);
end.append(bm.end);
notes.append(bm.notes);
}
session->settings[Bookmark_Start] = start;
session->settings[Bookmark_End] = end;
session->settings[Bookmark_Notes] = notes;
session->settings[LastUpdated] = QDateTime::currentDateTime().toTime_t();
session->StoreSummary();
return true;
}
return false;
}
QString JournalEntry::notes()
{
QHash<ChannelID, QVariant>::iterator it;
if (session && ((it=session->settings.find(Journal_Notes)) != session->settings.end())) {
return it.value().toString();
}
return QString();
}
void JournalEntry::setNotes(QString notes)
{
if (!session) return;
session->settings[Journal_Notes] = notes;
session->SetChanged(true);
}
EventDataType JournalEntry::weight()
{
QHash<ChannelID, QVariant>::iterator it;
if (session && ((it = session->settings.find(Journal_Weight)) != session->settings.end())) {
return it.value().toFloat();
}
return 0;
}
void JournalEntry::setWeight(EventDataType weight)
{
if (!session) return;
session->settings[Journal_Weight] = weight;
session->SetChanged(true);
}
int JournalEntry::zombie()
{
QHash<ChannelID, QVariant>::iterator it;
if (session && ((it = session->settings.find(Journal_ZombieMeter)) != session->settings.end())) {
return it.value().toFloat();
}
return 0;
}
void JournalEntry::setZombie(int zombie)
{
if (!session) return;
session->settings[Journal_ZombieMeter] = zombie;
session->SetChanged(true);
}
QList<Bookmark> & JournalEntry::getBookmarks()
{
bookmarks.clear();
if (!session || !session->settings.contains(Bookmark_Start)) {
return bookmarks;
}
QVariantList start=session->settings[Bookmark_Start].toList();
QVariantList end=session->settings[Bookmark_End].toList();
QStringList notes=session->settings[Bookmark_Notes].toStringList();
int size = start.size();
for (int i=0; i < size; ++i) {
bookmarks.append(Bookmark(start.at(i).toLongLong(), end.at(i).toLongLong(), notes.at(i)));
}
return bookmarks;
}
void JournalEntry::addBookmark(qint64 start, qint64 end, QString note)
{
bookmarks.append(Bookmark(start,end,note));
session->SetChanged(true);
}
void JournalEntry::delBookmark(qint64 start, qint64 end)
{
bool removed;
do {
removed = false;
int size = bookmarks.size();
for (int i=0; i<size; ++i) {
const Bookmark & bm = bookmarks.at(i);
if ((bm.start == start) && (bm.end == end)) {
bookmarks.removeAt(i);
session->SetChanged(true); // make sure it gets saved later..
removed=true;
break;
}
}
} while (removed); // clean up any stupid duplicates just in case.. :P
// if I wanted to be nice above, I could add the note string to the search as well..
// (some users might be suprised to see the lot go with the same start and end index)
}
void BackupJournal(QString filename)
bool Journal::BackupJournal(QString filename)
{
QString outBuf;
QXmlStreamWriter stream(&outBuf);
@ -220,13 +40,22 @@ void BackupJournal(QString filename)
stream.writeStartDocument();
// stream.writeProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\"");
stream.writeStartElement("OSCAR");
stream.writeAttribute("created", QDateTime::currentDateTime().toString(Qt::ISODate));
stream.writeStartElement("Journal");
stream.writeAttribute("username", p_profile->user->userName());
stream.writeAttribute("height_cm", QString::number(p_profile->user->height()));
if (p_profile->general->unitSystem()!=US_Undefined) {
stream.writeAttribute("systemUnits", ( p_profile->general->unitSystem()==US_Metric?"Metric":"Englsh") );
}
QDate first = p_profile->FirstDay(MT_JOURNAL);
QDate last = p_profile->LastDay(MT_JOURNAL);
DEBUGFC Q(first) Q(last);
QDate date = first.addDays(-1);
int days_saved = 0 ;
do {
date = date.addDays(1);
@ -243,18 +72,33 @@ void BackupJournal(QString filename)
&& !journal->settingExists(Bookmark_Start)) {
continue;
}
QString weight;
QString zombie;
QString notes;
QString lastupdated;
QVariantList start;
int havedata=0;
stream.writeStartElement("day");
stream.writeAttribute("date", date.toString());
if (journal->settingExists(Journal_Weight)) {
QString weight = sess->settings[Journal_Weight].toString();
stream.writeAttribute("weight", weight);
weight = sess->settings[Journal_Weight].toString();
havedata |= JRNL_Weight ;
}
if (journal->settingExists(Journal_ZombieMeter)) {
QString zombie = sess->settings[Journal_ZombieMeter].toString();
stream.writeAttribute("zombie", zombie);
zombie = sess->settings[Journal_ZombieMeter].toString();
havedata |= JRNL_Zombie ;
}
if (journal->settingExists(Journal_Notes)) {
notes = sess->settings[Journal_Notes].toString();
//notes = Daily::convertHtmlToPlainText(notes).trimmed();
havedata |= JRNL_Notes ;
}
if (journal->settingExists(Bookmark_Start)) {
start=sess->settings[Bookmark_Start].toList();
if (start.size()>0) havedata |= JRNL_Bookmarks ;
}
if (journal->settingExists(LastUpdated)) {
@ -264,35 +108,45 @@ void BackupJournal(QString filename)
#else
qint64 dtx = dt.toSecsSinceEpoch();
#endif
QString dts = QString::number(dtx);
stream.writeAttribute("lastupdated", dts);
lastupdated = QString::number(dtx);
}
if (journal->settingExists(Journal_Notes)) {
stream.writeStartElement("note");
stream.writeTextElement("text", sess->settings[Journal_Notes].toString());
stream.writeEndElement(); // notes
if (!havedata) {
// No data to archive.
continue ;
}
//QString dateStr = ((++count & 1)==0) ? date.toString(/*Qt::ISODate*/) : date.toString(Qt::ISODate) ;
QString dateStr =date.toString(Qt::ISODate) ;
stream.writeStartElement("day");
stream.writeAttribute("date", dateStr);
if(!weight.isEmpty()) stream.writeAttribute(WEIGHT, weight);
if(!zombie.isEmpty()) stream.writeAttribute(ZOMBIE, zombie);
stream.writeAttribute("lastupdated", lastupdated);
if (journal->settingExists(Bookmark_Start)) {
QVariantList start=sess->settings[Bookmark_Start].toList();
QVariantList end=sess->settings[Bookmark_End].toList();
QStringList notes=sess->settings[Bookmark_Notes].toStringList();
stream.writeStartElement("bookmarks");
int size = start.size();
for (int i=0; i< size; i++) {
stream.writeStartElement("bookmark");
stream.writeAttribute("notes",notes.at(i));
stream.writeAttribute("start",start.at(i).toString());
stream.writeAttribute("end",end.at(i).toString());
stream.writeEndElement(); // bookmark
if (!notes.isEmpty() ) {
stream.writeStartElement("note");
stream.writeTextElement("text", notes);
stream.writeEndElement(); // notes
}
stream.writeEndElement(); // bookmarks
}
if (start.size()>0) {
QVariantList end=sess->settings[Bookmark_End].toList();
QStringList notes=sess->settings[Bookmark_Notes].toStringList();
stream.writeStartElement("bookmarks");
int size = start.size();
for (int i=0; i< size; i++) {
stream.writeStartElement("bookmark");
stream.writeAttribute("notes",notes.at(i));
stream.writeAttribute("start",start.at(i).toString());
stream.writeAttribute("end",end.at(i).toString());
stream.writeEndElement(); // bookmark
}
stream.writeEndElement(); // bookmarks
}
days_saved++;
stream.writeEndElement(); // day
} while (date <= last);
// //stream.writeAttribute("DaysSaved", QString::number(days_saved));
stream.writeEndElement(); // Journal
stream.writeEndElement(); // OSCAR
@ -302,7 +156,7 @@ void BackupJournal(QString filename)
if (!file.open(QIODevice::WriteOnly)) {
qWarning() << "Couldn't open journal file" << filename << "error code" << file.error() << file.errorString();
return;
return false;
}
QTextStream ts(&file);
@ -310,23 +164,263 @@ void BackupJournal(QString filename)
ts.setGenerateByteOrderMark(true);
ts << outBuf;
file.close();
QMessageBox::information(nullptr, STR_MessageBox_Information,
QString(QObject::tr("%1 days Journal Data was saved in file %2")).arg(days_saved).arg(filename) ,
QMessageBox::Ok);
return true;
}
DayController::DayController()
{
journal = nullptr;
cpap = nullptr;
oximeter = nullptr;
}
DayController::~DayController()
{
delete journal;
void Journal::getJournal(Daily*& daily,QDate& date,Session* & journal) {
if (journal) return;
journal = daily->GetJournalSession(date,true);
if (journal) return;
journal = daily->CreateJournalSession(date);
}
void DayController::setDate(QDate date)
{
if (journal) {
delete journal;
bool Journal::RestoreDay (QDomElement& dayElement,QDate& date,QString& filename) {
Daily* daily = mainwin->getDaily();
if (!daily) return false;
Session* journal = nullptr;
bool changed = false;
// handle zombie - feelings
bool ok = false;
int zombie = 0;
zombie = (dayElement.attribute(ZOMBIE)).toInt(&ok);
if (!ok) { zombie=0; }
if (zombie == 0 ) {
zombie = (dayElement.attribute(OLD_ZOMBIE)).toInt(&ok);
if (!ok) { zombie=0; }
}
journal = new JournalEntry(date);
DEBUGFC O("\n\n") ;
DEBUGFC O(date) O(filename); Q_UNUSED(filename);
if (zombie>0) {
int jvalue = 0 ;
getJournal(daily,date,journal);
if (journal->settings.contains(Journal_ZombieMeter)) {
jvalue = journal->settings[Journal_ZombieMeter].toInt();
}
if (jvalue == 0) {
DEBUGFC O(date) Q(zombie);
daily->set_JournalZombie(date,zombie);
if (date == daily->getDate()) daily->set_ZombieUI(zombie);
changed = true;
}
}
// handle Weight
double weight = (dayElement.attribute(WEIGHT)).toDouble(&ok);
if (weight>zeroD) {
getJournal(daily,date,journal);
double jvalue = 0.0 ;
if (journal->settings.contains(Journal_Weight)) {
jvalue = journal->settings[Journal_Weight].toDouble();
}
if (jvalue < zeroD ) {
DEBUGFC O(date) Q(weight);
daily->set_JournalWeightValue(date,weight);
if (date == daily->getDate()) daily->set_WeightUI(weight);
changed = true;
}
}
// Handle Notes.
QDomElement noteText = dayElement.elementsByTagName("note").at(0).toElement().elementsByTagName("text").at(0).toElement();
if (!noteText.text().isEmpty() ) {
getJournal(daily,date,journal);
// there are characters in notes. maybe just spaces. Ignore spaces.
QString plainTextToAdd = Daily::convertHtmlToPlainText(noteText.text());
// get existing note if any.
QString currNoteHtml = journal->settings[Journal_Notes].toString();
QString currNotePlainText = Daily::convertHtmlToPlainText(currNoteHtml);
if (currNotePlainText.contains(plainTextToAdd) ) {
// plainText to add is equal to curr or is it a subset of the current Note
// use the current notes.. ignore text in backup.
} else {
// plainText is not equal to curr nor is it a subset of the current Note
if (plainTextToAdd.contains(currNotePlainText) ) {
//curr note is a subset of the new - so use new.
currNoteHtml = noteText.text();
} else {
// ToAdd text and Current text are different.
// use previous verson append with current
currNoteHtml.prepend(noteText.text());
}
daily->set_JournalNotesHtml(date,currNoteHtml);
if (date == daily->getDate()) daily->set_NotesUI(noteText.text());
DEBUGFC O(date) Q((void*)journal) O( )Daily::convertHtmlToPlainText(currNoteHtml);
changed = true;
}
}
QDomNodeList bookmarks = dayElement.elementsByTagName("bookmarks").at(0).toElement().elementsByTagName("bookmark");
if (bookmarks.size()>0) {
DEBUGFC Q(bookmarks.size());
getJournal(daily,date,journal);
// get list of bookmarks for journal. These will not be removed.
QVariantList start;
QVariantList end;
QStringList notes;
if (journal->settings.contains(Bookmark_Start)) {
//DEBUGFC;
start=journal->settings[Bookmark_Start].toList();
end=journal->settings[Bookmark_End].toList();
notes=journal->settings[Bookmark_Notes].toStringList();
}
// check if arcived bookmark is current list
bool bmChanged = false;
for (int idx=0 ; idx < bookmarks.size() ; idx++) {
// get archived bookmark
//DEBUGFC Q(idx) Q(bookmarks.size()) Q(start.size()) ;
QDomElement bookmark = bookmarks.at(idx).toElement();
qint64 archiveStart = bookmark.attribute("start").toLongLong();
qint64 archiveEnd = bookmark.attribute("end").toLongLong();
QString archiveNote = bookmark.attribute("notes");
// check if bookmark already exists.
bool duplicate = false;
bool bNoteChanged = false;
for (int idy=0 ; idy < start.size() ; idy++) {
//DEBUGFC Q(idy);
qint64 bmStart = start.at(idy).toLongLong();
qint64 bmEnd = end.at(idy).toLongLong();
if ( (bmStart == archiveStart) && (bmEnd == archiveEnd) ) {
duplicate = true;
//DEBUGFC Q(idx) Q(idy);
// have same bookmark - new check if notes need merging
QString aNote = archiveNote.simplified();
QString bmNote = notes.at(idy);
QString bNote = bmNote.simplified();
DEBUGFC Q(aNote) Q(bNote) Q(bNote.contains(aNote)) Q(aNote.contains(bNote));
if (bNote.contains(aNote) ) {
// no action needed.
//DEBUGFC Q(idx) Q(idy) Q(bNote);;
break;
} else {
// updated existing bookmark label
//DEBUGFC Q(idx) Q(idy);
// if an append is needed.
if (aNote.contains(bNote)) {
// use archived note
//DEBUGFC Q(idx) Q(idy);
} else {
//DEBUGFC Q(idx) Q(idy);
// prepend archive note to bmNote
archiveNote.append(" :: ").append(bmNote);
}
// use archiveNote.
notes[idy]= archiveNote;
bmChanged = true;
bNoteChanged = true;
}
}
}
if (!duplicate) {
DEBUGFC Q(date) Q(idx) Q(archiveNote);
// here if need to add archive bookmark.
// add archive bookmark to currrent list
start.push_back(archiveStart);
end.push_back(archiveEnd);
notes.push_back(archiveNote);
bmChanged = true;
} else if (bNoteChanged) {
DEBUGFC Q(date) Q(idx) Q(archiveNote);
}
}
if (bmChanged) {
//DEBUGFC Q(bmChanged);
getJournal(daily,date,journal);
journal->settings[Bookmark_Start]=start;
journal->settings[Bookmark_End]=end;
journal->settings[Bookmark_Notes]=notes;
if (date == daily->getDate()) daily->set_BookmarksUI(start,end,notes,0);
} else {
DEBUGFC O("bookmark ignored") ;
}
}
if (!journal) {
return true;
}
if (!journal->machine()) {
return true;
}
if (changed) {
journal->SetChanged(true);
journal->settings[LastUpdated] = QDateTime::currentDateTime();
journal->machine()->SaveSummaryCache();
journal->SetChanged(false);
}
DEBUGFC O(date) O("\n\n");
return true;
}
bool Journal::RestoreJournal(QString filename)
{
QFile file(filename);
if (!file.open(QFile::ReadOnly)) {
qWarning() << "Could not open" << filename.toLocal8Bit().data() << "for reading, error code" << file.error() << file.errorString();
return false;
}
QDomDocument doc("machines.xml");
if (!doc.setContent(&file)) {
qWarning() << "Invalid XML Content in" << filename.toLocal8Bit().data();
return false;
}
file.close();
QDomElement root = doc.documentElement(); // Get the root element of the document
if (root.isNull()) {
return false;
}
QDomNodeList days = doc.elementsByTagName("day");
if (days.isEmpty()) {
return false;
}
QDate first = p_profile->FirstDay();
QDate last = p_profile->LastDay();
QDate current = QDate::currentDate();
//int used=0;
for (int idx=0 ; idx < days.size() ; idx++) {
QDomElement dayElement = days.at(idx).toElement();
QString dateStr = dayElement.attribute("date") ;
QDate date = QDate::fromString(dateStr,Qt::ISODate) ;
if (!date.isValid()) {
QDate newdate = QDate::fromString(dateStr) ; // read original date format
date = newdate;
}
if (!date.isValid()) {
continue;
}
if (date < first) {
continue;
}
if (date > last) {
continue;
}
if (date > current) {
continue;
}
if ( RestoreDay(dayElement,date,filename) ) {
//used++;
}
}
double user_height_cm = p_profile->user->height();
if (user_height_cm<zeroD) {
QDomElement journal = root.elementsByTagName("Journal").at(0).toElement();
double height_cm = journal.attribute("height_cm").toDouble();
DEBUGFC Q(journal.tagName()) Q(height_cm);
if (height_cm>=zeroD) p_profile->user->setHeight(height_cm);
}
return true;
}

View File

@ -1,7 +1,7 @@
/* SleepLib Journal Implementation
*
* Copyright (c) 2019-2024 The OSCAR Team
* Copyright (C) 2011-2018 Mark Watkins
* Copyright (C) 2011-2018 Mark Watkins
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of the source code
@ -11,72 +11,22 @@
#ifndef JOURNAL_H
#define JOURNAL_H
class Session;
#include <QString>
#include <QDate>
#include <QDomDocument>
#include "daily.h"
#include "SleepLib/profiles.h"
void BackupJournal(QString filename);
class Bookmark {
class Journal {
public:
Bookmark() {
start = end = 0;
}
Bookmark(const Bookmark & copy) {
start = copy.start;
end = copy.end;
notes = copy.notes;
}
Bookmark& operator=(const Bookmark & other) = default;
Bookmark(qint64 start, qint64 end, QString notes):
start(start), end(end), notes(notes) {}
qint64 start;
qint64 end;
QString notes;
};
class JournalEntry
{
public:
JournalEntry(QDate date);
~JournalEntry();
bool Save();
QString notes();
void setNotes(QString notes);
EventDataType weight();
void setWeight(EventDataType weight);
int zombie();
void setZombie(int zombie);
QList<Bookmark> & getBookmarks();
void addBookmark(qint64 start, qint64 end, QString note);
void delBookmark(qint64 start, qint64 end);
protected:
QDate m_date;
QList<Bookmark> bookmarks;
Day * day;
Session * session;
bool newsession;
};
void BackupJournal(QString filename);
class DayController
{
DayController();
~DayController();
void setDate(QDate date);
QDate m_date;
JournalEntry * journal;
Day * cpap;
Day * oximeter;
enum { JRNL_Zombie = 1 , JRNL_Weight = 2 , JRNL_Notes = 4 , JRNL_Bookmarks = 8 };
static bool BackupJournal(QString filename);
static bool RestoreJournal(QString filename);
private:
constexpr static double zeroD = 0.0001;
static void getJournal(Daily*& daily,QDate& date,Session* & journal);
static bool RestoreDay (QDomElement& dayElement,QDate& date,QString& filename) ;
};
#endif // JOURNAL_H

View File

@ -7,6 +7,9 @@
* License. See the file COPYING in the main directory of the source code
* for more details. */
#define TEST_MACROS_ENABLEDoff
#include <test_macros.h>
#include <QDateTime>
#include <QTimeZone>
#include <QDebug>
@ -305,6 +308,11 @@ bool EDFInfo::ParseSignalData() {
for (int j=0;j<sig.sampleCnt;j++) { // Big endian safe
qint16 t=Read16();
sig.dataArray[recNo*sig.sampleCnt+j]=t;
// c++ macros IF DEBUGFC Q QQ will expand when TEST_MACROS_ENABLED is enabled
// Displays the first entry in an edf signal when data is valid (not all ones).
IF ( (j==0) && (t !=-1) ) {
DEBUGFC Q(&sig) QQ(rec,recNo) QQ(Cnt,sig.sampleCnt) QQ(off,j) QQ(dat,t) QQ(lab,sig.label);
}
}
}
}

View File

@ -669,8 +669,9 @@ void parseModel(MachineInfo & info, const QString & modelnum)
info.series = series;
}
bool PRS1Loader::PeekProperties(const QString & filename, QHash<QString,QString> & props)
bool PRS1Loader::PeekProperties(const QString & filePath, QHash<QString,QString> & props)
{
QString filename = filePath;
const static QMap<QString,QString> s_longFieldNames = {
// CF?
{ "SN", "SerialNumber" },
@ -696,7 +697,22 @@ bool PRS1Loader::PeekProperties(const QString & filename, QHash<QString,QString>
{ "DFN", "DFileNum" }, // number of .003 files in the D directory
{ "VC", "ValidCheck" },
};
#if 1
// fix enpty PROP.TXT file problem. use PROP.BAK if it exists
// Otherwise import will fail.
// Just readis bak file instead of prop.txt. No other changes.
QFileInfo fi(filename);
if (fi.isFile() && fi.size()==0 && fi.suffix().toUpper() == "TXT") {
QString newFilePath = fi.absolutePath() + "/" + fi.completeBaseName() + ".BAK";
fi = QFileInfo(newFilePath);
if (fi.isFile() && fi.size()>0) {
filename = newFilePath;
}
}
// END fix enpty PROP.TXT file problem. use PROP.BAK if it exists
#endif
QFile f(filename);
if (!f.open(QFile::ReadOnly)) {
return false;

View File

@ -64,7 +64,7 @@ void ResmedLoader::LogUnexpectedMessage(const QString & message)
m_importMutex.unlock();
}
static const QVector<int> AS11TestedModels {39463, 39420, 39421, 39423, 39483, 39485, 39517, 0};
static const QVector<int> AS11TestedModels {39463, 39420, 39421, 39423, 39483, 39485, 39517, 39520, 39494, 39491, 0};
ResmedLoader::ResmedLoader() {
#ifndef UNITTEST_MODE
@ -118,10 +118,10 @@ void ResmedLoader::initChannels()
chan->addOption(0, QObject::tr("CPAP"));
chan->addOption(1, QObject::tr("APAP"));
chan->addOption(2, QObject::tr("BiPAP-T"));
chan->addOption(3, QObject::tr("BiPAP-S"));
chan->addOption(4, QObject::tr("BiPAP-S/T"));
chan->addOption(5, QObject::tr("BiPAP-T"));
chan->addOption(2, QObject::tr("BiLevel-T"));
chan->addOption(3, QObject::tr("BiLevel-S"));
chan->addOption(4, QObject::tr("BiLevel-S/T"));
chan->addOption(5, QObject::tr("BiLevel-T"));
chan->addOption(6, QObject::tr("VPAPauto"));
chan->addOption(7, QObject::tr("ASV"));
chan->addOption(8, QObject::tr("ASVAuto"));
@ -1413,10 +1413,15 @@ bool ResmedLoader::ProcessSTRfiles(Machine *mach, QMap<QDate, STRFile> & STRmap,
R.maskevents = maskeventcount->dataArray[rec];
CPAPMode mode = MODE_UNKNOWN;
IF (AS_eleven)
DEBUGFC Q(AS_eleven) Q(mode) Q(CPAP_Mode) Q(MODE_CPAP) Q((void*)str.lookupSignal(CPAP_Mode)) O("___________________________________");
if ((sig = str.lookupSignal(CPAP_Mode))) {
int mod = EventDataType(sig->dataArray[rec]) * sig->gain + sig->offset;
R.rms9_mode = mod;
// Convert AirCurve 11 and AirSense 11 to appropiate resmed 10 modes.
DEBUGFC Q(rec) Q(sig->label) Q(sig->transducer_type);
DEBUGFC Q(mod) O("=") Q(sig->dataArray[rec]) O("*") Q(sig->gain) Q("+") Q(sig->offset);
if ( AS_eleven ) { // translate AS11 mode values back to S9 / AS10 values
switch ( mod ) {
case 0:
@ -1431,6 +1436,12 @@ bool ResmedLoader::ProcessSTRfiles(Machine *mach, QMap<QDate, STRFile> & STRmap,
case 3:
R.rms9_mode = 0; // make it be CPAP
break;
case 7: // Added for ASV .
case 8: // Added for vAuto .
//case 9:
//case 10:
//case 11: // will 11 (A4Her) ever be generated by AS/AC 11?
break; // no change these are the same as in aircurve 10
default:
R.rms9_mode = 16; // unknown for now
break;
@ -1866,7 +1877,7 @@ bool ResmedLoader::ProcessSTRfiles(Machine *mach, QMap<QDate, STRFile> & STRmap,
R.s_SmartStop = EventDataType(sig->dataArray[rec]) * sig->gain + sig->offset;
if ( AS_eleven )
R.s_SmartStop--;
qDebug() << "SmartStop is set to" << R.s_SmartStop;
//qDebug() << "SmartStop is set to" << R.s_SmartStop;
}
if ((sig = str.lookupLabel("S.HumEnable"))) {
R.s_HumEnable = EventDataType(sig->dataArray[rec]) * sig->gain + sig->offset;
@ -1888,7 +1899,7 @@ bool ResmedLoader::ProcessSTRfiles(Machine *mach, QMap<QDate, STRFile> & STRmap,
R.s_Tube = EventDataType(sig->dataArray[rec]) * sig->gain + sig->offset;
}
if ((R.rms9_mode >= 2) && (R.rms9_mode <= 5)) { // S, ST, or T modes
qDebug() << "BiLevel Mode found" << R.rms9_mode;
//qDebug() << "BiLevel Mode found" << R.rms9_mode;
if (R.rms9_mode == 3) { // S mode only
if ((sig = str.lookupLabel("S.EasyBreathe"))) {
R.s_EasyBreathe = EventDataType(sig->dataArray[rec]) * sig->gain + sig->offset;
@ -1919,19 +1930,19 @@ bool ResmedLoader::ProcessSTRfiles(Machine *mach, QMap<QDate, STRFile> & STRmap,
qDebug() << "vAuto mode found" << 6;
if ((sig = str.lookupLabel("S.Cycle"))) {
R.s_Cycle = EventDataType(sig->dataArray[rec]) * sig->gain + sig->offset;
qDebug() << "Cycle" << R.s_Cycle;
// qDebug() << "Cycle" << R.s_Cycle;
}
if ((sig = str.lookupLabel("S.Trigger"))) {
R.s_Trigger = EventDataType(sig->dataArray[rec]) * sig->gain + sig->offset;
qDebug() << "Trigger" << R.s_Trigger;
// qDebug() << "Trigger" << R.s_Trigger;
}
if ((sig = str.lookupLabel("S.TiMax"))) {
R.s_TiMax = EventDataType(sig->dataArray[rec]) * sig->gain + sig->offset;
qDebug() << QString("TiMax %1").arg( R.s_TiMax, 0, 'f', 1);
// qDebug() << QString("TiMax %1").arg( R.s_TiMax, 0, 'f', 1);
}
if ((sig = str.lookupLabel("S.TiMin"))) {
R.s_TiMin = EventDataType(sig->dataArray[rec]) * sig->gain + sig->offset;
qDebug() << QString("TiMin %1").arg( R.s_TiMin, 0, 'f', 1);
// qDebug() << QString("TiMin %1").arg( R.s_TiMin, 0, 'f', 1);
}
}
if ( R.min_pressure == 0 ) {
@ -3571,9 +3582,10 @@ void ResmedLoader::ToTimeDelta(Session *sess, ResMedEDFInfo &edf, EDFSignal &es,
el->AddEvent(tt, c);
if (forceDebug && ((code == CPAP_Pressure) || (code == CPAP_IPAP) || (code == CPAP_EPAP)) )
qDebug() << "Last Event:" << tmp << QDateTime::fromMSecsSinceEpoch(tt).toString() << "Pos:" << (sptr-1) - es.dataArray;
} else
} else {
qDebug() << "Failed to add last event - Code:" << QString::number(code, 16) << "Value:" << tmp <<
QDateTime::fromMSecsSinceEpoch(tt).toString() << "Pos:" << (sptr-1) - es.dataArray;
}
sess->updateMin(code, min);
sess->updateMax(code, max);

View File

@ -688,6 +688,8 @@ bool SleepStyleLoader::OpenSummary(Machine *mach, const QString & filename)
if (ts == 0xffffffff) {
#ifdef DEBUGSS
qDebug() << "SS SUM 0xffffffff terminator found at block" << nblock;
#else
Q_UNUSED(nblock);
#endif
break;
}
@ -996,6 +998,8 @@ bool SleepStyleLoader::OpenDetail(Machine *mach, const QString & filename)
#ifdef DEBUGSS
qDebug() << "SS DET pressure events" << PR->count() << "prSessVount" << PRSessCount << "beginning" << QDateTime::fromSecsSinceEpoch(ti/1000).toString("MM/dd/yyyy hh:mm:ss");
#else
Q_UNUSED(PRSessCount);
#endif
// Update indexes, process waveform and perform flagging
sess->setSummaryOnly(false);

View File

@ -21,6 +21,7 @@
#include <QMessageBox>
#include "viatom_loader.h"
#include "SleepLib/machine.h"
#include <memory>
// TODO: Merge this with PRS1 macros and generalize for all loaders.
#define SESSIONID m_session->session()
@ -127,8 +128,35 @@ Session* ViatomLoader::ParseFile(const QString & filename, bool *existing)
return nullptr;
}
ViatomFile v(file);
if (v.ParseHeader() == false) {
// Read in Viatom database version number
QByteArray data = file.read(2);
if (data.size() < 2) {
qDebug() << filename << "too short for a Viatom data file";
return nullptr;
}
const unsigned char* header = (const unsigned char*) data.constData();
int sig = header[0] | (header[1] << 8);
std::unique_ptr<ViatomFile> v = nullptr;
switch (sig) {
case 0x0003:
case 0x0005:
v = std::unique_ptr<ViatomFile>(new ViatomFile(file));
break;
case 0x0301:
v = std::unique_ptr<O2RingS>(new O2RingS(file));
break;
default:
qDebug() << filename << "Unrecognized DB version number in Viatom data file" << sig;
return nullptr;
}
if (!file.seek(0)) {
qDebug() << filename << "unable to seek to begining of file";
return nullptr;
}
// Parse header specific to database version number
if (v->ParseHeader() == false) {
return nullptr;
}
@ -144,7 +172,7 @@ Session* ViatomLoader::ParseFile(const QString & filename, bool *existing)
}
Machine *mach = p_profile->CreateMachine(info);
if (mach->SessionExists(v.sessionid())) {
if (mach->SessionExists(v->sessionid())) {
// Skip already imported session
//qDebug() << filename << "session already exists, skipping" << v.sessionid();
if (existing) {
@ -154,12 +182,12 @@ Session* ViatomLoader::ParseFile(const QString & filename, bool *existing)
return nullptr;
}
qint64 time_ms = v.timestamp();
m_session = new Session(mach, v.sessionid());
qint64 time_ms = v->timestamp();
m_session = new Session(mach, v->sessionid());
m_session->set_first(time_ms);
QList<ViatomFile::Record> records = v.ReadData();
m_step = v.duration() / records.size() * 1000L;
QList<ViatomFile::Record> records = v->ReadData();
m_step = v->duration() / records.size() * 1000L;
// Import data
for (auto & rec : records) {
@ -267,6 +295,20 @@ ViatomFile::ViatomFile(QFile & file) : m_file(file)
{
}
QDateTime ViatomFile::getFilenameTimestamp()
{
QString date_string = QFileInfo(m_file).fileName().section("_", -1); // Strip any SleepU_ etc. prefix.
int lastPoint = date_string.lastIndexOf("."); // Added to strip off any filename extension
date_string = date_string.left(lastPoint);
QString format_string = "yyyyMMddHHmmss";
if (date_string.contains(":")) {
format_string = "yyyy-MM-dd HH:mm:ss";
}
return QDateTime::fromString(date_string, format_string);
}
bool ViatomFile::ParseHeader()
{
static const int HEADER_SIZE = 40;
@ -312,17 +354,7 @@ bool ViatomFile::ParseHeader()
// starting timestamp). Technically these should probably be square charts, but
// the code currently forces them to be non-square.
QDateTime data_timestamp = QDateTime(QDate(year, month, day), QTime(hour, min, sec));
QString date_string = QFileInfo(m_file).fileName().section("_", -1); // Strip any SleepU_ etc. prefix.
int lastPoint = date_string.lastIndexOf("."); // Added to strip off any filename extension
date_string = date_string.left(lastPoint);
QString format_string = "yyyyMMddHHmmss";
if (date_string.contains(":")) {
format_string = "yyyy-MM-dd HH:mm:ss";
}
QDateTime filename_timestamp = QDateTime::fromString(date_string, format_string);
QDateTime filename_timestamp = getFilenameTimestamp();
if (filename_timestamp.isValid()) {
if (filename_timestamp != data_timestamp) {
// TODO: Once there's a better/easier way to adjust session times within OSCAR, we can remove the below.
@ -462,3 +494,57 @@ QList<ViatomFile::Record> ViatomFile::ReadData()
return records;
}
O2RingS::O2RingS(QFile & file) : ViatomFile(file)
{
}
bool O2RingS::ParseHeader()
{
// For the O2Ring S, the header only contains the signature
// Additional metadata is stored at the end of the file
// The record count is stored 36 bytes prior to EOF
int record_count_loc = m_file.size() - 36;
if (record_count_loc < 0 || !m_file.seek(record_count_loc)) {
qDebug() << m_file.fileName() << "error locating Viatom record count";
return false;
}
// read record count as a 2-byte little endian value
// max number of records in a O2Ring S file is 36000
QDataStream in(m_file.read(2));
in.setByteOrder(QDataStream::LittleEndian);
quint16 record_count;
in >> record_count;
m_sig = 0x0301;
m_record_count = m_duration = record_count;
m_timestamp = getFilenameTimestamp().toMSecsSinceEpoch();
m_sessionid = m_timestamp / 1000L;
m_resolution = 1000;
// advance past the header
return m_file.seek(10);
}
QList<ViatomFile::Record> O2RingS::ReadData()
{
QList<ViatomFile::Record> records;
// Read all Pulse, SPO2 and Motion data
// 0xFF for spo2 or hr indicates an interruption in measurement
// Vibration data is likely stored in a variable length block following the
// fixed-width pulse/SPO2/motion data. Zero out for now since OSCAR doesn't
// use this data.
QDataStream in(m_file.readAll());
do {
ViatomFile::Record rec;
in >> rec.spo2 >> rec.hr >> rec.motion;
rec.oximetry_invalid = (rec.spo2 == 0xFF || rec.hr == 0xFF) ? 0xFF : 0;
rec.vibration = 0;
records.append(rec);
} while (records.size() < m_record_count);
// Confirm that we have a 1s sample rate
CHECK_VALUE(duration() / records.size(), 1);
return records;
}

View File

@ -71,13 +71,14 @@ public:
unsigned char vibration;
};
ViatomFile(QFile & file);
~ViatomFile() = default;
virtual ~ViatomFile() = default;
bool ParseHeader();
QList<Record> ReadData();
virtual bool ParseHeader();
virtual QList<Record> ReadData();
SessionID sessionid() const { return m_sessionid; }
quint64 timestamp() const { return m_timestamp; }
int duration() const { return m_duration; }
QDateTime getFilenameTimestamp();
protected:
static const int RECORD_SIZE = 5;
@ -90,4 +91,13 @@ protected:
SessionID m_sessionid;
};
class O2RingS : public ViatomFile
{
public:
O2RingS(QFile & file);
~O2RingS() = default;
bool ParseHeader();
QList<Record> ReadData();
};
#endif // VIATOMLOADER_H

View File

@ -1145,7 +1145,7 @@ bool Machine::SaveSummaryCache()
bool Machine::Save()
{
//int size;
int cnt = 0;
// int cnt = 0;
QString path = getDataPath();
QDir dir(path);
@ -1160,7 +1160,7 @@ bool Machine::Save()
// store any event summaries..
for (s = sessionlist.begin(); s != sessionlist.end(); s++) {
cnt++;
// cnt++;
if ((*s)->IsChanged()) {
queTask(new SaveTask(*s, this));

View File

@ -316,7 +316,7 @@ bool compressFile(QString infile, QString outfile)
int MachineLoader::Open(const QStringList & paths)
{
int i, skipped = 0;
int i = 0;
int size = paths.size();
for (i=0; i < size; i++) {
if (isAborted()) {
@ -328,10 +328,6 @@ int MachineLoader::Open(const QStringList & paths)
if (res < 0) {
break;
}
if (res == 0) {
// Should we report on skipped count?
skipped++;
}
emit setProgressValue(i+1);
QCoreApplication::processEvents();
}

View File

@ -1151,16 +1151,8 @@ void Scan()
// validate user name in profile.
QString dbname = prof->user->userName();
if (dbname.isEmpty()) {
qWarning() << "Not a Profile " << npath;
delete prof;
continue; // skip over this folder. it is not a profile.
}
QString fname = QFileInfo(fi).fileName();
if (fname != dbname) {
// this condition currently causes an infinite loop - causes oscar issue.
// one solution is to avoid putting this profile in profiles MAP.
// the other solution is to update userName with its new name.
prof->user->setUserName(fname);
QString message = QString("%1 %2 %3 %4").arg("Changing Profile Name").arg(dbname).arg("==>").arg(fname);
qDebug() << message;
@ -1178,7 +1170,7 @@ void Scan()
}
// Update profiles.xml for mobile version
// profiles.xml is never read so it does not need to be saved.
// saveProfileList();
// saveProfileList();
}

View File

@ -400,7 +400,7 @@ void done()
// ahiChannels did not get cleared since day1 OSCAR when a reset was required.
// when reset occured then the Overview AHI graph would should an addtional set of channels.
// this fix just clears the variable that stores ahi data.
// probelm #59 https://gitlab.com/pholy/OSCAR-code/-/issues/59
// probelm #59 https://gitlab.com/.../OSCAR-code/-/issues/59
ahiChannels.clear();
schema_initialized = false;

View File

@ -1,5 +1,5 @@
// Update the string below to set OSCAR's version and release status.
// See https://semver.org/spec/v2.0.0.html for details on format.
#define VERSION "1.5.2-beta-2"
#define VERSION "1.5.3"

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,7 @@
#include <QScrollBar>
#include <QTableWidgetItem>
#include <QTextBrowser>
#include <QBitArray>
#include "SleepLib/profiles.h"
#include "mainwindow.h"
@ -47,6 +48,7 @@ class Daily : public QWidget
{
Q_OBJECT
friend class Journal;
public:
/*! \fn Daily()
\brief Constructs a Daily object
@ -112,7 +114,7 @@ public:
\param QDate date
\returns Session * containing valid Journal Session object or nullptr if none found.
*/
Session * GetJournalSession(QDate date);
Session * GetJournalSession(QDate date, bool create=true);
QString GetDetailsText();
/*! \fn eventBreakdownPie()
@ -149,7 +151,7 @@ public:
QString STR_SHOW_ALL_EVENTS =QString(tr("Show All Events"));
QString STR_HIDE_ALL_GRAPHS =QString(tr("Hide All Graphs"));
QString STR_SHOW_ALL_GRAPHS =QString(tr("Show All Graphs"));
static QString convertHtmlToPlainText(QString html) ;
public slots:
void on_LineCursorUpdate(double time);
void on_RangeUpdate(double minx, double maxx);
@ -230,11 +232,13 @@ private slots:
*/
void on_removeBookmarkButton_clicked();
/*! \fn on_bookmarkTable_itemClicked(QTableWidgetItem *item);
/*! \fn on_bookmarkTable_currentItemChanged(QTableWidgetItem *item, QTableWidgetItem *previous)
\brief Called when a bookmark has been selected.. Zooms in on the area
\param QTableWidgetItem *item
\param QTableWidgetItem *previous
*/
void on_bookmarkTable_itemClicked(QTableWidgetItem *item);
void on_bookmarkTable_currentItemChanged(QTableWidgetItem *current, QTableWidgetItem *previous);
/*! \fn on_bookmarkTable_itemChanged(QTableWidgetItem *item);
\brief Called when bookmarks have been altered.. Saves the bookmark list to Journal object.
@ -251,9 +255,11 @@ private slots:
*/
void on_ZombieMeter_valueChanged(int value);
void set_ZombieMeterLabel();
void set_ZombieUI(int value);
void set_WeightUI(double weight_kg);
void set_BmiUI(Session *journal = nullptr);
void set_BmiUI(double weight_kg); // should be a part of weight.
void set_NotesUI(QString htmlNote);
void set_BookmarksUI( QVariantList& start , QVariantList& end , QStringList& notes, qint64 drift=0);
/*! \fn on_weightSpinBox_editingFinished();
\brief Called when weight has changed.. Updates the BMI dislpay and journal objects.
@ -283,6 +289,11 @@ protected:
virtual void showEvent(QShowEvent *);
private:
double calculateBMI(double weight_kg, double height_cm);
void set_JournalZombie(QDate&, int);
void set_JournalWeightValue(QDate&, double kgs);
void set_JournalNotesHtml(QDate&, QString html);
/*! \fn CreateJournalSession()
\brief Create a new journal session for this date, if one doesn't exist.
\param QDate date
@ -322,7 +333,7 @@ private:
DailySearchTab* dailySearchTab = nullptr;
//QString getLeftAHI (Day * day);
QString getAHI (Day * day, bool isBrick);
QString getSessionInformation(Day *);
QString getMachineSettings(Day *);
QString getStatisticsInfo(Day *);
@ -330,7 +341,7 @@ private:
QString getOximeterInformation(Day *);
QString getEventBreakdown(Day *);
QString getPieChart(float values, Day *);
//QString getIndicesAndPie(Day *, float hours, bool isBrick);
QString getIndices(Day * day, QHash<ChannelID, EventDataType>& values );
QString getSleepTime(Day *);
QString getLeftSidebar (bool honorPieChart);
@ -368,13 +379,27 @@ private:
const int eventTypeEnd = QTreeWidgetItem::UserType+2;
#ifndef REMOVE_FITNESS
bool ZombieMeterMoved;
double user_weight_kg;
double user_height_cm;
constexpr static double zeroD = 0.0001 ;
#endif
bool BookmarksChanged;
SaveGraphLayoutSettings* saveGraphLayoutSettings=nullptr;
enum LEFT_SIDEBAR { LSB_FIRST ,
LSB_MACHINE_INFO ,
LSB_SLEEPTIME_INDICES ,
LSB_PIE_CHART ,
LSB_STATISTICS ,
LSB_OXIMETER_INFORMATION ,
LSB_DEVICE_SETTINGS ,
LSB_SESSION_INFORMATION ,
LSB_END_SIZE };
QBitArray leftSideBarEnable = QBitArray(LSB_END_SIZE,true);
void htmlLsbSectionHeader (QString& html, const QString& name,LEFT_SIDEBAR checkBox) ;
void htmlLsbSectionHeaderInit (bool section=true) ;
bool htmlLsbPrevSectionHeader = true;
};
#endif // DAILY_H

View File

@ -30,6 +30,7 @@
#include "dailySearchTab.h"
#include "SleepLib/day.h"
#include "SleepLib/profiles.h"
#include "SleepLib/journal.h"
#include "daily.h"
#include "SleepLib/machine_common.h"
@ -381,25 +382,6 @@ void DailySearchTab::addCommandItem(QString str,int topic) {
commandList->setItemWidget(item, topicButton);
}
void DailySearchTab::debugStates() {
#ifdef TEST_MACROS_ENABLED
return;
qDebug() ;
for (int ind = 0; ind <commandList->count() ; ++ind) {
QListWidgetItem *item = commandList->item(ind);
QAbstractButton* topicButton = dynamic_cast<QAbstractButton*>(commandList->itemWidget(item));
if (!topicButton) continue;
int topic = buttonGroup->id(topicButton);
DEBUGFC
QQ("checkable",topicButton->isCheckable())
QQ("check",topicButton->isChecked())
O(topicButton->text())
O(topic)
;
}
#endif
}
void DailySearchTab::showOnlyAhiChannels(bool ahiOnly) {
for (int ind = 0; ind <commandList->count() ; ++ind) {
QListWidgetItem *item = commandList->item(ind);
@ -423,7 +405,6 @@ void DailySearchTab::showOnlyAhiChannels(bool ahiOnly) {
lastButton = nullptr;
lastTopic = ST_NONE ;
};
debugStates();
};
void DailySearchTab::on_matchGroupButton_toggled(QAbstractButton* topicButton ) {
@ -487,12 +468,8 @@ void DailySearchTab::populateControl() {
operationCombo->addItem(opCodeStr(OP_NE));
// Now add events
QDate date = p_profile->LastDay(MT_CPAP);
if ( !date.isValid()) return;
Day* day = p_profile->GetDay(date);
if (!day) return;
commandList->clear();
addCommandItem(tr("Journal"),ST_JOURNAL);
addCommandItem(tr("Notes"),ST_NOTES);
addCommandItem(tr("Notes containing"),ST_NOTES_STRING);
addCommandItem(tr("Bookmarks"),ST_BOOKMARKS);
@ -508,6 +485,10 @@ void DailySearchTab::populateControl() {
}
addCommandItem(tr("Number of Sessions"),ST_SESSIONS_QTY);
QDate date = p_profile->LastDay(MT_CPAP);
if ( !date.isValid()) return;
Day* day = p_profile->GetDay(date);
if (!day) return;
if (p_profile->general->showUnknownFlags()) chans |= schema::UNKNOWN;
QList<ChannelID> available;
@ -527,7 +508,6 @@ void DailySearchTab::setState(STATE newState) {
STATE prev=state;
state = newState;
//enum STATE { reset , waitForSearchTopic , matching , multpileMatches , waitForStart , autoStart , searching , endOfSeaching , waitForContinue , noDataFound};
//DEBUGFC O(prev) O("==>") O(state) Q( matches.size()) QQ("name",match->matchName) O(match->opCodeStr) O(match->compareString) O(match->units);
switch (state) {
case multpileMatches :
break;
@ -598,7 +578,6 @@ void DailySearchTab::setState(STATE newState) {
hideResults(true);
break;
};
//DEBUGFC O(prev) O("==>") O(state) Q(matchButton->isVisible()) Q(addMatchButton->isVisible()) Q( matches.size());
};
QRegExp Match::searchPatterToRegex (QString searchPattern) {
@ -850,11 +829,52 @@ bool DailySearchTab::matchFind(Match* myMatch ,Day* day, QDate& date, Qt::Alignm
myMatch->updateMinMaxValues(numDisabled);
}
break;
case ST_JOURNAL :
{
Session* journal=daily->GetJournalSession(date,false);
if (journal) {
myMatch->foundString = journal->settings[LastUpdated].toDateTime().toString();
myMatch->foundString.append(" ");
bool empty =true;
if ( journal->settings.contains(Bookmark_Start) ) {
if (journal->settings[Bookmark_Start].toList().size()>0) {
empty = false;
myMatch->foundString.append("B");
/* Not reuired.
if ( journal->settings.contains(Bookmark_Notes) ) {
if (journal->settings[Bookmark_Start].toList().size()>0) {
myMatch->foundString.append("n");
}
}
*/
}
}
if ( journal->settings.contains(Journal_Notes) ) {
myMatch->foundString.append("N");
empty = false;
}
if ( journal->settings.contains(Journal_Weight) ) {
myMatch->foundString.append("W");
empty = false;
}
if ( journal->settings.contains(Journal_ZombieMeter) ) {
myMatch->foundString.append("F");
empty = false;
}
if (empty) {
break;
myMatch->foundString.append(tr("Empty"));
}
found=true;
alignment=Qt::AlignLeft;
}
}
break;
case ST_NOTES :
{
Session* journal=daily->GetJournalSession(date);
Session* journal=daily->GetJournalSession(date,false);
if (journal && journal->settings.contains(Journal_Notes)) {
QString jcontents = convertRichText2Plain(journal->settings[Journal_Notes].toString());
QString jcontents = Daily::convertHtmlToPlainText(journal->settings[Journal_Notes].toString());
myMatch->foundString = jcontents.simplified().left(stringDisplayLen).simplified();
found=true;
alignment=Qt::AlignLeft;
@ -863,7 +883,7 @@ bool DailySearchTab::matchFind(Match* myMatch ,Day* day, QDate& date, Qt::Alignm
break;
case ST_BOOKMARKS :
{
Session* journal=daily->GetJournalSession(date);
Session* journal=daily->GetJournalSession(date,false);
if (journal && journal->settings.contains(Bookmark_Notes)) {
found=true;
QStringList notes = journal->settings[Bookmark_Notes].toStringList();
@ -877,7 +897,7 @@ bool DailySearchTab::matchFind(Match* myMatch ,Day* day, QDate& date, Qt::Alignm
break;
case ST_BOOKMARKS_STRING :
{
Session* journal=daily->GetJournalSession(date);
Session* journal=daily->GetJournalSession(date,false);
if (journal && journal->settings.contains(Bookmark_Notes)) {
QStringList notes = journal->settings[Bookmark_Notes].toStringList();
QString findStr = selectString->text();
@ -895,9 +915,9 @@ bool DailySearchTab::matchFind(Match* myMatch ,Day* day, QDate& date, Qt::Alignm
break;
case ST_NOTES_STRING :
{
Session* journal=daily->GetJournalSession(date);
Session* journal=daily->GetJournalSession(date,false);
if (journal && journal->settings.contains(Journal_Notes)) {
QString jcontents = convertRichText2Plain(journal->settings[Journal_Notes].toString());
QString jcontents = Daily::convertHtmlToPlainText(journal->settings[Journal_Notes].toString());
QString findStr = selectString->text();
if (jcontents.contains(findStr,Qt::CaseInsensitive) ) {
found=true;
@ -1147,7 +1167,6 @@ void DailySearchTab::process_match_info(QString text, int topic) {
// here to select new search criteria
// must reset all variables and label, button, etc
clearMatch() ;
//DEBUGFC QQ("name",match->matchName) O(match->opCodeStr) O(match->compareString) O(match->units) O(selectUnits->text());
commandWidget->show();
match->matchName = text;
// get item selected
@ -1189,6 +1208,11 @@ void DailySearchTab::process_match_info(QString text, int topic) {
selectInteger->setValue(0);
setoperation(OP_NO_PARMS,displayWhole);
break;
case ST_JOURNAL :
setResult(DS_ROW_HEADER,1,QDate(),tr("JUmps\nJumps to Date's Notes"));
match->nextTab = TW_NOTES ;
setoperation( OP_NO_PARMS ,displayString);
break;
case ST_NOTES :
setResult(DS_ROW_HEADER,1,QDate(),tr("Note\nJumps to Date's Notes"));
match->nextTab = TW_NOTES ;
@ -1733,12 +1757,6 @@ QString Match::formatTime (qint32 ms) {
return QString("%1:%2:%3").arg(hours).arg(minutes,2,10,QLatin1Char('0')).arg(seconds,2,10,QLatin1Char('0'));
}
QString DailySearchTab::convertRichText2Plain (QString rich) {
richText.setHtml(rich);
QString line=richText.toPlainText().simplified();
return line.replace(QRegExp("[\\s\\r\\n]+")," ").simplified();
}
QString DailySearchTab::opCodeStr(OpCode opCode) {
switch (opCode) {
case OP_LT : return "< ";

View File

@ -47,7 +47,7 @@ class Daily; //forward declaration.
enum ValueMode { invalidValueMode , notUsed , minutesToMs , hoursToMs , hundredths , opWhole , displayWhole , opString , displayString, secondsDisplayString};
enum SearchTopic { ST_NONE , ST_DAYS_SKIPPED , ST_DISABLED_SESSIONS , ST_NOTES , ST_NOTES_STRING , ST_BOOKMARKS , ST_BOOKMARKS_STRING , ST_AHI , ST_SESSION_LENGTH , ST_SESSIONS_QTY , ST_DAILY_USAGE , ST_APNEA_LENGTH , ST_APNEA_ALL , ST_CLEAR , ST_EVENT };
enum SearchTopic { ST_NONE , ST_DAYS_SKIPPED , ST_DISABLED_SESSIONS , ST_JOURNAL , ST_NOTES , ST_NOTES_STRING , ST_BOOKMARKS , ST_BOOKMARKS_STRING , ST_AHI , ST_SESSION_LENGTH , ST_SESSIONS_QTY , ST_DAILY_USAGE , ST_APNEA_LENGTH , ST_APNEA_ALL , ST_CLEAR , ST_EVENT };
enum OpCode {
//DO NOT CHANGE NUMERIC OP CODES because THESE VALUES impact compare operations.
@ -224,7 +224,6 @@ private:
bool helpMode=false;
QString helpString = helpStr();
void clearMatch();
void debugStates();
void setState(STATE);
void createUi();
void populateControl();
@ -257,7 +256,6 @@ private:
QString helpStr();
QString centerLine(QString line);
QString convertRichText2Plain (QString rich);
QRegExp searchPatterToRegex (QString wildcard);
void addCommandItem(QString str,int topic);
float commandListItemMaxWidth = 0;
@ -283,8 +281,6 @@ private:
int DaysWithFileErrors;
void setoperation(OpCode opCode,ValueMode mode) ;
QTextDocument richText;
void process_match_info(QString text, int topic);

View File

@ -7,6 +7,9 @@
* License. See the file COPYING in the main directory of the source code
* for more details. */
#define TEST_MACROS_ENABLEDoff
#include <test_macros.h>
#include <QFileDialog>
#include <QLocale>
#include <QMessageBox>
@ -85,9 +88,10 @@ void ExportCSV::on_filenameBrowseButton_clicked()
if (ui->startDate->date() != ui->endDate->date()) { timestamp += "_" + ui->endDate->date().toString(Qt::ISODate); }
timestamp += ".csv";
QString name = QFileDialog::getSaveFileName(this, tr("Select file to export to"),
p_pref->Get("{home}/") + timestamp, tr("CSV Files (*.csv)"));
QString folder = mainwin->profilePath(STR_PREF_LastExportCsvPath);
QString name = QFileDialog::getSaveFileName(this, tr("Select file to export to"),
folder + QDir::separator() + timestamp, tr("CSV Files (*.csv)"));
if (name.isEmpty()) {
ui->exportButton->setEnabled(false);
return;
@ -99,6 +103,8 @@ void ExportCSV::on_filenameBrowseButton_clicked()
ui->filenameEdit->setText(name);
ui->exportButton->setEnabled(true);
folder = QFileInfo(name).absolutePath();
mainwin->saveProfilePath(STR_PREF_LastExportCsvPath,folder);
}
void ExportCSV::on_quickRangeCombo_activated(const QString &arg1)

View File

@ -44,7 +44,7 @@ namespace HighResolution {
}
HiResolutionMode setHiResolutionMode(HiResolutionMode value) {
QString filename = GetAppData() + HI_RES_FILENAME;
QString filename = GetAppData() + QDir::separator() + HI_RES_FILENAME;
if (value == HRM_ENABLED ) {
writeMode( filename , HRM_ENABLED ,"HiResolutionMode Enabled");
return HRM_ENABLED;
@ -55,22 +55,22 @@ namespace HighResolution {
}
HiResolutionMode getHiResolutionMode() {
QString filename = GetAppData() + HI_RES_FILENAME;
QString filename = GetAppData() + QDir::separator() + HI_RES_FILENAME;
int hiResMode= readMode( filename );
return (hiResMode == HRM_ENABLED ) ? HRM_ENABLED : HRM_DISABLED ;
}
// this function is used to control the text name of the high resolution preference checkbox.
void checkBox(bool set,QCheckBox* button) {
bool checkBox(bool set,QCheckBox* button) {
if (set) {
hiResolutionNextSessionMode = button->isChecked()? HRM_ENABLED : HRM_DISABLED ;
setHiResolutionMode(hiResolutionNextSessionMode);
if ( hiResolutionOperaingMode != hiResolutionNextSessionMode ) {
QMessageBox::information(nullptr,
STR_MessageBox_Information,
QObject::tr("High Resolution Mode change will take effect when OSCAR is restarted."));
QString msg = QString("%1\n%2").arg(QObject::tr("High Resolution Mode change will take effect when OSCAR is restarted."))
.arg(QObject::tr("Restart Oscar now?") );
return QMessageBox::question(nullptr, STR_MessageBox_Question, msg, QMessageBox::No, QMessageBox::Yes) == QMessageBox::Yes;
}
return;
return false;
}
QString label;
if (hiResolutionNextSessionMode == HRM_ENABLED ) {
@ -89,6 +89,7 @@ namespace HighResolution {
button->setChecked(false);
}
button->setText(label);
return false;
}
// These functions are for main.cpp

View File

@ -19,7 +19,7 @@ namespace HighResolution {
void display(bool);
// used by preferences
void checkBox(bool set,QCheckBox* button);
bool checkBox(bool set,QCheckBox* button);
}
#endif // HIGHRESOLUTION_H

View File

@ -296,7 +296,7 @@ void optionExit(int exitCode, QString error) {
Help Menu
Option Description
-p Pauses execution for 1 second
--profile <name> Name of profile. if name does not exist then uses last used profile.
--profile <name> Name of profile. if name does not exist then uses profile tab.
--l or --language Force language prompt
--datadir <folderName> Use folderName as Oscar Data folder. For relatve paths: <Documents folder>/<relative path>.
If folder does not exist then prompts user.
@ -397,11 +397,11 @@ int main(int argc, char *argv[]) {
// selection QDialog, which waits indefinitely for user input before MainWindow is constructed.
bool force_data_dir = false;
QString load_profile = "";
QString load_profile; // null profile means no --profile param
for (int i = 1; i < args.size(); i++) {
if ((args[i] == "--language") || (args[i] == "--l") ) {
settings.setValue(LangSetting,"");
} else if ( (args[i] == "-l") || (args[i] == "-nop")){
} else if ( (args[i] == "-l") || (args[i] == "-nop") || (args[i] == "") ){
// do nothing. internal calls that current don't have any functions in main.
} else if (args[i] == "-p") {
QThread::msleep(1000);
@ -409,7 +409,8 @@ int main(int argc, char *argv[]) {
if ((i+1) < args.size())
load_profile = args[++i];
else {
optionExit(1,"Missing argument to --profile");
// Just view all profiles.
load_profile = " ";
}
} else if (args[i] == "--datadir") { // mltam's idea
QString datadir, datadirwas ;
@ -435,7 +436,7 @@ int main(int argc, char *argv[]) {
} else if (QString(args[i]).contains("help",Qt::CaseInsensitive)) {
optionExit(0,QString(""));
} else {
optionExit(3,QString("Invalid Argument. %1").arg(args[i]));
optionExit(3,QString("Invalid Argument: '%1'").arg(args[i]));
}
} // end of for args loop
@ -645,6 +646,7 @@ int main(int argc, char *argv[]) {
QString language = settings.value(LangSetting, "").toString();
AppSetting->setLanguage(language);
if (!load_profile.isEmpty()) AppSetting->setProfileName(load_profile);
// Set fonts from preferences file
qDebug() << "App font before Prefs setting" << QApplication::font();

View File

@ -1,7 +1,7 @@
/* OSCAR MainWindow Implementation
*
* Copyright (c) 2020-2024 The OSCAR Team
* Copyright (c) 2011-2018 Mark Watkins
* Copyright (c) 2011-2018 Mark Watkins
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of the source code
@ -10,7 +10,6 @@
#define TEST_MACROS_ENABLEDoff
#include <test_macros.h>
#include <QHostInfo>
#include <QFileDialog>
#include <QMessageBox>
@ -45,6 +44,9 @@
#include "common_gui.h"
#include "version.h"
#include "SleepLib/appsettings.h" // defines for REMSTAR_M_SUPPORT
#include "SleepLib/journal.h"
#include "SleepLib/common.h"
#include "notifyMessageBox.h"
// Custom loaders that don't autoscan..
@ -328,11 +330,11 @@ void MainWindow::EnableTabs(bool b)
void MainWindow::Notify(QString s, QString title, int ms)
{
QString msg = s;
if (title.isEmpty()) {
title = STR_TR_OSCAR + " " + getVersion().displayString();
}
if (systray) {
QString msg = s;
if (systray && !AppSetting->notifyMessagBoxOption()) {
#ifdef Q_OS_UNIX
// GNOME3's systray hides the last line of the displayed Qt message.
@ -346,6 +348,8 @@ void MainWindow::Notify(QString s, QString title, int ms)
#endif
systray->showMessage(title, msg, QSystemTrayIcon::Information, ms);
} else {
createNotifyMessageBox(this, title , msg, (ms+999)/1000);
}
}
@ -1641,6 +1645,7 @@ void MainWindow::reloadProfile()
void MainWindow::RestartApplication(bool force_login, QString cmdline)
{
qDebug() << "Restarting OSCAR";
CloseProfile();
p_pref->Save();
@ -2269,9 +2274,34 @@ void MainWindow::on_actionChange_Data_Folder_triggered()
RestartApplication(false, "-d");
}
QString MainWindow::profilePath(QString folderProfileName ) {
QString folderName;
if (p_profile->contains(folderProfileName)) {
folderName = (*p_profile)[folderProfileName].toString();
QFileInfo fi(folderName);
if (fi.exists() && fi.isDir()) {
return folderName;
}
}
QStringList paths = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation);
if (paths.size()>1) folderName = paths[0];
return folderName;
}
void MainWindow::saveProfilePath(QString folderProfileName , QString pathName) {
(*p_profile)[folderProfileName] = pathName;
}
void MainWindow::importNonCPAP(MachineLoader &loader)
{
// get save location from profile.
QDir folder = QDir(profilePath(STR_PREF_LastOximetryPath));
QFileDialog w;
if (folder.exists() ) {
w.setDirectory(folder);
}
w.setFileMode(QFileDialog::ExistingFiles);
w.setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint);
w.setOption(QFileDialog::ShowDirsOnly, false);
@ -2285,6 +2315,7 @@ void MainWindow::importNonCPAP(MachineLoader &loader)
ProgressDialog progress(this);
if (w.exec() == QFileDialog::Accepted) {
saveProfilePath(STR_PREF_LastOximetryPath,w.directory().absolutePath());
QStringList files = w.selectedFiles();
int size = files.size();
if (size > 1) {
@ -2323,6 +2354,15 @@ void MainWindow::importNonCPAP(MachineLoader &loader)
progress.close();
QCoreApplication::processEvents();
}
if (res < 0) {
// res is used as an index to an array and will cause a crash if not handled.
// Negative numbers indicate a problem with the file format or the file does not exist.
//QString fileName = QFileInfo(files[0]).fileName();
QString msg = QString(tr("There was a problem parsing %1 \nData File: %2")
.arg(name, QFileInfo( files[0]).fileName() ) );
//QString msg = QString(tr("There was a problem parsing %1 \nData File: %2") .arg(name, fileName) );
Notify(msg,"",20*1000 /* convert sec to ms */);
} else
if (res == 0) {
Notify(tr("There was a problem opening %1 Data File: %2").arg(name, files[0]));
return;
@ -2400,7 +2440,7 @@ void MainWindow::on_statisticsButton_clicked()
}
}
void MainWindow::init_reportModeUi()
void MainWindow::init_reportModeUi()
{
QTextCharFormat format = ui->statStartDate->calendarWidget()->weekdayTextFormat(Qt::Saturday);
format.setForeground(QBrush(Qt::black, Qt::SolidPattern));
@ -2607,19 +2647,45 @@ void MainWindow::on_actionShowPersonalData_toggled(bool visible)
}
}
#include "SleepLib/journal.h"
void MainWindow::on_actionImport_Journal_triggered()
{
QString filename = QFileDialog::getOpenFileName(this,
tr("Choose where to read journal"),
profilePath(STR_PREF_LastJournalPath),
tr("XML Files (*.xml)"));
if (Journal::RestoreJournal(filename) ) {
QFileInfo fi(filename);
QDir dir = fi.dir();
if (dir.exists() ) {
saveProfilePath(STR_PREF_LastJournalPath,dir.absolutePath());
}
}
}
void MainWindow::on_actionExport_Journal_triggered()
{
QString folder;
folder = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
folder = profilePath(STR_PREF_LastJournalPath);
if (p_profile->contains(STR_PREF_LastJournalPath)) {
folder = (*p_profile)[STR_PREF_LastJournalPath].toString();
}
QFileInfo fi(folder);
if (!fi.isDir() ) {
folder = QStandardPaths::StandardLocation(QStandardPaths::DocumentsLocation);
}
folder += QDir::separator() + tr("%1's Journal").arg(p_profile->user->userName()) + ".xml";
QString filename = QFileDialog::getSaveFileName(this, tr("Choose where to save journal"), folder, tr("XML Files (*.xml)"));
BackupJournal(filename);
if (Journal::BackupJournal(filename) ) {
QFileInfo fi(filename);
QDir dir = fi.dir();
if (dir.exists() ) {
(*p_profile)[STR_PREF_LastJournalPath] = dir.absolutePath();
}
}
}
void MainWindow::on_actionShow_Performance_Counters_toggled(bool arg1)

View File

@ -1,7 +1,7 @@
/* OSCAR MainWindow Headers
*
* Copyright (c) 2019-2024 The OSCAR Team
* Copyright (C) 2011-2018 Mark Watkins
* Copyright (C) 2011-2018 Mark Watkins
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of the source code
@ -48,7 +48,7 @@ class MainWindow;
This document is an attempt to provide a little technical insight into OSCAR's program internals.
\section project_info Further Information
OSCAR is hosted on <a href="https://gitlab.com/pholy/OSCAR-code">Gitlab</a> with full source code available there.
OSCAR is hosted on <a href="https://gitlab.com/CrimsonNape/OSCAR-code">Gitlab</a> with full source code available there.
Help for users can be found in the <a href="http://www.apneaboard.com/wiki/index.php?title=OSCAR_Help">OSCAR Help Wiki</a>.
@ -138,14 +138,6 @@ class MainWindow : public QMainWindow
void updateOverview();
/*! \fn void RestartApplication(bool force_login=false);
\brief Closes down OSCAR and restarts it
\param bool force_login
If force_login is set, it will return to the login menu even if it's set to skip
*/
void RestartApplication(bool force_login = false, QString cmdline = QString());
void JumpDaily();
void JumpOverview();
void JumpStatistics();
@ -179,7 +171,18 @@ class MainWindow : public QMainWindow
//! \brief Recalculate all event summaries and flags
void doReprocessEvents();
void doRecompressEvents();
/*! \fn void RestartApplication(bool force_login=false);
\brief Closes down OSCAR and restarts it
\param bool force_login
If force_login is set, it will return to the login menu even if it's set to skip
allow timer to restart application.
*/
void RestartApplication(bool force_login = false, QString cmdline = QString());
QString profilePath(QString folderProfileName );
void saveProfilePath(QString folderProfileName , QString pathName);
protected:
void closeEvent(QCloseEvent *) override;
@ -345,6 +348,8 @@ class MainWindow : public QMainWindow
void on_actionExport_Journal_triggered();
void on_actionImport_Journal_triggered();
void on_actionShow_Performance_Counters_toggled(bool arg1);
void on_actionExport_CSV_triggered();

View File

@ -2411,6 +2411,7 @@ p, li { white-space: pre-wrap; }
<addaction name="separator"/>
<addaction name="menuExp_ort_CSV_Data"/>
<addaction name="actionExport_Journal"/>
<addaction name="actionImport_Journal"/>
<addaction name="separator"/>
<addaction name="actionChange_Data_Folder"/>
<addaction name="separator"/>
@ -2824,6 +2825,11 @@ p, li { white-space: pre-wrap; }
<string>Backup Journal</string>
</property>
</action>
<action name="actionImport_Journal">
<property name="text">
<string>Import Journal</string>
</property>
</action>
<action name="actionShow_Performance_Counters">
<property name="checkable">
<bool>true</bool>

View File

@ -56,7 +56,7 @@ NewProfile::NewProfile(QWidget *parent, const QString *user) :
m_passwordHashed = false;
ui->heightEdit2->setVisible(false);
ui->heightEdit->setDecimals(0);
ui->heightEdit->setSuffix(STR_UNIT_CM);
ui->heightEdit->setSuffix(QString(" %1").arg(STR_UNIT_CM));
{
// process countries list
@ -141,10 +141,10 @@ QString NewProfile::getIntroHTML()
"</body>"
"</html>";
}
#include <cmath>
int cmToFeetInch( double cm, double& inches ) {
inches = cm * inches_per_cm;
int feet = inches / 12;
int feet = std::round(inches / 12);
inches -= (double)(feet *12);
return feet;
}
@ -448,15 +448,15 @@ void NewProfile::on_heightCombo_currentIndexChanged(int index)
if (index == 0) {
//metric
ui->heightEdit->setDecimals(1);
ui->heightEdit->setSuffix(STR_UNIT_CM);
ui->heightEdit->setSuffix(QString(" %1").arg(STR_UNIT_CM));
ui->heightEdit->setValue(m_tmp_height_cm);
ui->heightEdit2->setVisible(false);
} else { //evil
} else { //english
ui->heightEdit->setDecimals(0); // feet are always a whole number.
ui->heightEdit2->setDecimals(1); // inches can be seen as double.
ui->heightEdit->setSuffix(STR_UNIT_FOOT);
ui->heightEdit->setSuffix(QString(" %1").arg(STR_UNIT_FOOT));
ui->heightEdit2->setVisible(true);
ui->heightEdit2->setSuffix(STR_UNIT_INCH);
ui->heightEdit2->setSuffix(QString(" %1").arg(STR_UNIT_INCH));
double inches=0;
ui->heightEdit->setValue(cmToFeetInch(m_tmp_height_cm,inches));
ui->heightEdit2->setValue(inches);

159
oscar/notifyMessageBox.cpp Normal file
View File

@ -0,0 +1,159 @@
/* Daily Panel
*
* Copyright (c) 2019-2024 The OSCAR Team
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of the source code
* for more details. */
#include "notifyMessageBox.h"
#define TEST_MACROS_ENABLEDoff
#include <test_macros.h>
int defaultTimeoutSeconds = 4 ;
//QString defaultTimeoutMessage = QObject::tr("Notifcation expires in %1 seconds.\nTo Dismiss: Press Escape or Enter.");
//QString timeoutStoppedMessage = QObject::tr("Timer Stopped.\nTo Dismiss: Press Escape or Enter.");
QString defaultTimeoutMessage = QObject::tr("Notifcation expires in %1 seconds.");
QString timeoutStoppedMessage = QObject::tr("");
NotifyMessageBox::NotifyMessageBox(const QString& title, const QString& message, int timeoutSeconds, const QString& timeoutMessage, QWidget* parent)
: QObject(parent), m_title(title), m_message(message), m_timeoutSeconds(timeoutSeconds), m_timeoutMessage(timeoutMessage), m_state(nmb_init)
{
if (timeoutSeconds<defaultTimeoutSeconds) m_timeoutSeconds=defaultTimeoutSeconds;
if ( timeoutMessage.isEmpty() ) m_timeoutMessage = defaultTimeoutMessage;
setupTimer();
}
NotifyMessageBox::~NotifyMessageBox()
{
};
void NotifyMessageBox::setupMessageBox()
{
m_msgBox = new QMessageBox(QMessageBox::Information,m_title,m_message);
//QFont boldFont;
//boldFont.setBold(true);
//m_msgBox->setFont(boldFont);
m_msgBox->setWindowTitle(m_title);
m_msgBox->setText(m_message);
#ifndef STOPTIMER
m_msgBox->setStandardButtons(QMessageBox::Ok);
#else
// Set action as the default button
QPushButton *terminateB = m_msgBox->addButton("Dismiss", QMessageBox::RejectRole);
m_msgBox->setDefaultButton(terminateB);
connect(m_msgBox, SIGNAL(rejected()), this, SLOT(onTerminate()));
if (m_state == nmb_stopped) {
m_msgBox->setInformativeText(timeoutStoppedMessage);
} else {
m_msgBox->setInformativeText(m_timeoutMessage.arg(m_timeoutSeconds));
m_msgBox->addButton("Stop Timer", QMessageBox::AcceptRole);
m_msgBox->setEscapeButton(QMessageBox::Cancel);
connect(m_msgBox, SIGNAL(accepted()), this, SLOT(onStop()));
}
#endif
m_msgBox->show();
m_msgBox->raise();
}
#if defined(STOPTIMER)
void NotifyMessageBox::onStop()
{
m_msgBox->close();
m_state = nmb_stopped;
setupMessageBox();
}
void NotifyMessageBox::onTerminate()
{
releaseResources();
}
#endif
void NotifyMessageBox::onTimeout()
{
switch (m_state) {
case nmb_init:
m_timer->setInterval(1000);
setupMessageBox();
m_state = nmb_running;
break;
case nmb_running:
m_timer->setInterval(1000);
m_timeoutSeconds--;
if (m_timeoutSeconds == 0) {
m_state = nmb_stopped;
releaseResources();
} else {
m_msgBox->setInformativeText(m_timeoutMessage.arg(m_timeoutSeconds));
}
break;
default:
case nmb_stopped:
break;
}
}
void NotifyMessageBox::setupTimer()
{
#if defined(STOPTIMER)
m_timer = new QTimer(this);
m_timer->setInterval(1);
m_timer->setSingleShot(false);
connect(m_timer, &QTimer::timeout, this, &NotifyMessageBox::onTimeout);
m_timer->start();
#endif
}
void NotifyMessageBox::releaseResources()
{
m_msgBox->close();
#if defined(STOPTIMER)
m_timer->deleteLater();
#endif
}
NotifyMessageBox* createNotifyMessageBox(
const QString& title,
const QString& message,
int timeoutSeconds,
const QString& timeoutMessage,
QWidget* parent)
{
NotifyMessageBox* msgBox = new NotifyMessageBox(title, message, timeoutSeconds, timeoutMessage, parent);
return msgBox;
}
NotifyMessageBox* createNotifyMessageBox (
QWidget* parent ,
const QString& title,
const QString& message,
int timeoutSeconds ,
const QString& timeoutMessage
) {
return createNotifyMessageBox(title, message, timeoutSeconds, timeoutMessage, parent);
};
#if 0
NotifyMessageBox* createNotifyMessageBox (
QWidget* parent ,
const QString& title,
const QString& message,
enum QMessageBox::Icon msgIcon,
int timeoutSeconds ,
const QString& timeoutMessage
) {
return createNotifyMessageBox(title, message, timeoutSeconds, timeoutMessage, parent);
};
#endif

94
oscar/notifyMessageBox.h Normal file
View File

@ -0,0 +1,94 @@
/* search GUI Headers
*
* Copyright (c) 2024-2024 The OSCAR Team
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of the source code
* for more details. */
#ifndef NOTIFYMESSAGEBOX_H
#define NOTIFYMESSAGEBOX_H
#define STOPTIMER
#include <QMessageBox>
#include <QFont>
#include <QDebug>
#ifdef STOPTIMER
#include <QTimer>
#include <QPushButton>
#endif
class NotifyMessageBox : public QObject
{
Q_OBJECT
public:
enum NMB_STATE { nmb_init, nmb_running, nmb_stopped };
NotifyMessageBox(const QString& title,
const QString& message,
int timeoutSeconds = 0 ,
const QString& timeoutMessage = "" ,
QWidget* parent = nullptr);
virtual ~NotifyMessageBox();
private:
void setupMessageBox();
void setupTimer();
private slots:
void releaseResources();
void onTimeout();
#if defined(STOPTIMER)
void onStop() ;
void onTerminate() ;
#endif
private:
QWidget* m_parent;
QString m_title;
QString m_message;
QMessageBox* m_msgBox;
int m_timeoutSeconds;
QString m_timeoutMessage;
NMB_STATE m_state = nmb_init;
#if defined(STOPTIMER)
QTimer* m_timer;
QPushButton *stopB ;
QPushButton *terminateB ;
#endif
};
NotifyMessageBox* createNotifyMessageBox (
QWidget* parent ,
const QString& title,
const QString& message,
int timeoutSeconds = 0 ,
const QString& timeoutMessage = "" ) ;
#if 0
NotifyMessageBox* createNotifyMessageBox (
const QString& title,
const QString& message,
int timeoutSeconds = 0 ,
const QString& timeoutMessage = "" ,
QWidget* parent = nullptr);
NotifyMessageBox* createNotifyMessageBox (
const QString& title,
const QString& message,
int timeoutSeconds = 0 ,
enum QMessageBox::Icon msgIcon =
const QString& timeoutMessage = "" ,
QWidget* parent = nullptr);
#endif
#endif // NOTIFYMESSAGEBOX_H

View File

@ -255,6 +255,7 @@ lessThan(QT_MAJOR_VERSION,5)|lessThan(QT_MINOR_VERSION,12) {
SOURCES += \
checkupdates.cpp \
notifyMessageBox.cpp \
highresolution.cpp \
Graphs/gGraph.cpp \
Graphs/gGraphView.cpp \
@ -365,6 +366,7 @@ QMAKE_EXTRA_COMPILERS += optimize
HEADERS += \
checkupdates.h \
notifyMessageBox.h \
highresolution.h \
dailySearchTab.h \
daily.h \

Some files were not shown because too many files have changed in this diff Show More